forked from nintha/river
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathplayer.html
More file actions
115 lines (97 loc) · 3.5 KB
/
Copy pathplayer.html
File metadata and controls
115 lines (97 loc) · 3.5 KB
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
108
109
110
111
112
113
114
115
<!doctype html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/semantic-ui@2.4.2/dist/semantic.min.css">
<script src="https://cdn.jsdelivr.net/npm/jquery@3.2.1/dist/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/semantic-ui@2.4.2/dist/semantic.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/jmuxer@2.0.2/dist/jmuxer.min.js"></script>
<title>River Player</title>
</head>
<body>
<div id="container" style="margin: 10px auto 0; width: 1024px;">
<video style="border: 1px solid #333; width: 1024px;" autoplay id="player"></video>
<br>
<div>
<button class="ui labeled icon button" onclick="open_ws(url, jmuxer);">
<i class="play icon"></i>
Play
</button>
<button class="ui labeled icon button" onclick="close_ws()">
<i class="stop icon"></i>
Stop
</button>
<button class="ui labeled icon disabled button" onclick="">
<i class="expand icon"></i>
Expand
</button>
</div>
</div>
</body>
<script>
const ctx = {/*$INJECTED_CONTEXT*/};
const url = `ws://${document.domain}:${ctx.port}/websocket${window.location.pathname}`;
let jmuxer = null;
let timer_id = null;
let close_ws = () => {
};
$(function main() {
jmuxer = new JMuxer({
flushingTime: 50,
fps: 30,
node: 'player',
mode: 'both', /* available values are: both, audio and video */
debug: false
});
let player = video_element = document.getElementById('player');
document.addEventListener("visibilitychange", function () {
forward_latest_frame(player);
});
timer_id = setInterval(() => {
forward_latest_frame(player);
}, 2000);
});
function open_ws(url, jmuxer) {
close_ws();
const socket = new WebSocket(url);
socket.binaryType = 'arraybuffer';
socket.addEventListener('open', function () {
console.log(`[event open] url=${url}`);
});
socket.addEventListener('message', function (event) {
feed_data(jmuxer, new Uint8Array(event.data));
});
socket.addEventListener('close', function () {
console.log(`[event close]`);
});
close_ws = () => {
clearInterval(timer_id);
socket.close(1000);
console.info("[close_ws] closed");
}
}
/**
*
* @param jmuxer
* @param event_data
*/
function feed_data(jmuxer, event_data) {
const type_flag = event_data[0];
const media_data = event_data.subarray(1);
// console.log(`[feed_data] type=${type_flag}, len=${media_data.length}`);
jmuxer.feed(type_flag ? {audio: media_data} : {video: media_data});
}
function forward_latest_frame(video) {
if (video && video.buffered && video.buffered.end(0)) {
let latest = video.buffered.end(0);
console.log(`[forward_latest_frame] latest=${latest}, video.buffered.length=${video.buffered.length}`);
if (latest - video.currentTime > 0.2) {
video.currentTime = latest;
}
}
}
</script>
</html>