<!DOCTYPE html> <html> <head> <meta charset=utf-8> <title>HLS WebM test</title> <link rel=stylesheet type=text/css href=video-js/video-js.css> </head> <body> <h1>HLS WebM test</h1> <p id=hls>Checking HLS support...</p> <p id=mse>Checking MSE VP9 support...</p> <p id=webm>Checking flat WebM VP8 / Vorbis support...</p> <p id=wasm>Checking WebAssembly support...</p> <h2>Caminandes - Llamigos</h2> <p>HLS with VP9-in-MP4 video with Opus-in-MP4 or MP3 audio. Flat WebM fallback with ogv.js loader.</p> <video id=hls1 controls width=640 height=360> <!--<source type=application/vnd.apple.mpegurl src=llamigos-vp9-opus-aac-mp3.m3u8>--> <source type=application/vnd.apple.mpegurl src=llamigos-vp9-mp3-opus.m3u8> <!--<source type=application/vnd.apple.mpegurl src=llamigos-vp9-mp3ts-opus.m3u8>--> <!--<source type=application/vnd.apple.mpegurl src=llamigos-vp9-mp3-vorbis.m3u8>--> <source type="video/webm; codecs="vp8, vorbis"" src=caminandes-llamigos.webm.flat.webm> <source type="video/quicktime; codecs="jpeg, mp3"" src=polyphon-jpeg-mp3.mov> </video> <p>Desired behavior:</p> <ul> <li>Firefox/Chrome: play via MSE with VP9/Opus (working)</li> <li>Desktop Safari with VP9 support: play via MSE with VP9/AAC or MP3 (currently MP3 fails)</li> <li>iOS Safari with VP9 support: play native HLS with VP9/AAC or MP3 (works)</li> <li>Older iOS and desktop Safari without VP9: play via ogv.js with WebM VP8/Vorbis (WebKit issue with some devices, in progress)</li> <li>Older iOS and desktop Safari without WebAssembly or with JS off: play backup MJPEG :D (HLS will take over but fail without JS)</li> <li>Very old Firefox/Chrome: play native WebM VP8/Vorbis</li> </ul> <!-- <p>HLS with VP9 video and Opus, AAC, and MP3 audio. Flag WebM fallback.</p> <video id=hls1 controls width=640 height=360> <source type=application/vnd.apple.mpegurl src=llamigos-vp9-opus-aac-mp3.m3u8> <source type=video/webm src=caminandes-llamigos.webm.flat.webm> </video> <p>Expected behavior:</p> <ul> <li>Firefox/Chrome: MSE VP9/Opus (AAC for now)</li> <li>Desktop Safari with VP9 support: MSE VP9/MP3 (AAC for now?)</li> <li>iOS Safari with VP9 support: HLS VP9/MP3 (AAC for now?)</li> <li>Older iOS and desktop Safari without VP9: ogv.js VP8/Vorbis</li> <li>Very old Firefox/Chrome: native WebM VP8/Vorbis</li> </ul> --> <!-- <p>HLS with VP9 video and AAC audio. Flag WebM fallback.</p> <video id=hls1 controls width=640 height=360> <source type=application/vnd.apple.mpegurl src=llamigos-vp9-aac.m3u8> <source type=video/webm src=caminandes-llamigos.webm.flat.webm> </video> <p>Expected behavior:</p> <ul> <li>Firefox/Chrome: MSE VP9/Opus (AAC for now)</li> <li>Desktop Safari with VP9 support: MSE VP9/MP3 (AAC for now?)</li> <li>iOS Safari with VP9 support: HLS VP9/MP3 (AAC for now?)</li> <li>Older iOS and desktop Safari without VP9: ogv.js VP8/Vorbis</li> <li>Very old Firefox/Chrome: native WebM VP8/Vorbis</li> </ul> --> <script> if (hls1.canPlayType('application/vnd.apple.mpegurl')) { hls.textContent = 'native HLS playback supported'; hls.style.color = 'green'; } else { hls.textContent = 'no native HLS'; hls.style.color = 'red'; } if (typeof MediaSource == 'function') { let codecs = [ ['VP9-in-WebM', 'video/webm; codecs="vp9"'], ['Opus-in-WebM', 'audio/webm; codecs="opus"'], ['Vorbis-in-WebM', 'audio/webm; codecs="vorbis"'], ['VP9-in-MP4', 'video/mp4; codecs="vp09.00.10.08"'], ['Opus-in-MP4', 'audio/mp4; codecs="opus"'], ['MP3 (mp3)', 'audio/mp3'], ['MP3 (mpeg)', 'audio/mpeg'], ]; let yes = []; let no = []; for (let [name, mime] of codecs) { if (MediaSource.isTypeSupported(mime)) { yes.push(name); } else { no.push(name); } } if (yes.length == codecs.length) { mse.textContent = 'MSE supports ' + yes.join(', '); mse.style.color = 'green'; } else { mse.textContent = 'MSE supports ' + yes.join(', ') + ' but not ' + no.join(', '); mse.style.color = 'orange'; } } else { mse.textContent = 'MSE not supported'; mse.style.color = 'red'; } if (hls1.canPlayType('video/webm; codecs="vp8, vorbis"')) { webm.textContent = 'flat WebM VP8/Vorbis supported'; webm.style.color = 'green'; } else { webm.textContent = 'flat WebM VP8/Vorbis not supported'; webm.style.color = 'red'; } if (typeof WebAssembly == 'object') { wasm.textContent = 'WebAssembly supported'; wasm.style.color = 'green'; } else { wasm.textContent = 'no WebAssembly support'; wasm.style.color = 'red'; } </script> <script src=ogvjs-1.8.4/ogv.js></script> <!-- <script src=video-js/alt/video.core.js></script> <script src=videojs-http-streaming.js></script> --> <!-- <script src="node_modules/video.js/dist/video.js"></script> --> <script src="node_modules/video.js/dist/alt/video.core.js"></script> <script src="http-streaming/dist/videojs-http-streaming.js"></script> <script src=videojs-ogvjs.js></script> <script> var playerConfig = { responsive: true, controlBar: { volumePanel: { vertical: true, inline: false } }, techOrder: [ 'html5' ], html5: {} }; function can(mime) { return (typeof MediaSource == 'function') && MediaSource.isTypeSupported(mime); } var vp9 = can('video/mp4; codecs="vp09.00.10.08"'); var opus = can('audio/mp4; codecs="opus"'); var aac = can('audio/mp4; codecs="mp4a.40.02'); var mp3 = can('audio/mp3'); //var mp3 = can('audio/mp4; codecs="mp4a.40.34"'); var mse = vp9 && (opus || mp3); if (mse) { // enable streaming plugin playerConfig.html5 = { vhs: { overrideNative: true, useDevicePixelRatio: true }, nativeAudioTracks: false, nativeVideoTracks: false }; console.log('will do mse'); } else { console.log('wont do mse'); } var webm = null; var m3u8 = null; for (let source of hls1.querySelectorAll('source')) { if (source.type.startsWith('video/webm')) { webm = source; continue; } if (source.type == 'application/vnd.apple.mpegurl') { m3u8 = source; continue; } } var ogv = webm && !mse && !hls1.canPlayType(webm.type) && (typeof WebAssembly == 'object') && (typeof WebAssembly.Module == 'function'); if (ogv) { console.log('can do ogvjs'); var base = '/misc/hls-test/ogvjs-1.8.4';//new URL('./ogvjs-1.8.4', document.location.pathname) playerConfig.ogvjs = { base: base }; console.log(playerConfig.ogvjs.base); playerConfig.techOrder.push('ogvjs'); } else { console.log('wont do ogvjs'); } videojs.log.level('debug'); hls1.classList.add('video-js'); hls1.classList.add('vjs-default-skin'); var vjs1 = videojs(hls1, playerConfig); vjs1.on('error', function failover() { console.log('got error'); var error = vjs1.error(); if (error && error.code == MediaError.MEDIA_ERR_DECODE) { console.log('saw its a decode error'); // HLS reports this if it can't find a codec it likes console.log(m3u8); if (mse && m3u8) { console.log('going to m3u8: ' + m3u8.getAttribute('src')); vjs1.src([{ src: m3u8.getAttribute('src'), type: m3u8.getAttribute('type') }]); vjs1.reset(); m3u8 = null; } else if (webm) { console.log('going to webm: ' + webm.getAttribute('src')); vjs1.src([{ src: webm.getAttribute('src'), type: webm.getAttribute('type') }]); vjs1.reset(); webm = null; } } vjs1.off('error', failover); }); // this fails on Chrome with a blob issue on the HLS player :D //vjs1.load(); </script> </body> </html>