Skip to content

Commit

Permalink
Add video support
Browse files Browse the repository at this point in the history
  • Loading branch information
myrotvorets-team committed Oct 18, 2022
1 parent 2245ce5 commit 9ed9446
Show file tree
Hide file tree
Showing 9 changed files with 133 additions and 1 deletion.
1 change: 1 addition & 0 deletions src/interfaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ export interface IFaceXRequestBuilder {
setSegment(segment: string): this;
setPhotoData(s: string): this;
setPhoto(s: Buffer | string | NodeJS.ReadableStream): Promise<this>;
setVideo(s: Buffer | string | NodeJS.ReadableStream): Promise<this>;
setComment(comment: string): this;
setResultNumber(resultNumber: number): this;
setParams(par1: number, par2: number): this;
Expand Down
16 changes: 15 additions & 1 deletion src/request/builder.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { createReadStream } from 'fs';
import { BufferStream } from '@myrotvorets/buffer-stream';
import { BufferStream, streamToBuffer } from '@myrotvorets/buffer-stream';
import { FaceXRequest, IFaceXRequestBuilder, IGuidGenerator, IImageProcessor } from '../interfaces';

export class FaceXRequestBuilder implements IFaceXRequestBuilder {
Expand Down Expand Up @@ -91,6 +91,20 @@ export class FaceXRequestBuilder implements IFaceXRequestBuilder {
return this;
}

public async setVideo(s: Buffer | string | NodeJS.ReadableStream): Promise<this> {
let b: Buffer;
if (Buffer.isBuffer(s)) {
b = s;
} else if (typeof s === 'string') {
b = Buffer.from(s);
} else {
b = await streamToBuffer(s);
}

this._request.data.foto = b.toString('base64');
return this;
}

public setComment(comment: string): this {
this._request.data.comment = comment;
return this;
Expand Down
6 changes: 6 additions & 0 deletions src/request/commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,9 @@ export const enum AdminCommands {
DELETE_INIT = 208,
DELETE_STATUS = 209,
}

export const enum VideoCommands {
VIDEO_UPLOAD = 240,
VIDEO_STATUS = 241,
VIDEO_RESULT = 242,
}
4 changes: 4 additions & 0 deletions src/responsefactory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,10 @@ const lookupTable: Record<number, typeof Response.Response> = {

208: Response.DeleteAck,
209: Response.DeleteStatus,

241: Response.VideoUploadAck,
243: Response.VideoStatus,
245: Response.VideoResult,
};

export function responseFactory(r: Response.RawResponse): Response.Response {
Expand Down
3 changes: 3 additions & 0 deletions src/responses/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,6 @@ export * from './preparedfaces'; // ans_type = 206
export * from './addpreparedfacesack'; // ans_type = 207
export * from './deleteack'; // ans_type = 208
export * from './deletestatus'; // ans_type = 209
export * from './videouploadack'; // ans_type = 241
export * from './videostatus'; // ans_type = 243
export * from './videoresult'; // ans_type = 245
43 changes: 43 additions & 0 deletions src/responses/videoresult.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import { PhotoEntry, Response } from './response';

export class VideoMatch {
private readonly _e: PhotoEntry;

public constructor(x: PhotoEntry) {
this._e = x;
}

public get archive(): string {
return this._e.foto as string;
}

public get archiveAsBuffer(): Buffer {
return Buffer.from(this._e.foto as string, 'base64');
}
}

// ans_type = 245
export class VideoResult extends Response {
private _idx = 0;

// eslint-disable-next-line class-methods-use-this
public isCacheable(): boolean {
return true;
}

public [Symbol.iterator](): Iterator<VideoMatch, undefined> {
return {
next: (): IteratorResult<VideoMatch, undefined> => {
if (this._idx < this._raw.data.fotos.length) {
return {
value: new VideoMatch(this._raw.data.fotos[this._idx++]),
done: false,
};
}

this._idx = 0;
return { value: undefined, done: true };
},
};
}
}
24 changes: 24 additions & 0 deletions src/responses/videostatus.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { Response } from './response';

// ans_type = 243
export class VideoStatus extends Response {
public isError(): boolean {
return this.resultCode < 0;
}

public isAccepted(): boolean {
return this.resultCode === 1;
}

public isInProgress(): boolean {
return this.resultCode === 2;
}

public isCompleted(): boolean {
return this.resultCode === 3;
}

public description(): string {
return this.comment;
}
}
8 changes: 8 additions & 0 deletions src/responses/videouploadack.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { Response } from './response';

// ans_type = 241
export class VideoUploadAck extends Response {
public isError(): boolean {
return this.resultCode < 0;
}
}
29 changes: 29 additions & 0 deletions src/videoclient.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { ClientBase } from './clientbase';
import { IFaceXRequestBuilder, IRemoteTransport } from './interfaces';
import { SvcClientRequestEncoder } from './encoders/svcclient';
import { VideoCommands } from './request/commands';
import * as R from './responses';

type VideoType = Buffer | string | NodeJS.ReadableStream;

export class VideoClient extends ClientBase {
public constructor(url: string, transport: IRemoteTransport, requestBuilder: IFaceXRequestBuilder) {
super(url, transport, new SvcClientRequestEncoder(), requestBuilder);
}

public async uploadVideo(video: VideoType): Promise<R.VideoUploadAck> {
const builder = await this._requestBuilder.reset(VideoCommands.VIDEO_UPLOAD).setVideo(video);
return this._sendRequest(await builder.get());
}

public async getVideoStatus(guid: string): Promise<R.VideoStatus> {
const builder = this._requestBuilder.reset(VideoCommands.VIDEO_STATUS, guid);
return this._sendRequest(await builder.get());
}

public async getVideoResult(guid: string, type: 'detect' | 'match', archiveNumber = 1): Promise<R.VideoResult> {
const builder = this._requestBuilder.reset(VideoCommands.VIDEO_RESULT, guid);
builder.setParams(type === 'detect' ? 1 : 2, archiveNumber);
return this._sendRequest(await builder.get());
}
}

0 comments on commit 9ed9446

Please sign in to comment.