15

I'm creating some custom video controls for an html5 element. I've bound a click event handler to a play/pause button which calls .play() on the corresponding video.

From my research, Safari will block calls to .play() unless you are in a click handler, however it is blocking my calls to .play() despite the fact that I am triggering it from within a click handler, like so:

$('.video-container .play-pause').click(function(event){
    var $video = $(event.currentTarget).parent().find('video');
    if($video[0].paused)
      $video[0].play();
    else
      $video[0].pause();
});

And the error:

Unhandled Promise Rejection: NotSupportedError (DOM Exception 9): The operation is not supported.

which is originating from $video[0].play();.

Safari Version 11.0.1 (13604.3.5)

OSX High Sierra 10.13.1 (17B48)

Any ideas?

Max Mumford
  • 2,482
  • 5
  • 28
  • 40
  • Have you tried to add the event handler as an attribute in the HTML instead of via jQuery? For example, ` – Ulysses Alves Nov 15 '17 at 02:01
  • Thanks for the suggestion - just tried it and it's resulting in the same error message. The code I used was: `window.main['play_pause_click'] = function(control){ console.log("Playing..."); $(control).parent().find('video')[0].play(); };` and onclick="window.main['play_pause_click'](this)" – Max Mumford Nov 15 '17 at 09:50

4 Answers4

6

It's worth noting that this error occurs whenever you call .play() on a video that Safari has failed to load.

Something else interesting is that Safari requires the web server to support the byte-range requests to correctly load video files. See note here: https://stackoverflow.com/a/36299252

I recently had an issue with serving files from the php command line process instead of a dedicated web server like Apache or nginx and couldn't work out why videos were playing on the live site, but not in my development environment.

A quick way to determine this is to load the video directly from the address bar. If it fails to load, your server likely doesn't support byte-range requests.

lachie_h
  • 559
  • 1
  • 6
  • 15
5

Eugh. The solution was to use an absolute path for the video source, not a relative one.

This is wrong: <video src="assets/vid.mp4"></video>

This is correct: <video src="http://example.com/assets/vid.mp4"></video>

Max Mumford
  • 2,482
  • 5
  • 28
  • 40
  • 1
    The two examples you have are different paths unless you are on the homepage.`src="assets/vid.mp4"` is relative to the current document path which means if you are on `http://example.com/page/` the source is going to attempt to load from `page/assets/vid.mp4`. The correct `src` should be `/assets/vid.mp4` as the preceding slash is going to be relative to the server root. – lachie_h Jan 17 '18 at 19:52
  • 1
    Thanks for the suggestion, but the video was loading and controls working properly on chrome and firefox, and the relative link was indeed on the home page. – Max Mumford Jan 18 '18 at 08:36
0

Figured out, that Safari on Mac needs server sending content-type of video/mp4

When I tried to use direct link from document manager, which gave content-type application/mp4, this didn't work (only) in Safari.

Rauli Rajande
  • 2,010
  • 1
  • 20
  • 24
0

I had same problem. The video didn't play in Safari. But apparently, when I put different mp4 file in same place, the video played successfully. I used ffmpeg tool with different settings to generate the video.

This question didn't help me but gave me the idea: FFMPEG video conversion to MP4 works everywhere except in iOS Safari/Chrome.

In short, make sure you tried some video file other than you are trying now.

pttsky
  • 737
  • 5
  • 15