-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmediastream.js
72 lines (65 loc) · 2.59 KB
/
mediastream.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
/* ---------------------------------------------------------------------------
** This software is in the public domain, furnished "as is", without technical
** support, and with no warranty, express or implied, as to its usefulness for
** any purpose.
**
** -------------------------------------------------------------------------*/
import { VideoProcessor } from './videoprocessor.js';
import { AudioProcessor } from './audioprocessor.js';
export class MediaStream {
reconnectTimer = null;
ws = null;
metadata = {media:'', codec: '', freq: 0, channels: 0, ts: 0, type: ''};
constructor(videoCanvas, audioContext, onvideoloadedcallback, onaudioloadedcallback) {
this.videoProcessor = new VideoProcessor(videoCanvas, onvideoloadedcallback);
if (audioContext) {
this.audioProcessor = new AudioProcessor(audioContext, onaudioloadedcallback);
}
}
async onMessage(message) {
const { data } = message;
try {
if (data instanceof ArrayBuffer) {
const bytes = new Uint8Array(data);
if (this.metadata.media === 'video') {
await this.videoProcessor.onVideoFrame(this.metadata, bytes);
} else if (this.metadata.media === 'audio') {
await this.audioProcessor?.onAudioFrame(this.metadata, bytes);
}
} else if (typeof data === 'string') {
this.metadata = JSON.parse(data);
}
} catch (e) {
console.warn(e);
}
}
setVolume(volume) {
this.audioProcessor?.setVolume(volume);
}
connect(stream) {
let wsurl = new URL(stream, location.href);
wsurl.protocol = wsurl.protocol.replace("http", "ws");
this.close();
console.log(`Connecting WebSocket to ${wsurl}`);
this.ws = new WebSocket(wsurl.href);
this.ws.binaryType = 'arraybuffer';
this.ws.onopen = () => clearTimeout(this.reconnectTimer);
this.ws.onerror = () => console.log(`WebSocket error`);
this.ws.onmessage = (message) => this.onMessage(message);
this.ws.onclose = () => this.reconnectTimer = setTimeout(() => this.connect(stream), 1000);
}
close() {
if (this.reconnectTimer) {
clearTimeout(this.reconnectTimer);
this.reconnectTimer = null;
}
if (this.ws) {
this.ws.onclose = () => {};
this.ws.onerror = () => {};
this.ws.close();
}
this.ws = null;
this.videoProcessor.close();
this.audioProcessor?.close();
}
}