@stream-io/video-client 0.0.3 → 0.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -12,4 +12,7 @@ export declare const watchCallRecordingStopped: (state: CallState) => (event: St
12
12
  * Watches for `call.broadcasting_started` events.
13
13
  */
14
14
  export declare const watchCallBroadcastingStarted: (state: CallState) => (event: StreamVideoEvent) => void;
15
+ /**
16
+ * Watches for `call.broadcasting_stopped` events.
17
+ */
15
18
  export declare const watchCallBroadcastingStopped: (state: CallState) => (event: StreamVideoEvent) => void;
@@ -969,12 +969,6 @@ export interface CallResponse {
969
969
  * @memberof CallResponse
970
970
  */
971
971
  blocked_user_ids: Array<string>;
972
- /**
973
- *
974
- * @type {boolean}
975
- * @memberof CallResponse
976
- */
977
- broadcasting: boolean;
978
972
  /**
979
973
  * The unique identifier for a call (<type>:<id>)
980
974
  * @type {string}
@@ -1008,17 +1002,17 @@ export interface CallResponse {
1008
1002
  [key: string]: any;
1009
1003
  };
1010
1004
  /**
1011
- * Date/time when the call ended
1012
- * @type {string}
1005
+ *
1006
+ * @type {EgressResponse}
1013
1007
  * @memberof CallResponse
1014
1008
  */
1015
- ended_at?: string;
1009
+ egress: EgressResponse;
1016
1010
  /**
1017
- *
1011
+ * Date/time when the call ended
1018
1012
  * @type {string}
1019
1013
  * @memberof CallResponse
1020
1014
  */
1021
- hls_playlist_url: string;
1015
+ ended_at?: string;
1022
1016
  /**
1023
1017
  * Call ID
1024
1018
  * @type {string}
@@ -1989,6 +1983,69 @@ export interface EdgeResponse {
1989
1983
  */
1990
1984
  yellow: number;
1991
1985
  }
1986
+ /**
1987
+ *
1988
+ * @export
1989
+ * @interface EgressHLSResponse
1990
+ */
1991
+ export interface EgressHLSResponse {
1992
+ /**
1993
+ *
1994
+ * @type {string}
1995
+ * @memberof EgressHLSResponse
1996
+ */
1997
+ playlist_url: string;
1998
+ }
1999
+ /**
2000
+ *
2001
+ * @export
2002
+ * @interface EgressRTMPResponse
2003
+ */
2004
+ export interface EgressRTMPResponse {
2005
+ /**
2006
+ *
2007
+ * @type {string}
2008
+ * @memberof EgressRTMPResponse
2009
+ */
2010
+ name: string;
2011
+ /**
2012
+ *
2013
+ * @type {string}
2014
+ * @memberof EgressRTMPResponse
2015
+ */
2016
+ stream_key: string;
2017
+ /**
2018
+ *
2019
+ * @type {string}
2020
+ * @memberof EgressRTMPResponse
2021
+ */
2022
+ url: string;
2023
+ }
2024
+ /**
2025
+ *
2026
+ * @export
2027
+ * @interface EgressResponse
2028
+ */
2029
+ export interface EgressResponse {
2030
+ /**
2031
+ *
2032
+ * @type {boolean}
2033
+ * @memberof EgressResponse
2034
+ */
2035
+ broadcasting: boolean;
2036
+ /**
2037
+ *
2038
+ * @type {EgressHLSResponse}
2039
+ * @memberof EgressResponse
2040
+ */
2041
+ hls?: EgressHLSResponse;
2042
+ /**
2043
+ *
2044
+ * @type {Array<EgressRTMPResponse>}
2045
+ * @memberof EgressResponse
2046
+ */
2047
+ rtmps: Array<EgressRTMPResponse>;
2048
+ }
1992
2049
  /**
1993
2050
  *
1994
2051
  * @export
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stream-io/video-client",
3
- "version": "0.0.3",
3
+ "version": "0.0.5",
4
4
  "packageManager": "yarn@3.2.4",
5
5
  "main": "dist/index.cjs.js",
6
6
  "module": "dist/index.es.js",
@@ -30,25 +30,36 @@ describe('recording and broadcasting events', () => {
30
30
 
31
31
  it('handles call.broadcasting_started events', () => {
32
32
  const state = new CallState();
33
+ state.setMetadata({
34
+ // @ts-ignore
35
+ egress: {
36
+ broadcasting: false,
37
+ hls: {
38
+ playlist_url: '',
39
+ },
40
+ },
41
+ });
33
42
  const handler = watchCallBroadcastingStarted(state);
34
43
  // @ts-ignore
35
44
  handler({
36
45
  type: 'call.broadcasting_started',
37
46
  hls_playlist_url: 'https://example.com/playlist.m3u8',
38
47
  });
39
- expect(state.metadata?.broadcasting).toBe(true);
40
- expect(state.metadata?.hls_playlist_url).toBe(
48
+ expect(state.metadata?.egress.broadcasting).toBe(true);
49
+ expect(state.metadata?.egress.hls?.playlist_url).toBe(
41
50
  'https://example.com/playlist.m3u8',
42
51
  );
43
52
  });
44
53
 
45
54
  it('handles call.broadcasting_stopped events', () => {
46
55
  const state = new CallState();
56
+ // @ts-ignore
57
+ state.setMetadata({});
47
58
  const handler = watchCallBroadcastingStopped(state);
48
59
  // @ts-ignore
49
60
  handler({
50
61
  type: 'call.broadcasting_stopped',
51
62
  });
52
- expect(state.metadata?.broadcasting).toBe(false);
63
+ expect(state.metadata?.egress.broadcasting).toBe(false);
53
64
  });
54
65
  });
@@ -35,18 +35,30 @@ export const watchCallBroadcastingStarted = (state: CallState) => {
35
35
  if (event.type !== 'call.broadcasting_started') return;
36
36
  state.setMetadata((metadata) => ({
37
37
  ...metadata!,
38
- broadcasting: true,
39
- hls_playlist_url: event.hls_playlist_url,
38
+ egress: {
39
+ ...metadata!.egress,
40
+ broadcasting: true,
41
+ hls: {
42
+ ...metadata!.egress.hls,
43
+ playlist_url: event.hls_playlist_url,
44
+ },
45
+ },
40
46
  }));
41
47
  };
42
48
  };
43
49
 
50
+ /**
51
+ * Watches for `call.broadcasting_stopped` events.
52
+ */
44
53
  export const watchCallBroadcastingStopped = (state: CallState) => {
45
54
  return function onCallBroadcastingStopped(event: StreamVideoEvent) {
46
55
  if (event.type !== 'call.broadcasting_stopped') return;
47
56
  state.setMetadata((metadata) => ({
48
57
  ...metadata!,
49
- broadcasting: false,
58
+ egress: {
59
+ ...metadata!.egress,
60
+ broadcasting: false,
61
+ },
50
62
  }));
51
63
  };
52
64
  };
@@ -968,12 +968,6 @@ export interface CallResponse {
968
968
  * @memberof CallResponse
969
969
  */
970
970
  blocked_user_ids: Array<string>;
971
- /**
972
- *
973
- * @type {boolean}
974
- * @memberof CallResponse
975
- */
976
- broadcasting: boolean;
977
971
  /**
978
972
  * The unique identifier for a call (<type>:<id>)
979
973
  * @type {string}
@@ -1005,17 +999,17 @@ export interface CallResponse {
1005
999
  */
1006
1000
  custom: { [key: string]: any };
1007
1001
  /**
1008
- * Date/time when the call ended
1009
- * @type {string}
1002
+ *
1003
+ * @type {EgressResponse}
1010
1004
  * @memberof CallResponse
1011
1005
  */
1012
- ended_at?: string;
1006
+ egress: EgressResponse;
1013
1007
  /**
1014
- *
1008
+ * Date/time when the call ended
1015
1009
  * @type {string}
1016
1010
  * @memberof CallResponse
1017
1011
  */
1018
- hls_playlist_url: string;
1012
+ ended_at?: string;
1019
1013
  /**
1020
1014
  * Call ID
1021
1015
  * @type {string}
@@ -1971,6 +1965,69 @@ export interface EdgeResponse {
1971
1965
  */
1972
1966
  yellow: number;
1973
1967
  }
1968
+ /**
1969
+ *
1970
+ * @export
1971
+ * @interface EgressHLSResponse
1972
+ */
1973
+ export interface EgressHLSResponse {
1974
+ /**
1975
+ *
1976
+ * @type {string}
1977
+ * @memberof EgressHLSResponse
1978
+ */
1979
+ playlist_url: string;
1980
+ }
1981
+ /**
1982
+ *
1983
+ * @export
1984
+ * @interface EgressRTMPResponse
1985
+ */
1986
+ export interface EgressRTMPResponse {
1987
+ /**
1988
+ *
1989
+ * @type {string}
1990
+ * @memberof EgressRTMPResponse
1991
+ */
1992
+ name: string;
1993
+ /**
1994
+ *
1995
+ * @type {string}
1996
+ * @memberof EgressRTMPResponse
1997
+ */
1998
+ stream_key: string;
1999
+ /**
2000
+ *
2001
+ * @type {string}
2002
+ * @memberof EgressRTMPResponse
2003
+ */
2004
+ url: string;
2005
+ }
2006
+ /**
2007
+ *
2008
+ * @export
2009
+ * @interface EgressResponse
2010
+ */
2011
+ export interface EgressResponse {
2012
+ /**
2013
+ *
2014
+ * @type {boolean}
2015
+ * @memberof EgressResponse
2016
+ */
2017
+ broadcasting: boolean;
2018
+ /**
2019
+ *
2020
+ * @type {EgressHLSResponse}
2021
+ * @memberof EgressResponse
2022
+ */
2023
+ hls?: EgressHLSResponse;
2024
+ /**
2025
+ *
2026
+ * @type {Array<EgressRTMPResponse>}
2027
+ * @memberof EgressResponse
2028
+ */
2029
+ rtmps: Array<EgressRTMPResponse>;
2030
+ }
1974
2031
  /**
1975
2032
  *
1976
2033
  * @export
@@ -69,7 +69,7 @@ const getMediaSection = (sdp: string, mediaType: 'video' | 'audio') => {
69
69
  sdp.split(/(\r\n|\r|\n)/).forEach((line) => {
70
70
  const isValidLine = /^([a-z])=(.*)/.test(line);
71
71
  if (!isValidLine) return;
72
- /*
72
+ /*
73
73
  NOTE: according to https://www.rfc-editor.org/rfc/rfc8866.pdf
74
74
  Each media description starts with an "m=" line and continues to the next media description or the end of the whole session description, whichever comes first
75
75
  */
@@ -170,7 +170,7 @@ export const removeCodec = (
170
170
  sdp: string,
171
171
  mediaType: 'video' | 'audio',
172
172
  codecToRemove: string,
173
- ) => {
173
+ ): string => {
174
174
  const section = getMediaSection(sdp, mediaType);
175
175
  const mediaSection = section?.media;
176
176
  if (!mediaSection) {
@@ -190,30 +190,26 @@ export const removeCodec = (
190
190
  mediaSection.original,
191
191
  `${mediaSection.mediaWithPorts} ${newCodecOrder}`,
192
192
  )
193
- .replace(new RegExp(`${rtpMap.original}[\r\n|\r|\n]`), '') // remove the corresponding rtpmap line
194
- .replace(
195
- fmtp?.original ? new RegExp(`${fmtp?.original}[\r\n|\r|\n]`) : '',
196
- '',
197
- ); // remove the corresponding fmtp line
193
+ .replace(new RegExp(`${rtpMap.original}[\r\n]+`), '') // remove the corresponding rtpmap line
194
+ .replace(fmtp?.original ? new RegExp(`${fmtp?.original}[\r\n]+`) : '', ''); // remove the corresponding fmtp line
198
195
  };
199
196
 
200
197
  /**
201
198
  * Gets the fmtp line corresponding to opus
202
199
  */
203
- const getOpusFmtp = (sdp: string) => {
200
+ const getOpusFmtp = (sdp: string): Fmtp | undefined => {
204
201
  const section = getMediaSection(sdp, 'audio');
205
202
  const rtpMap = section?.rtpMap.find((r) => r.codec.toLowerCase() === 'opus');
206
203
  const codecId = rtpMap?.payload;
207
204
  if (codecId) {
208
- const fmtp = section?.fmtp.find((f) => f.payload === codecId);
209
- return fmtp;
205
+ return section?.fmtp.find((f) => f.payload === codecId);
210
206
  }
211
207
  };
212
208
 
213
209
  /**
214
210
  * Returns an SDP with DTX enabled or disabled.
215
211
  */
216
- export const toggleDtx = (sdp: string, enable: boolean) => {
212
+ export const toggleDtx = (sdp: string, enable: boolean): string => {
217
213
  const opusFmtp = getOpusFmtp(sdp);
218
214
  if (opusFmtp) {
219
215
  const matchDtx = /usedtx=(\d)/.exec(opusFmtp.config);
@@ -342,7 +342,7 @@ export class Publisher {
342
342
  const offer = await this.publisher.createOffer();
343
343
  let sdp = offer.sdp;
344
344
  if (sdp) {
345
- toggleDtx(sdp, this.isDtxEnabled);
345
+ sdp = toggleDtx(sdp, this.isDtxEnabled);
346
346
  if (isReactNative()) {
347
347
  if (this.preferredVideoCodec) {
348
348
  sdp = setPreferredCodec(sdp, 'video', this.preferredVideoCodec);