242 lines
No EOL
10 KiB
HTML
242 lines
No EOL
10 KiB
HTML
<!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> |