Safari Video Blob

by dustinkerstein

CSS

video {
  margin: 0;
  width: 100%;
  height: 100%;
}

JavaScript

// Below are two examples (with 4 variations total) that show degraded playback in Safari (tested on 2019 Macbook Pro and iPad Pro 1st Gen). Both examples, across all 4 variations, playback with no issues in Firefox and Chrome.
// The issue appears to be related to the network requests being made in an attempt to buffer. 
// Note that with the Fetch() variations it may take a little while to download the videos

// Example #1 - 4k60fps with 100% I-Frames (and only 243 frames total)
// Try setting src directly and not using fetch() - Note they behave the same way (which is different from Example #2)
// This broken playback can even be replicated by directly going to https://files.panomoments.com/uhd60fps.mp4 in the browser
var src = "https://s3.amazonaws.com/files.panomoments.com/uhd60fps.mp4";
var video = document.createElement("video");
document.body.appendChild(video);
video.controls = true;
video.preload = 'none';
video.autoplay = true;
video.muted = true;
video.loop = true;
//video.src = src;  // Only use this when Fetch() is disabled.
fetch(src).then(function(response) {
  response.blob().then(function(myBlob) {
    video.src = window.URL.createObjectURL(myBlob);
  });
});


// Example #2 - 4k60fps with normal I-Frame / GOP encoding. Source - http://bbb3d.renderfarming.net/download.html
// Note that in this example, playback is better than the example above with 100% I-Frames. Only when using Blob as src does it slow down. When using Blob as src, each buffering requests' Resource Size is near the full size of the file. When not using Blob as src, each request is much smaller.
/* var src = "https://s3.amazonaws.com/files.panomoments.com/bbb_sunflower_2160p_60fps_normal.mp4";
var video = document.createElement("video");
document.body.appendChild(video);
video.controls = true;
video.preload = 'none';
video.autoplay = true;
video.muted = true;
video.loop = true;
//video.src = src; // Only use this when Fetch() is disabled.
fetch(src).then(function(response) {
 ...