@fishjam-cloud/ts-client 0.7.1 → 0.7.2
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.
- package/dist/src/webrtc/CommandsQueue.d.ts +2 -2
- package/dist/src/webrtc/CommandsQueue.js +4 -3
- package/dist/src/webrtc/tracks/LocalTrack.js +17 -15
- package/dist/src/webrtc/tracks/muteTrackUtils.d.ts +3 -0
- package/dist/src/webrtc/tracks/muteTrackUtils.js +19 -0
- package/dist/src/webrtc/webRTCEndpoint.js +4 -10
- package/package.json +6 -6
|
@@ -2,10 +2,10 @@ import type { Deferred } from './deferred';
|
|
|
2
2
|
import type { LocalTrackManager } from './tracks/LocalTrackManager';
|
|
3
3
|
import type { ConnectionManager } from './ConnectionManager';
|
|
4
4
|
export type Command = {
|
|
5
|
-
handler: () => void
|
|
5
|
+
handler: () => Promise<void>;
|
|
6
6
|
parse?: () => void;
|
|
7
7
|
resolutionNotifier: Deferred<void>;
|
|
8
|
-
resolve: 'after-renegotiation' | '
|
|
8
|
+
resolve: 'after-renegotiation' | 'on-handler-resolve';
|
|
9
9
|
};
|
|
10
10
|
export declare class CommandsQueue<EndpointMetadata, TrackMetadata> {
|
|
11
11
|
private readonly localTrackManager;
|
|
@@ -56,11 +56,12 @@ export class CommandsQueue {
|
|
|
56
56
|
this.commandResolutionNotifier = command.resolutionNotifier;
|
|
57
57
|
this.handleCommand(command);
|
|
58
58
|
};
|
|
59
|
-
handleCommand = (command) => {
|
|
59
|
+
handleCommand = async (command) => {
|
|
60
60
|
try {
|
|
61
61
|
command.parse?.();
|
|
62
|
-
command.handler();
|
|
63
|
-
if (command.resolve === '
|
|
62
|
+
const promise = command.handler();
|
|
63
|
+
if (command.resolve === 'on-handler-resolve') {
|
|
64
|
+
await promise;
|
|
64
65
|
this.resolvePreviousCommand();
|
|
65
66
|
this.processNextCommand();
|
|
66
67
|
}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import { generateCustomEvent
|
|
1
|
+
import { generateCustomEvent } from '../mediaEvent';
|
|
2
2
|
import { defaultBitrates, defaultSimulcastBitrates, UNLIMITED_BANDWIDTH } from '../bitrate';
|
|
3
3
|
import { getEncodingParameters } from './encodings';
|
|
4
4
|
import { createTransceiverConfig } from './transceivers';
|
|
5
|
+
import { emitMutableEvents, getActionType } from './muteTrackUtils';
|
|
5
6
|
/**
|
|
6
7
|
* This is a wrapper over `TrackContext` that adds additional properties such as:
|
|
7
8
|
* - `MLineId`: required to generate sdpOffer
|
|
@@ -99,6 +100,7 @@ export class LocalTrack {
|
|
|
99
100
|
replaceTrack = async (newTrack, webrtc) => {
|
|
100
101
|
const trackId = this.id;
|
|
101
102
|
const stream = this.trackContext.stream;
|
|
103
|
+
const oldTrack = this.trackContext.track;
|
|
102
104
|
if (!this.sender)
|
|
103
105
|
throw Error('There is no RTCRtpSender for this track id!');
|
|
104
106
|
stream?.getTracks().forEach((track) => {
|
|
@@ -107,25 +109,25 @@ export class LocalTrack {
|
|
|
107
109
|
if (newTrack) {
|
|
108
110
|
stream?.addTrack(newTrack);
|
|
109
111
|
}
|
|
110
|
-
|
|
111
|
-
const mediaEvent = generateMediaEvent('muteTrack', { trackId: trackId });
|
|
112
|
-
webrtc.sendMediaEvent(mediaEvent);
|
|
113
|
-
webrtc.emit('localTrackMuted', { trackId: trackId });
|
|
114
|
-
}
|
|
115
|
-
else if (!this.trackContext.track && newTrack) {
|
|
116
|
-
const mediaEvent = generateMediaEvent('unmuteTrack', {
|
|
117
|
-
trackId: trackId,
|
|
118
|
-
});
|
|
119
|
-
webrtc.sendMediaEvent(mediaEvent);
|
|
120
|
-
webrtc.emit('localTrackUnmuted', { trackId: trackId });
|
|
121
|
-
}
|
|
112
|
+
this.trackContext.track = newTrack;
|
|
122
113
|
this.mediaStreamTrackId = newTrack?.id ?? null;
|
|
114
|
+
const action = getActionType(this.trackContext.track, newTrack);
|
|
115
|
+
if (action === 'mute' || action === 'unmute') {
|
|
116
|
+
emitMutableEvents(action, webrtc, trackId);
|
|
117
|
+
}
|
|
123
118
|
try {
|
|
124
119
|
await this.sender.replaceTrack(newTrack);
|
|
125
|
-
this.trackContext.track = newTrack;
|
|
126
120
|
}
|
|
127
121
|
catch (_error) {
|
|
128
|
-
//
|
|
122
|
+
// rollback: emit opposite events and revert internal state
|
|
123
|
+
if (action === 'mute') {
|
|
124
|
+
emitMutableEvents('unmute', webrtc, trackId);
|
|
125
|
+
}
|
|
126
|
+
else if (action === 'unmute') {
|
|
127
|
+
emitMutableEvents('mute', webrtc, trackId);
|
|
128
|
+
}
|
|
129
|
+
this.trackContext.track = oldTrack;
|
|
130
|
+
this.mediaStreamTrackId = oldTrack?.id ?? null;
|
|
129
131
|
}
|
|
130
132
|
};
|
|
131
133
|
setTrackBandwidth = (bandwidth) => {
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import type { WebRTCEndpoint } from '../webRTCEndpoint';
|
|
2
|
+
export declare function emitMutableEvents<EndpointMetadata, TrackMetadata>(action: 'mute' | 'unmute', webrtc: WebRTCEndpoint<EndpointMetadata, TrackMetadata>, trackId: string): void;
|
|
3
|
+
export declare function getActionType(currentTrack: MediaStreamTrack | null, newTrack: MediaStreamTrack | null): 'mute' | 'unmute' | 'replace';
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { generateMediaEvent } from '../mediaEvent';
|
|
2
|
+
export function emitMutableEvents(action, webrtc, trackId) {
|
|
3
|
+
const mediaEventType = action === 'mute' ? `muteTrack` : `unmuteTrack`;
|
|
4
|
+
const localEventType = action === 'mute' ? `localTrackMuted` : `localTrackUnmuted`;
|
|
5
|
+
const mediaEvent = generateMediaEvent(mediaEventType, { trackId: trackId });
|
|
6
|
+
webrtc.sendMediaEvent(mediaEvent);
|
|
7
|
+
webrtc.emit(localEventType, { trackId: trackId });
|
|
8
|
+
}
|
|
9
|
+
export function getActionType(currentTrack, newTrack) {
|
|
10
|
+
if (currentTrack && !newTrack) {
|
|
11
|
+
return 'mute';
|
|
12
|
+
}
|
|
13
|
+
else if (!currentTrack && newTrack) {
|
|
14
|
+
return 'unmute';
|
|
15
|
+
}
|
|
16
|
+
else {
|
|
17
|
+
return 'replace';
|
|
18
|
+
}
|
|
19
|
+
}
|
|
@@ -327,9 +327,7 @@ export class WebRTCEndpoint extends EventEmitter {
|
|
|
327
327
|
metadata = parsedMetadata;
|
|
328
328
|
stream.addTrack(track);
|
|
329
329
|
this.commandsQueue.pushCommand({
|
|
330
|
-
handler: () =>
|
|
331
|
-
this.localTrackManager.addTrackHandler(trackId, track, stream, parsedMetadata, simulcastConfig, maxBandwidth);
|
|
332
|
-
},
|
|
330
|
+
handler: async () => this.localTrackManager.addTrackHandler(trackId, track, stream, parsedMetadata, simulcastConfig, maxBandwidth),
|
|
333
331
|
parse: () => this.localTrackManager.parseAddTrack(track, simulcastConfig, maxBandwidth),
|
|
334
332
|
resolve: 'after-renegotiation',
|
|
335
333
|
resolutionNotifier,
|
|
@@ -397,11 +395,9 @@ export class WebRTCEndpoint extends EventEmitter {
|
|
|
397
395
|
async replaceTrack(trackId, newTrack) {
|
|
398
396
|
const resolutionNotifier = new Deferred();
|
|
399
397
|
this.commandsQueue.pushCommand({
|
|
400
|
-
handler: () =>
|
|
401
|
-
this.localTrackManager.replaceTrackHandler(this, trackId, newTrack);
|
|
402
|
-
},
|
|
398
|
+
handler: () => this.localTrackManager.replaceTrackHandler(this, trackId, newTrack),
|
|
403
399
|
resolutionNotifier,
|
|
404
|
-
resolve: '
|
|
400
|
+
resolve: 'on-handler-resolve',
|
|
405
401
|
});
|
|
406
402
|
return resolutionNotifier.promise.then(() => {
|
|
407
403
|
this.emit('localTrackReplaced', { trackId, track: newTrack });
|
|
@@ -466,9 +462,7 @@ export class WebRTCEndpoint extends EventEmitter {
|
|
|
466
462
|
async removeTrack(trackId) {
|
|
467
463
|
const resolutionNotifier = new Deferred();
|
|
468
464
|
this.commandsQueue.pushCommand({
|
|
469
|
-
handler: () =>
|
|
470
|
-
this.localTrackManager.removeTrackHandler(trackId);
|
|
471
|
-
},
|
|
465
|
+
handler: async () => this.localTrackManager.removeTrackHandler(trackId),
|
|
472
466
|
resolutionNotifier,
|
|
473
467
|
resolve: 'after-renegotiation',
|
|
474
468
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fishjam-cloud/ts-client",
|
|
3
|
-
"version": "0.7.
|
|
3
|
+
"version": "0.7.2",
|
|
4
4
|
"description": "Typescript client library for Fishjam Cloud",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"author": "Fishjam Cloud Team",
|
|
@@ -53,20 +53,20 @@
|
|
|
53
53
|
"devDependencies": {
|
|
54
54
|
"@playwright/test": "^1.47.2",
|
|
55
55
|
"@types/events": "^3.0.3",
|
|
56
|
-
"@types/node": "^22.7.
|
|
56
|
+
"@types/node": "^22.7.5",
|
|
57
57
|
"@types/uuid": "^10.0.0",
|
|
58
|
-
"@vitest/coverage-v8": "^2.1.
|
|
58
|
+
"@vitest/coverage-v8": "^2.1.2",
|
|
59
59
|
"fake-mediastreamtrack": "^1.2.0",
|
|
60
60
|
"husky": "^9.1.6",
|
|
61
61
|
"lint-staged": "^15.2.10",
|
|
62
62
|
"react": "^18.2.0",
|
|
63
|
-
"ts-proto": "^2.2.
|
|
63
|
+
"ts-proto": "^2.2.3",
|
|
64
64
|
"typed-emitter": "^2.1.0",
|
|
65
|
-
"typedoc": "^0.26.
|
|
65
|
+
"typedoc": "^0.26.8",
|
|
66
66
|
"typedoc-plugin-external-resolver": "^1.0.3",
|
|
67
67
|
"typedoc-plugin-mdn-links": "^3.3.2",
|
|
68
68
|
"typescript": "^5.6.2",
|
|
69
|
-
"vitest": "^2.1.
|
|
69
|
+
"vitest": "^2.1.2",
|
|
70
70
|
"zod": "^3.23.6"
|
|
71
71
|
},
|
|
72
72
|
"lint-staged": {
|