Skip to content
This repository was archived by the owner on Oct 25, 2024. It is now read-only.

Commit d1ef66b

Browse files
authored
Fix undefined issue when transcoding is disabled. (#511)
1 parent d48b59c commit d1ef66b

File tree

2 files changed

+190
-28
lines changed

2 files changed

+190
-28
lines changed

src/sdk/conference/streamutils.js

+22-17
Original file line numberDiff line numberDiff line change
@@ -129,23 +129,28 @@ export function convertToSubscriptionCapabilities(mediaInfo) {
129129
}
130130
}
131131
videoCodecs.sort();
132-
const resolutions = Array.from(
133-
track.optional.parameters.resolution,
134-
(r) => new MediaFormatModule.Resolution(r.width, r.height));
135-
resolutions.sort(sortResolutions);
136-
const bitrates = Array.from(
137-
track.optional.parameters.bitrate,
138-
(bitrate) => extractBitrateMultiplier(bitrate));
139-
bitrates.push(1.0);
140-
bitrates.sort(sortNumbers);
141-
const frameRates = JSON.parse(
142-
JSON.stringify(track.optional.parameters.framerate));
143-
frameRates.sort(sortNumbers);
144-
const keyFrameIntervals = JSON.parse(
145-
JSON.stringify(track.optional.parameters.keyFrameInterval));
146-
keyFrameIntervals.sort(sortNumbers);
147-
video = new SubscriptionModule.VideoSubscriptionCapabilities(
148-
videoCodecs, resolutions, frameRates, bitrates, keyFrameIntervals);
132+
if (!track.optional?.parameters) {
133+
video = new SubscriptionModule.VideoSubscriptionCapabilities(
134+
videoCodecs, [], [], [], []);
135+
} else {
136+
const resolutions = Array.from(
137+
track.optional.parameters.resolution,
138+
(r) => new MediaFormatModule.Resolution(r.width, r.height));
139+
resolutions.sort(sortResolutions);
140+
const bitrates = Array.from(
141+
track.optional.parameters.bitrate,
142+
(bitrate) => extractBitrateMultiplier(bitrate));
143+
bitrates.push(1.0);
144+
bitrates.sort(sortNumbers);
145+
const frameRates =
146+
JSON.parse(JSON.stringify(track.optional.parameters.framerate));
147+
frameRates.sort(sortNumbers);
148+
const keyFrameIntervals = JSON.parse(
149+
JSON.stringify(track.optional.parameters.keyFrameInterval));
150+
keyFrameIntervals.sort(sortNumbers);
151+
video = new SubscriptionModule.VideoSubscriptionCapabilities(
152+
videoCodecs, resolutions, frameRates, bitrates, keyFrameIntervals);
153+
}
149154
}
150155
}
151156
return new SubscriptionModule.SubscriptionCapabilities(audio, video);

test/unit/resources/scripts/conference.js

+168-11
Original file line numberDiff line numberDiff line change
@@ -6,25 +6,24 @@
66

77
import {ConferenceClient} from '../../../../src/sdk/conference/client.js';
88
import {ConferencePeerConnectionChannel} from '../../../../src/sdk/conference/channel.js';
9-
import * as StreamModule from '../../../../src/sdk/base/stream.js';
109
import * as EventModule from '../../../../src/sdk/base/event.js'
10+
import * as StreamUtils from '../../../../src/sdk/conference/streamutils.js';
1111
import * as SubscriptionModule from '../../../../src/sdk/conference/subscription.js'
12-
import { TransportSettings, TransportType } from '../../../../src/sdk/base/transport.js';
12+
import {TransportSettings, TransportType} from '../../../../src/sdk/base/transport.js';
1313

1414
const expect = chai.expect;
1515
chai.use(chaiAsPromised);
1616

1717
describe('Unit tests for ConferenceClient', function() {
1818
describe('Create a ConferenceClient.', function() {
19-
it(
20-
'Create a ConferenceClient with or without configuration should success.',
21-
done => {
22-
let confclient = new ConferenceClient({});
23-
expect(confclient).to.be.an.instanceof(EventModule.EventDispatcher);
24-
confclient = new ConferenceClient({});
25-
expect(confclient).to.be.an.instanceof(EventModule.EventDispatcher);
26-
done();
27-
});
19+
it('Create a ConferenceClient with or without configuration should success.',
20+
done => {
21+
let confclient = new ConferenceClient({});
22+
expect(confclient).to.be.an.instanceof(EventModule.EventDispatcher);
23+
confclient = new ConferenceClient({});
24+
expect(confclient).to.be.an.instanceof(EventModule.EventDispatcher);
25+
done();
26+
});
2827

2928
it('Event should be fired on correct target.', done => {
3029
let conf1 = new ConferenceClient({});
@@ -109,4 +108,162 @@ describe('Unit tests for Subscription.', () => {
109108
'sessionId', undefined, transportSettings);
110109
expect(subscription.transport).to.equal(transportSettings);
111110
});
111+
});
112+
113+
describe('Unit tests for StreamUtils.', () => {
114+
it('Convert server messages to subscription capabilities.', () => {
115+
const messages = [
116+
[
117+
{
118+
'tracks': [
119+
{
120+
'id': '35951ba82cf14a8cb0348ab64517fb80-2',
121+
'type': 'audio',
122+
'source': 'mic',
123+
'format': {'channelNum': 2, 'sampleRate': 48000, 'codec': 'opus'},
124+
'optional': {
125+
'format': [
126+
{'sampleRate': 16000, 'codec': 'isac'},
127+
{'sampleRate': 32000, 'codec': 'isac'},
128+
{'channelNum': 1, 'sampleRate': 16000, 'codec': 'g722'},
129+
{'codec': 'pcma'}, {'codec': 'pcmu'},
130+
{'channelNum': 2, 'sampleRate': 48000, 'codec': 'aac'},
131+
{'codec': 'ac3'}, {'codec': 'nellymoser'}, {'codec': 'ilbc'}
132+
]
133+
},
134+
'status': 'active',
135+
'mid': '2'
136+
},
137+
{
138+
'id': '35951ba82cf14a8cb0348ab64517fb80-3',
139+
'type': 'video',
140+
'source': 'camera',
141+
'format': {'codec': 'vp8'},
142+
'optional': {
143+
'format': [
144+
{'profile': 'CB', 'codec': 'h264'},
145+
{'profile': 'B', 'codec': 'h264'}, {'codec': 'vp9'}
146+
],
147+
'parameters': {
148+
'resolution': [
149+
{'width': 480, 'height': 360},
150+
{'width': 426, 'height': 320},
151+
{'width': 320, 'height': 240},
152+
{'width': 212, 'height': 160},
153+
{'width': 160, 'height': 120}, {'width': 352, 'height': 288}
154+
],
155+
'bitrate': ['x0.8', 'x0.6', 'x0.4', 'x0.2'],
156+
'framerate': [6, 12, 15, 24],
157+
'keyFrameInterval': [100, 30, 5, 2, 1]
158+
}
159+
},
160+
'status': 'active',
161+
'mid': '3'
162+
}
163+
]
164+
},
165+
{
166+
'audio': {
167+
'codecs': [
168+
{'name': 'isac', 'clockRate': 16000},
169+
{'name': 'isac', 'clockRate': 32000},
170+
{'name': 'g722', 'channelCount': 1, 'clockRate': 16000},
171+
{'name': 'pcma'}, {'name': 'pcmu'},
172+
{'name': 'aac', 'channelCount': 2, 'clockRate': 48000},
173+
{'name': 'ac3'}, {'name': 'nellymoser'}, {'name': 'ilbc'}
174+
]
175+
},
176+
'video': {
177+
'codecs': [
178+
{'name': 'h264', 'profile': 'CB'},
179+
{'name': 'h264', 'profile': 'B'}, {'name': 'vp9'}
180+
],
181+
'resolutions': [
182+
{'width': 160, 'height': 120}, {'width': 212, 'height': 160},
183+
{'width': 320, 'height': 240}, {'width': 352, 'height': 288},
184+
{'width': 426, 'height': 320}, {'width': 480, 'height': 360}
185+
],
186+
'frameRates': [6, 12, 15, 24],
187+
'bitrateMultipliers': [0.2, 0.4, 0.6, 0.8, 1],
188+
'keyFrameIntervals': [1, 2, 5, 30, 100]
189+
}
190+
}
191+
],
192+
[
193+
// Audio only.
194+
{
195+
'tracks': [{
196+
'id': '35951ba82cf14a8cb0348ab64517fb80-2',
197+
'type': 'audio',
198+
'source': 'mic',
199+
'format': {'channelNum': 2, 'sampleRate': 48000, 'codec': 'opus'},
200+
'optional': {
201+
'format': [
202+
{'sampleRate': 16000, 'codec': 'isac'},
203+
{'sampleRate': 32000, 'codec': 'isac'},
204+
{'channelNum': 1, 'sampleRate': 16000, 'codec': 'g722'},
205+
{'codec': 'pcma'}, {'codec': 'pcmu'},
206+
{'channelNum': 2, 'sampleRate': 48000, 'codec': 'aac'},
207+
{'codec': 'ac3'}, {'codec': 'nellymoser'}, {'codec': 'ilbc'}
208+
]
209+
},
210+
'status': 'active',
211+
'mid': '2'
212+
}]
213+
},
214+
{
215+
'audio': {
216+
'codecs': [
217+
{'name': 'isac', 'clockRate': 16000},
218+
{'name': 'isac', 'clockRate': 32000},
219+
{'name': 'g722', 'channelCount': 1, 'clockRate': 16000},
220+
{'name': 'pcma'}, {'name': 'pcmu'},
221+
{'name': 'aac', 'channelCount': 2, 'clockRate': 48000},
222+
{'name': 'ac3'}, {'name': 'nellymoser'}, {'name': 'ilbc'}
223+
]
224+
}
225+
}
226+
],
227+
[
228+
// Transcoding is disabled.
229+
{
230+
'tracks': [
231+
{
232+
'type': 'audio',
233+
'format': {'codec': 'opus', 'sampleRate': 48000, 'channelNum': 2},
234+
'optional': {},
235+
'status': 'active'
236+
},
237+
{
238+
'type': 'video',
239+
'format': {'codec': 'vp8'},
240+
'parameters': {
241+
'resolution': {'width': 640, 'height': 480},
242+
'framerate': 24,
243+
'keyFrameInterval': 100
244+
},
245+
'optional': {},
246+
'status': 'active'
247+
}
248+
]
249+
},
250+
{
251+
'audio': {'codecs': []},
252+
'video': {
253+
'codecs': [],
254+
'resolutions': [],
255+
'frameRates': [],
256+
'bitrateMultipliers': [],
257+
'keyFrameIntervals': []
258+
}
259+
}
260+
]
261+
];
262+
for (const [message, capabilities] of messages) {
263+
// Stringify to avoid type comparison.
264+
expect(JSON.stringify(
265+
StreamUtils.convertToSubscriptionCapabilities(message)))
266+
.to.equal(JSON.stringify(capabilities));
267+
}
268+
});
112269
});

0 commit comments

Comments
 (0)