Spaces:
Running
Running
Upload vtv_test.html
Browse files- vtv_test.html +78 -0
vtv_test.html
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<!DOCTYPE html>
|
| 2 |
+
<html>
|
| 3 |
+
<head><meta charset="utf-8"><title>VTV Stream Test</title></head>
|
| 4 |
+
<body style="background:#000;color:#fff;font-family:monospace;padding:20px">
|
| 5 |
+
<h2>VTV Stream Test</h2>
|
| 6 |
+
<div id="log" style="white-space:pre-wrap;font-size:12px;max-height:400px;overflow-y:auto;background:#111;padding:10px;margin:10px 0"></div>
|
| 7 |
+
<video id="v" controls autoplay muted style="width:100%;max-width:640px;display:block;background:#000"></video>
|
| 8 |
+
|
| 9 |
+
<script src="https://cdn.jsdelivr.net/npm/hls.js@1.5.13/dist/hls.min.js"></script>
|
| 10 |
+
<script>
|
| 11 |
+
const log = msg => { const el = document.getElementById('log'); el.textContent += new Date().toISOString().substr(11,12) + ' ' + msg + '\n'; el.scrollTop = el.scrollHeight; console.log(msg); };
|
| 12 |
+
const video = document.getElementById('v');
|
| 13 |
+
|
| 14 |
+
const streamUrl = 'https://vtvgolive-failover.vtvdigital.vn/vtvgo/vtv1-manifest.m3u8';
|
| 15 |
+
const proxyUrl = 'https://bep40-vnews.hf.space/api/proxy/m3u8/vtv?url=' + encodeURIComponent(streamUrl);
|
| 16 |
+
|
| 17 |
+
log('HLS.js version: ' + (Hls.version || 'unknown'));
|
| 18 |
+
log('Hls.isSupported: ' + Hls.isSupported());
|
| 19 |
+
log('video.canPlayType m3u8: ' + video.canPlayType('application/vnd.apple.mpegurl'));
|
| 20 |
+
|
| 21 |
+
function tryLoad(label, url) {
|
| 22 |
+
log('\n--- Trying ' + label + ' ---');
|
| 23 |
+
log('URL: ' + url);
|
| 24 |
+
|
| 25 |
+
if (!Hls.isSupported()) {
|
| 26 |
+
video.src = url;
|
| 27 |
+
video.addEventListener('loadedmetadata', () => { log('Native: metadata loaded'); video.play(); });
|
| 28 |
+
return;
|
| 29 |
+
}
|
| 30 |
+
|
| 31 |
+
const hls = new Hls({
|
| 32 |
+
enableWorker: false,
|
| 33 |
+
lowLatencyMode: true,
|
| 34 |
+
startLevel: 0,
|
| 35 |
+
capLevelToPlayerSize: true,
|
| 36 |
+
maxBufferLength: 8,
|
| 37 |
+
debug: false,
|
| 38 |
+
});
|
| 39 |
+
|
| 40 |
+
hls.on(Hls.Events.MEDIA_ATTACHING, () => log('HLS: MEDIA_ATTACHING'));
|
| 41 |
+
hls.on(Hls.Events.MEDIA_ATTACHED, () => log('HLS: MEDIA_ATTACHED'));
|
| 42 |
+
hls.on(Hls.Events.MANIFEST_LOADING, () => log('HLS: MANIFEST_LOADING'));
|
| 43 |
+
hls.on(Hls.Events.MANIFEST_LOADED, () => log('HLS: MANIFEST_LOADED'));
|
| 44 |
+
hls.on(Hls.Events.MANIFEST_PARSED, (ev,d) => {
|
| 45 |
+
log('HLS: MANIFEST_PARSED levels=' + d.levels.length + ' video=' + !!d.video + ' audio=' + !!d.audio);
|
| 46 |
+
if (d.levels[0]) log('HLS: First level: ' + d.levels[0].width + 'x' + d.levels[0].height + ' @' + d.levels[0].bitrate + 'bps');
|
| 47 |
+
video.play().then(() => log('HLS: PLAY OK')).catch(e => log('HLS: PLAY ERROR: ' + e));
|
| 48 |
+
});
|
| 49 |
+
hls.on(Hls.Events.LEVEL_LOADED, (ev,d) => log('HLS: LEVEL_LOADED fragments=' + d.details.fragments.length));
|
| 50 |
+
hls.on(Hls.Events.FRAG_LOADING, (ev,d) => log('HLS: FRAG_LOADING ' + (d.frag && d.frag.url && d.frag.url.substring(0,60))));
|
| 51 |
+
hls.on(Hls.Events.FRAG_LOADED, (ev,d) => log('HLS: FRAG_LOADED size=' + (d.frag && d.frag.data && d.frag.data.length)));
|
| 52 |
+
hls.on(Hls.Events.FRAG_BUFFERED, (ev,d) => log('HLS: FRAG_BUFFERED ' + (d.frag && d.frag.url && d.frag.url.substring(0,60))));
|
| 53 |
+
hls.on(Hls.Events.BUFFER_CREATED, () => log('HLS: BUFFER_CREATED'));
|
| 54 |
+
hls.on(Hls.Events.BUFFER_APPENDING, () => log('HLS: BUFFER_APPENDING'));
|
| 55 |
+
hls.on(Hls.Events.BUFFER_APPENDED, () => log('HLS: BUFFER_APPENDED'));
|
| 56 |
+
hls.on(Hls.Events.ERROR, (ev,data) => {
|
| 57 |
+
log('HLS: ERROR type=' + data.type + ' details=' + data.details + ' fatal=' + data.fatal + ' reason=' + data.reason);
|
| 58 |
+
if (data.url) log(' URL: ' + data.url.substring(0,100));
|
| 59 |
+
if (data.response) log(' Resp: ' + JSON.stringify(data.response).substring(0,100));
|
| 60 |
+
if (data.fatal) {
|
| 61 |
+
hls.destroy();
|
| 62 |
+
if (label === 'DIRECT') {
|
| 63 |
+
log('\nDIRECT failed, trying PROXY...');
|
| 64 |
+
tryLoad('PROXY', proxyUrl);
|
| 65 |
+
} else {
|
| 66 |
+
log('\nBOTH FAILED');
|
| 67 |
+
}
|
| 68 |
+
}
|
| 69 |
+
});
|
| 70 |
+
|
| 71 |
+
hls.loadSource(url);
|
| 72 |
+
hls.attachMedia(video);
|
| 73 |
+
}
|
| 74 |
+
|
| 75 |
+
tryLoad('DIRECT', streamUrl);
|
| 76 |
+
</script>
|
| 77 |
+
</body>
|
| 78 |
+
</html>
|