Skip to content

Commit

Permalink
feat: add experience composer and captions to video (#809)
Browse files Browse the repository at this point in the history
  • Loading branch information
dragonmantank authored Mar 27, 2023
1 parent 254386f commit f10f9e4
Show file tree
Hide file tree
Showing 20 changed files with 451 additions and 6 deletions.
6 changes: 3 additions & 3 deletions packages/video/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,9 +86,9 @@ The following is a list of Vonage Video APIs and whether the SDK provides suppor
| Force Muting ||
| Archiving ||
| Custom S3/Azure buckets ||
| SIP Interconnect | |
| Live Streaming Broadcasts | |
| Experience Composer | |
| SIP Interconnect | |
| Live Streaming Broadcasts | |
| Experience Composer | |
| Account Management ||

[signup]: https://dashboard.nexmo.com/sign-up?utm_source=DEV_REL&utm_medium=github&utm_campaign=node-server-sdk
Expand Down
8 changes: 8 additions & 0 deletions packages/video/__tests__/__dataSets__/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import videoTests from './video';

export default [
{
label: 'Video Transactions',
tests: videoTests,
},
];
202 changes: 202 additions & 0 deletions packages/video/__tests__/__dataSets__/video.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,202 @@
import { ExperienceComposerResolution } from '../../lib/enums/ExperienceComposerResolution'
import { ExperienceComposerOptions } from '../../lib/interfaces/ExperienceComposerOptions'
import { CaptionOptions } from '../../lib/interfaces/CaptionOptions'

const renderInformation = {
"id": "1248e7070b81464c9789f46ad10e7764",
"sessionId": "2_MX4xMDBfjE0Mzc2NzY1NDgwMTJ-TjMzfn4",
"projectId": "e2343f23456g34709d2443a234",
"createdAt": 1437676551000,
"updatedAt": 1437676551000,
"url": "https://webapp.customer.com",
"resolution": "1280x720",
"status": "starting",
"streamId": "e32445b743678c98230f238"
}
const renderInformation2 = {
"id": "o89hergjkhaldfg",
"sessionId": "lioaherfgiolae",
"projectId": "e2343f23456g34709d2443a234",
"createdAt": 1437676551000,
"updatedAt": 1437676551000,
"url": "https://webapp.customer.com",
"resolution": "1280x720",
"status": "starting",
"streamId": "e32445b743678c98230f238"
}

const mutliRenderResponse = {
count: 2,
items: [renderInformation, renderInformation2]
}

const enableCaptionsResponse = {
"captionsId": "7c0680fc-6274-4de5-a66f-d0648e8d3ac2"
}

const captionInfoResponse = {
"captionId": "7c0680fc-6274-4de5-a66f-d0648e8d3ac2",
"projectId": "100",
"sessionId": "2_MX4xMDB-flR1ZSBOb3YgMTkgMTE6MDk6NTggUFNUIDIwMTN-MC4zNzQxNzIxNX4",
"status": "failed",
"createdAt": 1628115911,
"updatedAt": 1628115911,
"duration": 300,
"languageCode": "en-US",
"reason": "Quota exceeded for Amazon Transcribe",
"provider": "aws-transcribe"
}

export default [
{
label: "Start an experience render",
request: [
'/v2/project/abcd-1234/render',
'POST',
{
sessionId: "1234",
token: "q34h9uit",
url: "https://example.com",
maxDuration: 1800,
resolution: ExperienceComposerResolution.HD_LANDSCAPE,
properties: {
name: "Sample Render"
}
}
],
response: [
200,
renderInformation
],
method: 'post',
clientMethod: 'startExperienceComposerRender',
parameters: [
"1234",
"q34h9uit",
{
url: "https://example.com",
maxDuration: 1800,
resolution: ExperienceComposerResolution.HD_LANDSCAPE,
properties: {
name: "Sample Render"
}

} as ExperienceComposerOptions
],
expected: renderInformation
},
{
label: "Stop an experience render",
request: [
'/v2/project/abcd-1234/render/1248e7070b81464c9789f46ad10e7764',
'DELETE'
],
response: [
204
],
method: 'delete',
clientMethod: 'stopExperienceComposerRender',
parameters: [
"1248e7070b81464c9789f46ad10e7764",
],
expected: undefined
},
{
label: "Get information about a render",
request: [
'/v2/project/abcd-1234/render/1248e7070b81464c9789f46ad10e7764',
'GET'
],
response: [
200,
renderInformation
],
method: 'delete',
clientMethod: 'getExperienceComposerRender',
parameters: [
"1248e7070b81464c9789f46ad10e7764",
],
expected: renderInformation
},
{
label: "List available renders",
request: [
'/v2/project/abcd-1234/render',
'GET'
],
response: [
200,
mutliRenderResponse
],
method: 'get',
clientMethod: 'listExperienceComposerRenders',
parameters: [],
expected: mutliRenderResponse
},
{
label: "Enable captions for a session",
request: [
'/v2/project/abcd-1234/captions',
'POST',
{
sessionId: "1234",
token: "q34h9uit",
statusCallbackUrl: "https://example.com",
maxDuration: 1800,
partialCaptions: "true",
languageCode: "en-us"
}
],
response: [
200,
enableCaptionsResponse
],
method: 'post',
clientMethod: 'enableCaptions',
parameters: [
"1234",
"q34h9uit",
{
statusCallbackUrl: "https://example.com",
maxDuration: 1800,
partialCaptions: "true",
languageCode: "en-us"

} as CaptionOptions
],
expected: enableCaptionsResponse
},
{
label: "Disable captions for a session",
request: [
'/v2/project/abcd-1234/captions/7c0680fc-6274-4de5-a66f-d0648e8d3ac2/stop',
'POST'
],
response: [
200
],
method: 'post',
clientMethod: 'disableCaptions',
parameters: [
"7c0680fc-6274-4de5-a66f-d0648e8d3ac2"
],
expected: undefined
},
{
label: "Get information about a session caption",
request: [
'/v2/project/abcd-1234/captions/7c0680fc-6274-4de5-a66f-d0648e8d3ac2',
'GET'
],
response: [
200,
captionInfoResponse
],
method: 'get',
clientMethod: 'getCaptionStatus',
parameters: [
"7c0680fc-6274-4de5-a66f-d0648e8d3ac2"
],
expected: captionInfoResponse
}
]
32 changes: 32 additions & 0 deletions packages/video/__tests__/video.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,41 @@ import { LayoutType } from '../lib/enums/LayoutType';
import { MediaMode } from '../lib/interfaces/MediaMode';
import { ArchiveMode } from '../lib/interfaces/ArchiveMode';
import { Auth } from '@vonage/auth';
import testDataSets from './__dataSets__/index'

const BASE_URL = 'https://video.api.vonage.com/'.replace(/\/+$/, '');

describe.each(testDataSets)('$label', ({ tests }) => {
let client;
let scope;

beforeEach(() => {
client = new Video(new Auth({ applicationId: 'abcd-1234', privateKey: fs.readFileSync(`${__dirname}/private.test.key`).toString() }));
scope = nock(BASE_URL, {
reqheaders: {
authorization: value => value.startsWith('Bearer ') && value.length > 10
}
}).persist()
});

afterEach(() => {
client = null;
scope = null;
nock.cleanAll();
})

test.each(tests)(
'Can $label using: $clientMethod',
async ({ request, response, clientMethod, expected, parameters }) => {
scope.intercept(...request).reply(...response);
const results = await client[clientMethod](...parameters);
expect(results).toEqual(expected);
expect(nock.isDone()).toBeTruthy();
}
)
})

// Legacy unit tests
describe('video', () => {
let client;

Expand Down
6 changes: 6 additions & 0 deletions packages/video/lib/enums/CaptionStatus.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
export enum CaptionStatus {
STARTED = "started",
STOPPED = "stopped",
PAUSED = "paused",
FAILED = "failed"
}
8 changes: 8 additions & 0 deletions packages/video/lib/enums/ExperienceComposerResolution.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { Resolution } from "./Resolution";

export enum ExperienceComposerResolution {
SD_LANDSCAPE = Resolution.SD_LANDSCAPE,
SD_PORTRAIT = Resolution.SD_PORTRAIT,
HD_LANDSCAPE = Resolution.HD_LANDSCAPE,
HD_PORTRAIT = Resolution.HD_PORTRAIT,
}
7 changes: 7 additions & 0 deletions packages/video/lib/enums/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export * from './ArchiveOutputMode';
export * from './AudioRate';
export * from './CaptionStatus';
export * from './ExperienceComposerResolution';
export * from './LayoutType';
export * from './Resolution';
export * from './StreamMode';
6 changes: 4 additions & 2 deletions packages/video/lib/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
export { Video } from './video';
export { SIPCallOptions } from './interfaces/SIPCallOptions';
export * from './enums';
export * from './interfaces';
export * from './parameters';
export * from './video';
6 changes: 6 additions & 0 deletions packages/video/lib/interfaces/CaptionOptions.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
export interface CaptionOptions {
languageCode?: "en-us"
maxDuration?: number
partialCaptions?: "true" | "false"
statusCallbackUrl?: string
}
9 changes: 9 additions & 0 deletions packages/video/lib/interfaces/ClientTokenClaims.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
export interface ClientTokenClaims {
scope: string,
session_id: string,
role: string,
initial_layout_class_list: string
data?: string
exp?: number
connection_data?: string
}
4 changes: 4 additions & 0 deletions packages/video/lib/interfaces/ExperienceComposerListFilter.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export interface ExperienceComposerListFilter {
offset?: number;
count?: number;
}
11 changes: 11 additions & 0 deletions packages/video/lib/interfaces/ExperienceComposerOptions.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { ExperienceComposerResolution } from "../enums/ExperienceComposerResolution";

export interface ExperienceComposerOptions {
url: string
properties?: {
name?: string
}
maxDuration?: number
resolution?: ExperienceComposerResolution
statusCallbackUrl?: string
}
14 changes: 14 additions & 0 deletions packages/video/lib/interfaces/Response/CaptionStatusResponse.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { CaptionStatus } from "../../enums/CaptionStatus";

export interface CaptionStatusResponse {
captionId: string
applicationId: string
sessionId: string
status: CaptionStatus
createdAt: number
updatedAt: number
duration: number
languageCode: "en-us"
provider: "aws-transcribe"
reason?: string
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export interface EnableCaptionResponse {
captionsId: string
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { ExperienceComposerResolution } from "../../enums/ExperienceComposerResolution";

export interface ExperienceComposerResponse {
id: string
sessionId: string
applicationId: string
createdAt: number
updatedAt: number
url: string
resolution: ExperienceComposerResolution
status: "starting" | "started" | "stopped" | "failed"
streamId: string
reason?: string
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { ExperienceComposerResponse } from "./ExperienceComposerResponse";

export interface MultiExperienceComposerResponse {
count: number
items: ExperienceComposerResponse[]
}
14 changes: 14 additions & 0 deletions packages/video/lib/interfaces/Response/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
export * from './BroadcastDetailsResponse';
export * from './CaptionStatusResponse';
export * from './CreateSessionResponse';
export * from './EnableCaptionResponse';
export * from './ExperienceComposerResponse';
export * from './MultiArchiveResponse';
export * from './MultiBroadcastResponse';
export * from './MultiExperienceComposerResponse';
export * from './MultiStreamLayoutResponse';
export * from './ProjectDetailsResponse';
export * from './SingleArchiveResponse';
export * from './SingleStreamLayoutResponse';
export * from './SIPCallResponse';
export * from './WebSocketConnectResponse';
Loading

0 comments on commit f10f9e4

Please sign in to comment.