-
Notifications
You must be signed in to change notification settings - Fork 12
/
Copy pathindex.html
107 lines (89 loc) · 4.15 KB
/
index.html
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
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
<html>
<head></head>
<body>
<img id="image" width="640" height="480"/>
<canvas id="canvas" width="640" heigth="480"></canvas>
<script>
// The mjpeg url.
const url = "/mjpeg";
const SOI = new Uint8Array(2);
SOI[0] = 0xFF;
SOI[1] = 0xD8;
const CONTENT_LENGTH = 'content-length';
const TYPE_JPEG = 'image/jpeg';
let image = document.getElementById('image');
fetch(url)
.then(response => {
if (!response.ok) {
throw Error(response.status+' '+response.statusText)
}
if (!response.body) {
throw Error('ReadableStream not yet supported in this browser.')
}
const reader = response.body.getReader();
let headers = '';
let contentLength = -1;
let imageBuffer = null;
let bytesRead = 0;
// calculating fps. This is pretty lame. Should probably implement a floating window function.
let frames = 0;
setInterval(() => {
console.log("fps : " + frames);
frames = 0;
}, 1000)
const read = () => {
reader.read().then(({done, value}) => {
if (done) {
controller.close();
return;
}
for (let index =0; index < value.length; index++) {
// we've found start of the frame. Everything we've read till now is the header.
if (value[index] === SOI[0] && value[index+1] === SOI[1]) {
// console.log('header found : ' + newHeader);
contentLength = getLength(headers);
// console.log("Content Length : " + newContentLength);
imageBuffer = new Uint8Array(new ArrayBuffer(contentLength));
}
// we're still reading the header.
if (contentLength <= 0) {
headers += String.fromCharCode(value[index]);
}
// we're now reading the jpeg.
else if (bytesRead < contentLength){
imageBuffer[bytesRead++] = value[index];
}
// we're done reading the jpeg. Time to render it.
else {
// console.log("jpeg read with bytes : " + bytesRead);
let frame = URL.createObjectURL(new Blob([imageBuffer], {type: MJPEG.TYPE_JPEG}))
image.src = frame;
URL.revokeObjectURL(frame)
frames++;
contentLength = 0;
bytesRead = 0;
headers = '';
}
}
read();
}).catch(error => {
console.error(error);
})
}
read();
}).catch(error => {
console.error(error);
})
const getLength = (headers) => {
let contentLength = -1;
headers.split('\n').forEach((header, _) => {
const pair = header.split(':');
if (pair[0].toLowerCase() === CONTENT_LENGTH) { // Fix for issue https://github.com/aruntj/mjpeg-readable-stream/issues/3 suggested by martapanc
contentLength = pair[1];
}
})
return contentLength;
};
</script>
</body>
</html>