This commit is contained in:
Brooke Vibber 2023-04-05 12:05:14 -07:00
commit a3e7cd59c1
3 changed files with 157 additions and 63 deletions

View file

@ -17,64 +17,79 @@
<h3>With fallbacks</h3>
<p>HLS with VP9 (.mp4)/MJPEG (.mov) video tracks and Opus/MP3 audio tracks. Custom MSE wrapper enabled to provide HLS-over-MSE for Mac Safari/Chrome/Firefox.</p>
<p>HLS with VP9 (.mp4)/MJPEG (.mov) video tracks and Opus/MP3 audio tracks. Video.js enabled to provide HLS-over-MSE for Chrome/Firefox/desktop Safari.</p>
<div>
<video controls width=640 height=360>
<source type=application/vnd.apple.mpegurl src=fmp4.vp9-mjpeg.mov.m3u8>
</video>
</div>
<p>Current behavior:</p>
<p>Browsers that play the VP9 track will get sharp video, those that play the MJPEG track will get blurry video. Audio should sound the same either way.</p>
<ul>
<li>MSE-based streaming with VHS
<ul>
<li>Firefox seems to work with VP9 & Opus tracks via video.js</li>
<li>Chrome works (needed to fix an output setting)</li>
<li>Safari uses the MP3 audio tracks and VHS gets confused because it tries to parse them as MP4 (not Safari's fault)</li>
</ul>
</li>
<li>Apple HLS player
<ul>
<li>macOS 13's Safari 16 plays MJPEG on most of my test machines, though macOS 12 ~2015 systems with Intel graphics require lying about the type.</li>
<li>iOS 16 plays VP9 if supported, or MJPEG if no hardware codec</li>
<li>Those last two will also play h.263 or MPEG-4 visual <a href="fmp4-lies.html">IF labeled as if h.264 in the playlist</a>; MJPEG can be properly labeled as "jpeg". I haven't found a supported labeling that is correct yet.</li>
<li><i>no access to iOS 13-15</i></li>
<li>iOS 13 doesn't seem to like mjpeg in .mp4, but .mov is fine</li>
<li>iOS 12 doesn't seem to like any version on an old iPad Air, except with h264 video</li>
<li><i>no access to iOS 11</i></li>
<li>iOS 10 on iPhone 5C plays h.263, or mpeg-4 visual IF labeled as false avc1.blah. It will also play mjpeg if so mislabeled, but only in .mov not in .mp4 as above.</li>
<li>iOS 9 doesn't understand the required version of HLS playlist format, and fails.</li>
</ul>
</li>
</ul>
<!--<script src="node_modules/video.js/dist/video.js"></script>-->
<script src="video.js/dist/alt/video.core.js"></script>
<script src="http-streaming/dist/videojs-http-streaming.js"></script>
<script type="text/javascript">
if (typeof MediaSource !== 'undefined') {
async function process(video) {
let vp9 = 'video/mp4; codecs="vp09.00.41.08"';
let opus = 'audio/mp4; codecs="opus"';
let mp3 = 'audio/mpeg';
// Temporary hack, just load the full tracks
let videoTracks = [
{ type: vp9, src: 'fmp4.480p.vp9.mp4' },
];
let audioTracks = [
{ type: opus, src: 'fmp4.audio.opus.mp4' },
{ type: mp3, src: 'fmp4.audio.mpeg.mp3' },
];
let videoTrack = videoTracks.filter(({type}) => MediaSource.isTypeSupported(type))[0];
let audioTrack = audioTracks.filter(({type}) => MediaSource.isTypeSupported(type))[0];
if (!videoTrack || !audioTrack) {
throw new Error('error no tracks');
let playerConfig = {
responsive: true,
controlBar: {
volumePanel: {
vertical: true,
inline: false
}
console.log(videoTrack);
console.log(audioTrack);
let videoBytes = await (await fetch(videoTrack.src)).arrayBuffer();
// hackhack
videoBytes = videoBytes.slice(0, 878148 + 779);
let audioBytes = await (await fetch(audioTrack.src)).arrayBuffer();
let source = new MediaSource();
source.addEventListener("sourceopen", (event) => {
source.duration = 150; // hack
let videoBuffer = source.addSourceBuffer(videoTrack.type);
let audioBuffer = source.addSourceBuffer(audioTrack.type);
videoBuffer.appendBuffer(videoBytes);
audioBuffer.appendBuffer(audioBytes);
console.log('appended.');
});
video.addEventListener('error', (event) => {
console.log('video error?', video.error);
});
video.src = URL.createObjectURL(source);
console.log('opening...');
}
},
html5: {
vhs: {
// Currently the MP3 audio track fails in Safari
// and it doesn't grok the Opus
// Either fix MP3 handling in vhs or use AAC.
overrideNative: true
}
},
};
videojs.log.level('debug');
console.log(typeof MediaSource)
if (typeof MediaSource !== 'undefined') {
//let vp9 = MediaSource.isTypeSupported('video/mp4; codecs="vp09.00.41.08"');
//let opus = MediaSource.isTypeSupported('video/mp4; codecs="opus"');
//let mp3 = MediaSource.isTypeSupported('audio/mpeg');
//if (vp9 && (opus || mp3)) {
for (let video of document.querySelectorAll('video')) {
process(video);
video.classList.add('video-js');
video.classList.add('vjs-default-skin');
videojs(video, playerConfig);
}
// }
}
</script>
</body>
</html>
</html>