Skip to content

Commit 8d25f9b

Browse files
authored
Merge pull request #77 from millicast/develop
Release v0.1.7
2 parents 23171ef + a2dc7f8 commit 8d25f9b

File tree

12 files changed

+53
-31
lines changed

12 files changed

+53
-31
lines changed

packages/millicast-sdk/package-lock.json

Lines changed: 13 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/millicast-sdk/package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@millicast/sdk",
3-
"version": "0.1.6",
3+
"version": "0.1.7",
44
"description": "SDK for building a realtime broadcaster using the Millicast platform.",
55
"keywords": [
66
"sdk",
@@ -48,6 +48,7 @@
4848
"buffer": "^6.0.3",
4949
"events": "^3.3.0",
5050
"js-logger": "^1.6.1",
51+
"jwt-decode": "^3.1.2",
5152
"re-emitter": "^1.1.4",
5253
"semantic-sdp": "^3.21.0",
5354
"transaction-manager": "^2.1.3",

packages/millicast-sdk/src/Director.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import axios from 'axios'
2+
import jwtDecode from 'jwt-decode'
23
import Logger from './Logger'
34

45
const logger = Logger.get('Director')
@@ -14,6 +15,7 @@ let apiEndpoint = defaultApiEndpoint
1415
* @typedef {Object} MillicastDirectorResponse
1516
* @property {Array<String>} urls - WebSocket available URLs.
1617
* @property {String} jwt - Access token for signaling initialization.
18+
* @property {Object} jwtDecoded - Access token decoded.
1719
*/
1820

1921
/**
@@ -83,7 +85,7 @@ export default class Director {
8385
try {
8486
const { data } = await axios.post(url, payload, { headers })
8587
logger.debug('Getting publisher response: ', data)
86-
return data.data
88+
return { ...data.data, jwtDecoded: jwtDecode(data.data.jwt).millicast }
8789
} catch (e) {
8890
logger.error('Error while getting publisher connection path: ', e.response?.data)
8991
throw e
@@ -134,7 +136,7 @@ export default class Director {
134136
try {
135137
const { data } = await axios.post(url, payload, { headers })
136138
logger.debug('Getting subscriber response: ', data)
137-
return data.data
139+
return { ...data.data, jwtDecoded: jwtDecode(data.data.jwt).millicast }
138140
} catch (e) {
139141
logger.error('Error while getting subscriber connection path: ', e.response?.data)
140142
throw e

packages/millicast-sdk/src/PeerConnection.js

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -254,16 +254,18 @@ export default class PeerConnection extends EventEmitter {
254254

255255
/**
256256
* @typedef {Object} MillicastCapability
257-
* @property {String} codec - Audio or video codec name.
258-
* @property {String} mimeType - Audio or video codec mime type.
259-
* @property {Array<String>} [scalabilityModes] - In case of SVC support, a list of scalability modes supported.
260-
* @property {Number} [channels] - Only for audio, the number of audio channels supported.
257+
* @property {Array<Object>} codecs
258+
* @property {String} codecs.codec - Audio or video codec name.
259+
* @property {String} codecs.mimeType - Audio or video codec mime type.
260+
* @property {Array<String>} [codecs.scalabilityModes] - In case of SVC support, a list of scalability modes supported.
261+
* @property {Number} [codecs.channels] - Only for audio, the number of audio channels supported.
262+
* @property {Array<RTCRtpHeaderExtensionCapability>} headerExtensions - An array specifying the URI of the header extension, as described in RFC 5285.
261263
*/
262264
/**
263265
* Gets user's browser media capabilities compared with Millicast Media Server support.
264266
*
265267
* @param {"audio"|"video"} kind - Type of media for which you wish to get sender capabilities.
266-
* @returns {Array<MillicastCapability>} An array with all capabilities supported by user's browser and Millicast Media Server.
268+
* @returns {MillicastCapability} Object with all capabilities supported by user's browser and Millicast Media Server.
267269
*/
268270
static getCapabilities (kind) {
269271
const browserData = new UserAgent()

packages/millicast-sdk/src/Publish.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ export default class Publish extends BaseWebRTC {
5252
* @param {String} options.scalabilityMode - Selected scalability mode. You can get the available capabilities using <a href="PeerConnection#.getCapabilities">PeerConnection.getCapabilities</a> method.
5353
* **Only available in Google Chrome.**
5454
* @param {RTCConfiguration} options.peerConfig - Options to configure the new RTCPeerConnection.
55+
* @param {Boolean} [options.record] - Enable stream recording. If record is not provided, use default Token configuration. **Only available in Tokens with recording enabled.**
5556
* @returns {Promise<void>} Promise object which resolves when the broadcast started successfully.
5657
* @fires PeerConnection#connectionStateChange
5758
* @example await publish.connect(options)
@@ -111,7 +112,7 @@ export default class Publish extends BaseWebRTC {
111112
reemit(this.webRTCPeer, this, [webRTCEvents.connectionStateChange])
112113

113114
const localSdp = await this.webRTCPeer.getRTCLocalSDP(this.options)
114-
let remoteSdp = await this.signaling.publish(localSdp, this.options.codec)
115+
let remoteSdp = await this.signaling.publish(localSdp, this.options.codec, this.options.record)
115116

116117
if (!this.options.disableVideo && this.options.bandwidth > 0) {
117118
remoteSdp = this.webRTCPeer.updateBandwidthRestriction(remoteSdp, this.options.bandwidth)

packages/millicast-sdk/src/Signaling.js

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -203,10 +203,11 @@ export default class Signaling extends EventEmitter {
203203
* Establish WebRTC connection with Millicast Server as Publisher role.
204204
* @param {String} sdp - The SDP information created by your offer.
205205
* @param {VideoCodec} [codec="h264"] - Codec for publish stream.
206+
* @param {Boolean} [record] - Enable stream recording. If record is not provided, use default Token configuration. **Only available in Tokens with recording enabled.**
206207
* @example const response = await millicastSignaling.publish(sdp, 'h264')
207208
* @return {Promise<String>} Promise object which represents the SDP command response.
208209
*/
209-
async publish (sdp, codec = VideoCodec.H264) {
210+
async publish (sdp, codec = VideoCodec.H264, record = null) {
210211
logger.info(`Starting publishing to streamName: ${this.streamName}, codec: ${codec}`)
211212
logger.debug('Publishing local description: ', sdp)
212213

@@ -227,6 +228,10 @@ export default class Signaling extends EventEmitter {
227228
codec
228229
}
229230

231+
if (record !== null) {
232+
data.record = record
233+
}
234+
230235
try {
231236
await this.connect()
232237
logger.info('Sending publish command')

packages/millicast-sdk/tests/features/OfferPublishingStream.feature

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ Feature: As a user I want to signal Millicast Server so I can offer publishing a
22

33
Scenario: Offer a SDP with no previous connection and h264 codec
44
Given a local sdp and no previous connection to server
5-
When I offer my local sdp with h264 codec
5+
When I offer my local sdp with h264 codec and recording option
66
Then returns a filtered sdp to offer to remote peer
77

88
Scenario: Offer a SDP with no previous connection and vp8 codec

packages/millicast-sdk/tests/features/step-definitions/GetPublisherConnectionPath.steps.js

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import Director from '../../../src/Director'
44
const feature = loadFeature('../GetPublisherConnectionPath.feature', { loadRelativePath: true, errors: true })
55

66
jest.mock('axios')
7+
const dummyToken = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyLCJtaWxsaWNhc3QiOnt9fQ.IqT-PLLz-X7Wn7BNo-x4pFApAbMT9mmnlupR8eD9q4U'
78

89
defineFeature(feature, test => {
910
test('Publish with an existing stream name and valid token', ({ given, when, then }) => {
@@ -19,7 +20,7 @@ defineFeature(feature, test => {
1920
urls: [
2021
'wss://live-west.millicast.com/ws/v2/pub/12345'
2122
],
22-
jwt: '123jwt',
23+
jwt: dummyToken,
2324
streamAccountId: 'Existing_accountId'
2425
}
2526
}
@@ -36,7 +37,7 @@ defineFeature(feature, test => {
3637

3738
then('I get the publish connection path', async () => {
3839
expect(response).toBeDefined()
39-
expect(response).toEqual(mockedResponse.data.data)
40+
expect(response).toEqual(expect.objectContaining(mockedResponse.data.data))
4041
})
4142
})
4243

@@ -104,7 +105,7 @@ defineFeature(feature, test => {
104105

105106
then('throws an error with "invalid token" message', async () => {
106107
expect(responseError).toBeDefined()
107-
expect(responseError.response.data).toEqual(mockedResponse.response.data)
108+
expect(responseError.response.data).toEqual(expect.objectContaining(mockedResponse.response.data))
108109
})
109110
})
110111

@@ -121,7 +122,7 @@ defineFeature(feature, test => {
121122
urls: [
122123
'wss://live-west.millicast.com/ws/v2/pub/12345'
123124
],
124-
jwt: '123jwt',
125+
jwt: dummyToken,
125126
streamAccountId: 'Existing_accountId'
126127
}
127128
}
@@ -144,7 +145,7 @@ defineFeature(feature, test => {
144145
expect.any(Object)
145146
)
146147
expect(response).toBeDefined()
147-
expect(response).toEqual(mockedResponse.data.data)
148+
expect(response).toEqual(expect.objectContaining(mockedResponse.data.data))
148149
})
149150
})
150151
})

packages/millicast-sdk/tests/features/step-definitions/GetSubscriberConnectionPath.steps.js

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import Director from '../../../src/Director'
44
const feature = loadFeature('../GetSubscriberConnectionPath.feature', { loadRelativePath: true, errors: true })
55

66
jest.mock('axios')
7+
const dummyToken = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyLCJtaWxsaWNhc3QiOnt9fQ.IqT-PLLz-X7Wn7BNo-x4pFApAbMT9mmnlupR8eD9q4U'
78

89
defineFeature(feature, test => {
910
test('Subscribe to an existing unrestricted stream, valid accountId and no token', ({ given, when, then }) => {
@@ -18,7 +19,7 @@ defineFeature(feature, test => {
1819
urls: [
1920
'wss://live-west.millicast.com/ws/v2/sub/12345'
2021
],
21-
jwt: '123jwt',
22+
jwt: dummyToken,
2223
streamAccountId: 'Existing_accountId'
2324
}
2425
}
@@ -35,7 +36,7 @@ defineFeature(feature, test => {
3536

3637
then('I get the subscriber connection path', async () => {
3738
expect(response).toBeDefined()
38-
expect(response).toEqual(mockedResponse.data.data)
39+
expect(response).toEqual(expect.objectContaining(mockedResponse.data.data))
3940
})
4041
})
4142

@@ -51,7 +52,7 @@ defineFeature(feature, test => {
5152
urls: [
5253
'wss://live-west.millicast.com/ws/v2/sub/12345'
5354
],
54-
jwt: '123jwt',
55+
jwt: dummyToken,
5556
streamAccountId: 'Existing_accountId'
5657
}
5758
}
@@ -68,7 +69,7 @@ defineFeature(feature, test => {
6869

6970
then('I get the subscriber connection path', async () => {
7071
expect(response).toBeDefined()
71-
expect(response).toEqual(mockedResponse.data.data)
72+
expect(response).toEqual(expect.objectContaining(mockedResponse.data.data))
7273
})
7374
})
7475

@@ -119,7 +120,7 @@ defineFeature(feature, test => {
119120
urls: [
120121
'wss://live-west.millicast.com/ws/v2/sub/12345'
121122
],
122-
jwt: '123jwt',
123+
jwt: dummyToken,
123124
streamAccountId: 'Existing_accountId'
124125
}
125126
}
@@ -142,7 +143,7 @@ defineFeature(feature, test => {
142143
expect.any(Object)
143144
)
144145
expect(response).toBeDefined()
145-
expect(response).toEqual(mockedResponse.data.data)
146+
expect(response).toEqual(expect.objectContaining(mockedResponse.data.data))
146147
})
147148
})
148149
})

packages/millicast-sdk/tests/features/step-definitions/OfferPublishingStream.steps.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,12 +72,12 @@ defineFeature(feature, test => {
7272
})
7373
})
7474

75-
when('I offer my local sdp with h264 codec', async () => {
75+
when('I offer my local sdp with h264 codec and recording option', async () => {
7676
const signaling = new Signaling({
7777
streamName: streamName,
7878
url: publishWebSocketLocation
7979
})
80-
response = await signaling.publish(localSdp, 'h264')
80+
response = await signaling.publish(localSdp, 'h264', true)
8181
})
8282

8383
then('returns a filtered sdp to offer to remote peer', async () => {

0 commit comments

Comments
 (0)