14
votes

i have this weird behavior on html5 video tag. I have 4 videos, that i want to play at the same time. So i create my own control bar to play/pause, so when play button is clicked, all 4 videos is played, same as pause button.

On safari, it has weird problem, the video didn't play at the same time, 1 or 2 videos have delay when i click play, so not all videos playing at the same time.

On Chrome and Firefox it's working allright, what's wrong with safari?

I'm using javascript .play() function to play all videos.

I also make sure the video is loaded before playing it. Something like,

<video id="example_video_1" class="video-js vjs-default-skin" preload="auto">
    <source src="asset/video/al_vertrag_kranken_v1_part1.ogv" type='video/ogg' />
    <source src="asset/video/al_vertrag_kranken_v1_part1.mp4" type='video/mp4' />
    <source src="asset/video/al_vertrag_kranken_v1_part1.webm" type='video/webm' />
</video>

video_1 = document.getElementById('example_video_1');

if (video_1.readyState == 4 && video_2.readyState == 4 && video_3.readyState == 4 && video_4.readyState == 4) {
    video_1.play();
    video_2.play();
    video_3.play();
}

there's 3 more video tag like that, that 1 is only example.

4
Probably because different videos have different pre-loading timesslash197
i already use .readyState function before playing the video. But still not working. i will edit my questionmorgan9999
How is your setup-code for the video elements?user1693593
edited my question again, please take a look, thank you :)morgan9999
Are all videos delayed the same time? like: Video 1 <--> Video 2 ( 2sec ), Video 2 <--> Video 3 ( 2sec ) etc..Jim

4 Answers

2
votes

I Noticed you are using Videojs library (your video has the class "video-> js"

Please, check this fiddle i´ve prepared for you to test this with Videojs

I think is what you need ;)

As you can see, the problem with safari is always happening. In chrome or others it´s working perfectly. It seems to be produced by a delay it has when starting playback of videos. The same happens when playback starts for audio.

maybe in that stack you´ll find your solution. It seems that the audio solution is to generate a swf (FLASH) object and to play videos with it (don´t know about it but i´ll try to prepare another edit to the answer with an example)

EDIT

I´ve found this js library https://github.com/videojs/video-js-swf I´ll try with it to solve!

Hope it helps to you.

$(window).ready(function() {

  alert("FIRST LOADING VIDEOS AND WAITING");


  var vid = document.getElementById("example_video_1");
  vid.oncanplay = function() {
    startplay(1);
  };
  var vid2 = document.getElementById("example_video_2");
  vid2.oncanplay = function() {
    startplay(1);
  };
  var vid3 = document.getElementById("example_video_3");
  vid3.oncanplay = function() {
    startplay(1);

  };
  var vid4 = document.getElementById("example_video_4");
  vid4.oncanplay = function() {
    startplay(1);
  };

});


var loaded = 0;

function startplay(num) {
  // alert(num);
  loaded += 1;

  if (loaded == 4) {

    document.getElementById("example_video_1").play();
    document.getElementById("example_video_2").play();
    document.getElementById("example_video_3").play();
    document.getElementById("example_video_4").play();

  }
}
<script src="http://vjs.zencdn.net/4.12/video.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<video id="example_video_1" class="video-js vjs-default-skin" preload="auto" width="640" height="264">
  <source src="http://www.w3schools.com/html/mov_bbb.mp4" type='video/mp4' />
</video>
<video id="example_video_2" class="video-js vjs-default-skin" preload="auto" width="640" height="264">
  <source src="http://www.w3schools.com/html/mov_bbb.mp4" type='video/mp4' />
</video>
<video id="example_video_3" class="video-js vjs-default-skin" preload="auto" width="640" height="264">
  <source src="http://www.w3schools.com/html/mov_bbb.mp4" type='video/mp4' />
</video>
<video id="example_video_4" class="video-js vjs-default-skin" preload="auto" width="640" height="264">
  <source src="http://www.w3schools.com/html/mov_bbb.mp4" type='video/mp4' />
</video>
2
votes

As per Safari HTML Audio Video Guide

Syncing Multiple Media Elements Together Until the advent of media controllers, ensuring that two or more videos played at precisely the same time was a challenging endeavor.

Media controllers let you group any number of audio and/or video elements so that they can be managed by a universal set of controls, and also so that they can be kept in perfect sync, even if a network hiccup occurs.

To create a media controller, simply add the mediagroup attribute to all of the elements you wish to sync together. The value you choose to assign to mediagroup is up to you—as long as the value is the same for each slaved element, a media controller will be created implicitly.

<video src="video.m4v" width="960" height="600"
mediagroup="masterController"></video>

Most of the same functions, attributes, and events available to audio and video elements are also available to media controllers. Instead of calling play() or pause() directly on the video itself, you call them on the media controller.

Controlling Media with JavaScript Syncing Multiple Media Elements Together 2012-12-13 | Copyright © 2012 Apple Inc. All Rights Reserved.

var myVideo = document.querySelector('video');
var mediaController = myVideo.controller;
mediaController.play();

Note: Two attributes that aren’t supported by media controllers are loop and autoplay.

Accessing the controller object on any of the slaved media elements will return a controller of the grouped elements. You can also create a media controller entirely in JavaScript without needing to modify the attributes of your HTML:

var myVideos = document.querySelectorAll('video');
var mediaController = new MediaController();
myVideos[0].controller = mediaController;
myVideos[1].controller = mediaController;
mediaController.play();

If one video stalls or stutters, the other videos will automatically pause to wait for the lagging video to catch up. When the video buffers and is ready to play, the remaining videos will resume in sync.

I hope this helps...

And you can find this doc here

1
votes

Try to monitor canplay event on all 4 elements. Something like

// Event trigger counter
var i = 0;
$('video').on('canplay', function(){
    i += 1;
    // Start playback when everything is ready
    if (i === 4) {
        $('video').each(function(){
            this.play();
        });
    }
});
0
votes

It looks like playing multiple video simultaneously is not currently supported on Safari...

From Safari HTML5 Audio and video guide :

https://developer.apple.com/library/safari/documentation/AudioVideo/Conceptual/Using_HTML5_Audio_Video/Device-SpecificConsiderations/Device-SpecificConsiderations.html#//apple_ref/doc/uid/TP40009523-CH5-SW10

Multiple Simultaneous Audio or Video Streams

Currently, all devices running iOS are limited to playback of a single audio or video stream at any time. Playing more than one video—side by side, partly overlapping, or completely overlaid—is not currently supported on iOS devices. Playing multiple simultaneous audio streams is also not supported. You can change the audio or video source dynamically, however. See Replacing a Media Source Sequentially for details.