Skip to content

Commit cfe4dab

Browse files
committed
Prepare for MediaStreamTrackProcessor in worker
1 parent a076ab5 commit cfe4dab

File tree

2 files changed

+268
-102
lines changed

2 files changed

+268
-102
lines changed

src/avinterface.js

Lines changed: 188 additions & 93 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ export class AVDeviceInputStream extends AVStream {
5858
constructor(args) {
5959
super(args)
6060
this.track = args.track
61+
this.trackEnabled = false
6162
this.deviceId = args.deviceId
6263
}
6364

@@ -110,8 +111,8 @@ export class AVVideoInputStream extends AVDeviceInputStream {
110111
}
111112

112113
videoOff() {
113-
if (this.track && !this.off) {
114-
this.track.enabled = false
114+
if ((this.track || this.trackEnabled) && !this.off) {
115+
if (this.track) this.track.enabled = false
115116
this.off = true
116117
AVInterface.worker.postMessage({
117118
task: 'offChange',
@@ -122,8 +123,8 @@ export class AVVideoInputStream extends AVDeviceInputStream {
122123
}
123124

124125
videoOn() {
125-
if (this.track && this.off) {
126-
this.track.enabled = true
126+
if ((this.track || this.trackEnabled) && this.off) {
127+
if (this.track) this.track.enabled = true
127128
this.off = false
128129
AVInterface.worker.postMessage({
129130
task: 'offChange',
@@ -202,52 +203,80 @@ export class AVVideoInputStream extends AVDeviceInputStream {
202203
}
203204

204205
switchTrack({ track, screenshare }) {
205-
// eslint-disable-next-line no-undef
206-
const trackprocessor = new MediaStreamTrackProcessor({
207-
track,
208-
maxBufferSize: 10
209-
})
210-
if (!this.track) {
211-
// now we will drop the track to the worker
212-
AVInterface.worker.postMessage(
213-
{
214-
task: 'openVideoInput',
215-
webworkid: this.webworkid,
216-
screenshare,
217-
readable: transferReadableStream(
218-
trackprocessor.readable,
219-
trackprocessor.isPolyfill
220-
)
221-
},
222-
[
223-
transferReadableStream(
224-
trackprocessor.readable,
225-
trackprocessor.isPolyfill
226-
)
227-
]
228-
)
206+
if (!AVInterface.mstinworker) {
207+
// eslint-disable-next-line no-undef
208+
const trackprocessor = new MediaStreamTrackProcessor({
209+
track,
210+
maxBufferSize: 10
211+
})
212+
if (!this.track) {
213+
// now we will drop the track to the worker
214+
AVInterface.worker.postMessage(
215+
{
216+
task: 'openVideoInput',
217+
webworkid: this.webworkid,
218+
screenshare,
219+
readable: transferReadableStream(
220+
trackprocessor.readable,
221+
trackprocessor.isPolyfill
222+
)
223+
},
224+
[
225+
transferReadableStream(
226+
trackprocessor.readable,
227+
trackprocessor.isPolyfill
228+
)
229+
]
230+
)
231+
} else {
232+
AVInterface.worker.postMessage(
233+
{
234+
task: 'switchVideoInput',
235+
screenshare,
236+
webworkid: this.webworkid,
237+
readable: transferReadableStream(
238+
trackprocessor.readable,
239+
trackprocessor.isPolyfill
240+
)
241+
},
242+
[
243+
transferReadableStream(
244+
trackprocessor.readable,
245+
trackprocessor.isPolyfill
246+
)
247+
]
248+
)
249+
}
250+
251+
this.track = track
252+
if (this.off) this.track.enabled = false
229253
} else {
230-
AVInterface.worker.postMessage(
231-
{
232-
task: 'switchVideoInput',
233-
screenshare,
234-
webworkid: this.webworkid,
235-
readable: transferReadableStream(
236-
trackprocessor.readable,
237-
trackprocessor.isPolyfill
238-
)
239-
},
240-
[
241-
transferReadableStream(
242-
trackprocessor.readable,
243-
trackprocessor.isPolyfill
244-
)
245-
]
246-
)
254+
if (!this.trackEnabled) {
255+
// now we will drop the track to the worker
256+
AVInterface.worker.postMessage(
257+
{
258+
task: 'openVideoInput',
259+
webworkid: this.webworkid,
260+
screenshare,
261+
track,
262+
off: this.off
263+
},
264+
[track]
265+
)
266+
} else {
267+
AVInterface.worker.postMessage(
268+
{
269+
task: 'switchVideoInput',
270+
screenshare,
271+
webworkid: this.webworkid,
272+
track,
273+
off: this.off
274+
},
275+
[track]
276+
)
277+
}
278+
this.trackEnabled = true
247279
}
248-
249-
this.track = track
250-
if (this.off) this.track.enabled = false
251280
}
252281
}
253282

@@ -303,8 +332,8 @@ export class AVMicrophoneStream extends AVDeviceInputStream {
303332
}
304333

305334
muteOn() {
306-
if (this.track && !this.mute) {
307-
this.track.enabled = false
335+
if ((this.track || this.trackEnabled) && !this.mute) {
336+
if (this.track) this.track.enabled = false
308337
this.mute = true
309338
AVInterface.worker.postMessage({
310339
task: 'muteChangeMic',
@@ -315,8 +344,8 @@ export class AVMicrophoneStream extends AVDeviceInputStream {
315344
}
316345

317346
muteOff() {
318-
if (this.track && this.mute) {
319-
this.track.enabled = true
347+
if ((this.track || this.trackEnabled) && this.mute) {
348+
if (this.track) this.track.enabled = true
320349
this.mute = false
321350
AVInterface.worker.postMessage({
322351
task: 'muteChangeMic',
@@ -355,46 +384,71 @@ export class AVMicrophoneStream extends AVDeviceInputStream {
355384
})
356385
console.log('audio track settings after', track.getSettings())
357386

358-
// eslint-disable-next-line no-undef
359-
const trackprocessor = new MediaStreamTrackProcessor({
360-
track,
361-
maxBufferSize: 10
362-
})
363-
if (!this.track) {
364-
// now we will drop the track to the worker
365-
AVInterface.worker.postMessage(
366-
{
367-
task: 'openAudioMicrophone',
368-
webworkid: this.webworkid,
369-
readable: transferReadableStream(
370-
trackprocessor.readable,
371-
trackprocessor.isPolyfill
372-
)
373-
},
374-
[
375-
transferReadableStream(
376-
trackprocessor.readable,
377-
trackprocessor.isPolyfill
378-
)
379-
]
380-
)
387+
if (!AVInterface.mstinworker) {
388+
// eslint-disable-next-line no-undef
389+
const trackprocessor = new MediaStreamTrackProcessor({
390+
track,
391+
maxBufferSize: 10
392+
})
393+
if (!this.track && !this.trackEnabled) {
394+
// now we will drop the track to the worker
395+
AVInterface.worker.postMessage(
396+
{
397+
task: 'openAudioMicrophone',
398+
webworkid: this.webworkid,
399+
readable: transferReadableStream(
400+
trackprocessor.readable,
401+
trackprocessor.isPolyfill
402+
)
403+
},
404+
[
405+
transferReadableStream(
406+
trackprocessor.readable,
407+
trackprocessor.isPolyfill
408+
)
409+
]
410+
)
411+
} else {
412+
AVInterface.worker.postMessage(
413+
{
414+
task: 'switchAudioMicrophone',
415+
webworkid: this.webworkid,
416+
readable: transferReadableStream(
417+
trackprocessor.readable,
418+
trackprocessor.isPolyfill
419+
)
420+
},
421+
[
422+
transferReadableStream(
423+
trackprocessor.readable,
424+
trackprocessor.isPolyfill
425+
)
426+
]
427+
)
428+
}
381429
} else {
382-
AVInterface.worker.postMessage(
383-
{
384-
task: 'switchAudioMicrophone',
385-
webworkid: this.webworkid,
386-
readable: transferReadableStream(
387-
trackprocessor.readable,
388-
trackprocessor.isPolyfill
389-
)
390-
},
391-
[
392-
transferReadableStream(
393-
trackprocessor.readable,
394-
trackprocessor.isPolyfill
395-
)
396-
]
397-
)
430+
if (!this.track && !this.trackEnabled) {
431+
// now we will drop the track to the worker
432+
AVInterface.worker.postMessage(
433+
{
434+
task: 'openAudioMicrophone',
435+
webworkid: this.webworkid,
436+
track,
437+
mute: this.mute
438+
},
439+
[track]
440+
)
441+
} else {
442+
AVInterface.worker.postMessage(
443+
{
444+
task: 'switchAudioMicrophone',
445+
webworkid: this.webworkid,
446+
track,
447+
mute: this.mute
448+
},
449+
[track]
450+
)
451+
}
398452
}
399453
const ac = AVInterface.getInterface().getAudioContext()
400454
const tracksource = ac.createMediaStreamSource(mstream)
@@ -414,8 +468,12 @@ export class AVMicrophoneStream extends AVDeviceInputStream {
414468

415469
this.tracksource = tracksource
416470

417-
this.track = track
418-
if (this.mute) this.track.enabled = false
471+
if (AVInterface.mstinworker) {
472+
this.trackEnabled = true
473+
} else {
474+
this.track = track
475+
if (this.mute) this.track.enabled = false
476+
}
419477
}
420478
}
421479

@@ -520,6 +578,7 @@ export class AVInterface {
520578
static interf = null
521579
static mediadevicesupported = false
522580
static userhash // unique hash, should be set, so that we can distinguish users, but should be a hash, so that we can not identify!
581+
static mstinworker = false
523582

524583
constructor(
525584
args // do not call directly
@@ -550,6 +609,9 @@ export class AVInterface {
550609
AVInterface.worker.addEventListener('message', interf.onMessage)
551610
AVInterface.worker.addEventListener('error', interf.onError)
552611
AVInterface.worker.addEventListener('messageerror', interf.onMessageError)
612+
AVInterface.worker.postMessage({
613+
task: 'probeMSTP'
614+
})
553615
return AVInterface.interf
554616
}
555617

@@ -651,6 +713,36 @@ export class AVInterface {
651713
this.avstatuscbs.delete(cb)
652714
}
653715

716+
tryActivateMstWorker() {
717+
// we have a media stream track source inside a worker
718+
// let's check if the Mediatrack is transferable
719+
try {
720+
const canvas = document.createElement('canvas')
721+
canvas.width = 40
722+
canvas.height = 40
723+
const stream = canvas.captureStream(1)
724+
const testtrack = stream.getVideoTracks()[0]
725+
testtrack.stop()
726+
AVInterface.worker.postMessage(
727+
{
728+
task: 'testtransferabletrack',
729+
testtrack
730+
},
731+
[testtrack]
732+
)
733+
AVInterface.mstinworker = true
734+
} catch (error) {
735+
// eslint-disable-next-line no-undef
736+
if (!(error instanceof DataCloneError)) {
737+
console.log('Test error result', error)
738+
}
739+
// deactivvate in any error case
740+
AVInterface.mstinworker = false
741+
}
742+
console.log('Create MediaStreamTrackProcessor in worker!')
743+
AVInterface.mstinworker = false // deactivate until testing is possible
744+
}
745+
654746
onMessage(event) {
655747
const task = event.data.task
656748
switch (task) {
@@ -724,6 +816,9 @@ export class AVInterface {
724816
obj.extBlocked({ reason: event.data.block })
725817
}
726818
break
819+
case 'activatemstinworker':
820+
this.tryActivateMstWorker()
821+
break
727822
default:
728823
console.log('unhandled onMessage', event)
729824
break

0 commit comments

Comments
 (0)