mirror of
https://github.com/davedoesdev/streamana.git
synced 2025-12-24 13:28:19 +08:00
Remove a layer of Worker
This commit is contained in:
@@ -1,99 +0,0 @@
|
||||
let ffmpeg_worker;
|
||||
let ffmpeg_args;
|
||||
let base_url;
|
||||
|
||||
function onerror(e) {
|
||||
if (ffmpeg_worker) {
|
||||
console.error(e);
|
||||
self.postMessage({
|
||||
type: 'error',
|
||||
detail: e.message
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function ffmpeg_onmessage(e) {
|
||||
const msg = e.data;
|
||||
switch (msg.type) {
|
||||
case 'ready':
|
||||
this.postMessage({
|
||||
type: 'run',
|
||||
arguments: [
|
||||
'-loglevel', 'debug',
|
||||
...ffmpeg_args,
|
||||
'-f', 'hls', // use hls encoder
|
||||
'-hls_time', '2', // 2 second HLS chunks
|
||||
'-hls_segment_type', 'mpegts', // MPEG2-TS muxer
|
||||
'-hls_list_size', '2', // two chunks in the list at a time
|
||||
'-hls_flags', 'split_by_time',
|
||||
'/outbound/output.m3u8' // path to media playlist file in virtual FS,
|
||||
// must be under /outbound
|
||||
],
|
||||
MEMFS: [
|
||||
{ name: 'stream1' },
|
||||
{ name: 'stream2' }
|
||||
]
|
||||
});
|
||||
break;
|
||||
case 'stdout':
|
||||
console.log(msg.data);
|
||||
break;
|
||||
case 'stderr':
|
||||
console.error(msg.data);
|
||||
break;
|
||||
case 'error':
|
||||
case 'abort':
|
||||
onerror(msg.data);
|
||||
break;
|
||||
case 'start-stream':
|
||||
this.postMessage({
|
||||
type: 'base-url',
|
||||
data: base_url
|
||||
});
|
||||
self.postMessage(msg);
|
||||
break;
|
||||
case 'exit':
|
||||
ffmpeg_worker = null;
|
||||
self.postMessage({ type: msg.type, code: msg.data });
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
onmessage = function (e) {
|
||||
const msg = e.data;
|
||||
switch (msg.type) {
|
||||
case 'start':
|
||||
({ ffmpeg_args, base_url } = msg);
|
||||
ffmpeg_worker = new Worker(msg.ffmpeg_lib_url);
|
||||
ffmpeg_worker.onerror = onerror;
|
||||
ffmpeg_worker.onmessage = ffmpeg_onmessage;
|
||||
break;
|
||||
case 'end':
|
||||
if (ffmpeg_worker) {
|
||||
if (msg.force) {
|
||||
ffmpeg_worker.terminate();
|
||||
self.postMessage({
|
||||
type: 'exit',
|
||||
code: 'force-end'
|
||||
});
|
||||
} else {
|
||||
ffmpeg_worker.postMessage({
|
||||
type: 'stream-end'
|
||||
});
|
||||
}
|
||||
ffmpeg_worker = null;
|
||||
}
|
||||
break;
|
||||
case 'muxed-data':
|
||||
if (ffmpeg_worker) {
|
||||
ffmpeg_worker.postMessage({
|
||||
type: 'stream-data',
|
||||
name: msg.name,
|
||||
data: msg.data
|
||||
}, [msg.data]);
|
||||
}
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
self.postMessage({ type: 'ready' });
|
||||
38
site/hls.js
38
site/hls.js
@@ -1,4 +1,5 @@
|
||||
import { UpdateLimiter } from './update-limiter.js';
|
||||
import { WebMDestination } from './webm-destination.js';
|
||||
|
||||
const audioBitsPerSecond = 128 * 1000;
|
||||
const videoBitsPerSecond = 2500 * 1000;
|
||||
@@ -74,13 +75,9 @@ export class HLS extends EventTarget {
|
||||
|
||||
// push encoded data into the ffmpeg worker
|
||||
recorder.ondataavailable = async event => {
|
||||
if (this.worker) {
|
||||
const data = await event.data.arrayBuffer();
|
||||
this.worker.postMessage({
|
||||
type: 'muxed-data',
|
||||
name: 'stream1',
|
||||
data
|
||||
}, [data]);
|
||||
if (this.destination) {
|
||||
this.destination.muxed_data(await event.data.arrayBuffer(),
|
||||
{ name: 'stream1' });
|
||||
}
|
||||
};
|
||||
|
||||
@@ -96,16 +93,13 @@ export class HLS extends EventTarget {
|
||||
dummy_processor.connect(context.destination);
|
||||
|
||||
// start the ffmpeg worker
|
||||
this.worker = new Worker('./hls-worker.js');
|
||||
this.worker.onerror = onerror;
|
||||
this.worker.onmessage = e => {
|
||||
const msg = e.data;
|
||||
this.destination = new WebMDestination();
|
||||
this.destination.addEventListener('message', e => {
|
||||
const msg = e.detail;
|
||||
switch (msg.type) {
|
||||
case 'ready':
|
||||
this.worker.postMessage({
|
||||
type: 'start',
|
||||
this.destination.start({
|
||||
ffmpeg_lib_url: this.ffmpeg_lib_url,
|
||||
base_url: this.base_url,
|
||||
ffmpeg_args: [
|
||||
'-i', '/work/stream1',
|
||||
'-map', '0:v',
|
||||
@@ -115,7 +109,8 @@ export class HLS extends EventTarget {
|
||||
['-c:a', 'copy'] : // assume already AAC
|
||||
['-c:a', 'aac', // re-encode audio as AAC-LC
|
||||
'-b:a', audioBitsPerSecond.toString()]) // set audio bitrate
|
||||
]
|
||||
],
|
||||
base_url: this.base_url
|
||||
});
|
||||
break;
|
||||
|
||||
@@ -130,8 +125,7 @@ export class HLS extends EventTarget {
|
||||
break;
|
||||
|
||||
case 'exit':
|
||||
this.worker.terminate();
|
||||
this.worker = null;
|
||||
this.destination = null;
|
||||
if (recorder.state !== 'inactive') {
|
||||
recorder.stop();
|
||||
}
|
||||
@@ -140,7 +134,7 @@ export class HLS extends EventTarget {
|
||||
this.dispatchEvent(new CustomEvent(msg.type, { detail: { code: msg.code } }));
|
||||
break;
|
||||
}
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
webcodecs(video_codec, audio_codec, video_config, audio_config) {
|
||||
@@ -248,7 +242,7 @@ export class HLS extends EventTarget {
|
||||
codec_id: 'A_OPUS'
|
||||
}
|
||||
},
|
||||
webm_destination: './hls-worker.js',
|
||||
webm_destination: './webm-destination.js',
|
||||
muxed_metadata: { name: 'stream1' },
|
||||
ffmpeg_lib_url: this.ffmpeg_lib_url,
|
||||
base_url: this.base_url,
|
||||
@@ -264,7 +258,9 @@ export class HLS extends EventTarget {
|
||||
}
|
||||
|
||||
end(force) {
|
||||
if (this.worker) {
|
||||
if (this.destination) {
|
||||
this.destination.end({ force });
|
||||
} else if (this.worker) {
|
||||
this.worker.postMessage({
|
||||
type: 'end',
|
||||
force
|
||||
@@ -273,7 +269,7 @@ export class HLS extends EventTarget {
|
||||
}
|
||||
|
||||
onerror(e) {
|
||||
if (this.worker) {
|
||||
if (this.destination || this.worker) {
|
||||
this.dispatchEvent(new CustomEvent('error', { detail: e }));
|
||||
}
|
||||
};
|
||||
|
||||
104
site/webm-destination.js
Normal file
104
site/webm-destination.js
Normal file
@@ -0,0 +1,104 @@
|
||||
export class WebMDestination extends EventTarget {
|
||||
constructor() {
|
||||
super();
|
||||
setTimeout(() => {
|
||||
this.dispatchEvent(new CustomEvent('message', { detail: {
|
||||
type: 'ready'
|
||||
}}));
|
||||
}, 0);
|
||||
}
|
||||
|
||||
start({ ffmpeg_lib_url, ffmpeg_args, base_url }) {
|
||||
this.worker = new Worker(ffmpeg_lib_url);
|
||||
this.worker.onerror = this.onerror.bind(this);
|
||||
this.worker.onmessage = e => {
|
||||
const msg = e.data;
|
||||
switch (msg.type) {
|
||||
case 'ready':
|
||||
this.worker.postMessage({
|
||||
type: 'run',
|
||||
arguments: [
|
||||
'-loglevel', 'debug',
|
||||
...ffmpeg_args,
|
||||
'-f', 'hls', // use hls encoder
|
||||
'-hls_time', '2', // 2 second HLS chunks
|
||||
'-hls_segment_type', 'mpegts', // MPEG2-TS muxer
|
||||
'-hls_list_size', '2', // two chunks in the list at a time
|
||||
'-hls_flags', 'split_by_time',
|
||||
'/outbound/output.m3u8' // path to media playlist file in virtual FS,
|
||||
// must be under /outbound
|
||||
],
|
||||
MEMFS: [
|
||||
{ name: 'stream1' },
|
||||
{ name: 'stream2' }
|
||||
]
|
||||
});
|
||||
break;
|
||||
case 'stdout':
|
||||
console.log(msg.data);
|
||||
break;
|
||||
case 'stderr':
|
||||
console.error(msg.data);
|
||||
break;
|
||||
case 'error':
|
||||
case 'abort':
|
||||
this.onerror(msg.data);
|
||||
break;
|
||||
case 'start-stream':
|
||||
this.worker.postMessage({
|
||||
type: 'base-url',
|
||||
data: base_url
|
||||
});
|
||||
this.dispatchEvent(new CustomEvent('message', { detail: msg }));
|
||||
break;
|
||||
case 'exit':
|
||||
this.worker = null;
|
||||
this.dispatchEvent(new CustomEvent('message', { detail: {
|
||||
type: msg.type,
|
||||
code: msg.data
|
||||
}}));
|
||||
this.worker.terminate();
|
||||
break;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
muxed_data(data, { name }) {
|
||||
if (this.worker) {
|
||||
this.worker.postMessage({
|
||||
type: 'stream-data',
|
||||
name,
|
||||
data
|
||||
}, [data]);
|
||||
}
|
||||
}
|
||||
|
||||
end({ force }) {
|
||||
if (this.worker) {
|
||||
if (force) {
|
||||
this.worker.terminate();
|
||||
self.postMessage({
|
||||
this.dispatchEvent(new CustomEvent('message', { detail: {
|
||||
type: 'exit',
|
||||
code: 'force-end'
|
||||
}}));
|
||||
});
|
||||
} else {
|
||||
this.worker.postMessage({
|
||||
type: 'stream-end'
|
||||
});
|
||||
}
|
||||
this.worker = null;
|
||||
}
|
||||
}
|
||||
|
||||
onerror(e) {
|
||||
if (this.worker) {
|
||||
console.error(e);
|
||||
this.dispatchEvent(new CustomEvent('message', { detail: {
|
||||
type: 'error',
|
||||
detail: e.message
|
||||
}}));
|
||||
}
|
||||
}
|
||||
}
|
||||
Submodule webm-muxer.js updated: c4c051469c...73cb64a981
Reference in New Issue
Block a user