0

I have a strange problem.

On a website for my client, I'm showing some mp4 files using the HTML5 video element. The videos that are visible on the page while loading do show up on mobile devices without any problems.

When I try to change the source of a video element (after an AJAX request), the video element shows a black screen. The new video source I changed could be exactly the same as one that was already shown on page load, but after updating the src parameter it just won't show..

Already tried checking the mp4 encoding (which is H.264), the content-type in the server response-headers is correct (video/mp4) and the server seems to return "206 Partial Content". Also, gzip encoding for mp4 files is off.

If I check the remote debugger in Safari (inspecting Safari on an iPad), I get the error "An error occurred trying to load the resource". Below you find the response headers:

HTTP/1.1 206 Partial Content
Content-Type: video/mp4
ETag: "23f72-5a4561b99803e"
Last-Modified: Tue, 28 Apr 2020 09:03:40 GMT
Content-Range: bytes 0-147313/147314
Accept-Ranges: bytes
Date: Wed, 29 Apr 2020 05:13:12 GMT
Content-Length: 147314
Keep-Alive: timeout=5, max=84
Connection: Keep-Alive
Server: Apache

Does anyone have an idea what could be causing this issue? Thanks!

Sjors
  • 1,205
  • 1
  • 8
  • 21
  • Also tried using a direct video link from a Vimeo Pro account, but got the same result.. Looks like replacing the video element src-url in mobile is very buggy.. – Sjors Apr 29 '20 at 08:24

1 Answers1

1

The documentation for this can be a bit confusing - it can look like it is not possible to dynamically change the source (https://html.spec.whatwg.org/multipage/embedded-content.html):

Dynamically modifying a source element and its attribute when the element is already inserted in a video or audio element will have no effect. To change what is playing, just use the src attribute on the media element directly, possibly making use of the canPlayType() method to pick from amongst available resources. Generally, manipulating source elements manually after the document has been parsed is an unnecessarily complicated approach.

However, it can be changed and the code snippet below should work reliably cross browser - the video.load() line is key as it actually makes sure the new source is inserted. You can experiment by commenting out this line and seeing the difference:

var video = document.getElementById('video');
var source = document.createElement('source');

source.setAttribute('src', 'http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/ForBiggerBlazes.mp4');

video.appendChild(source);
video.play();

function changeSource() {  
    video.pause();

    source.setAttribute('src', 'http://clips.vorwaerts-gmbh.de/VfE_html5.mp4'); 

    video.load();  //This step is key
    video.play();
}
<h1>Video source change test</h1>
<p>
<button id="sourceButtom" onclick="changeSource()">Click me to change the video source.</button>
<p>
<video id="video" width="320" controls height="240"></video>

The above is based on the excellent answer here: https://stackoverflow.com/a/18454389/334402

Mick
  • 19,483
  • 1
  • 40
  • 91