Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Syncing HTML5 <video> with <audio> playback

I am having track from one source, mute, and I'd like to play background music over it using element. The tracks contain some time critical elements.

What would be the options to sync these two different media players in HTML5 / Javascript? would give the master clock as it audio playback is very time sensitive - loosing video frames now and then is not critical.

like image 203
Mikko Ohtamaa Avatar asked Jun 22 '11 01:06

Mikko Ohtamaa


3 Answers

Mikko Ohtamaa provided a solution in a comment, which I actually think is the best option here - it doesn't require a framework, and it doesn't require you to edit your video files.

Essentially, just grab the current time from the video element when it is "unmuted", and apply that time to the audio element. Some code might look like this:

function unmute() {   var vid = document.getElementById("video");   var aud = document.getElementById("audio");    aud.currentTime = vid.currentTime;   aud.play();  } 
like image 102
jwegner Avatar answered Oct 06 '22 22:10

jwegner


Here is a simple solution using Popcorn.js inspired by this article.

$(function(){  var medias = {      audio: Popcorn("#narration"),      video: Popcorn("#video")    },    loadCount = 0,    events = "play pause timeupdate seeking volumechange".split(/\s+/g);       // iterate both media sources  Popcorn.forEach(medias, function(media, type) {      // when each is ready...     media.on("canplayall", function() {        // trigger a custom "sync" event      this.emit("sync");        // Listen for the custom sync event...        }).on("sync", function() {        // Once both items are loaded, sync events      if (++loadCount == 2) {        // Uncomment this line to silence the video        //medias.video.mute();          // Iterate all events and trigger them on the video         // whenever they occur on the audio        events.forEach(function(event) {            medias.video.on(event, function() {              // Avoid overkill events, trigger timeupdate manually            if (event === "timeupdate") {                if (!this.media.paused) {                return;              }              medias.audio.emit("timeupdate");                return;            }              if (event === "seeking") {                medias.audio.currentTime(this.currentTime());            }                        if (event === "volumechange") {            	  if(this.muted()) {           		  medias.audio.mute();           	  } else {          		  medias.audio.unmute();           	  }           	            	  medias.audio.volume(this.volume());            }              if (event === "play" || event === "pause") {              medias.audio[event]();            }          });        });      }    });  });  });
  	<script type="text/javascript" src="http://code.jquery.com/jquery-git.js"></script>    	<script type="text/javascript" src="https://static.bocoup.com/js/popcorn.min.js"></script>         <audio id="narration">  	<source src="https://videos.cdn.mozilla.net/uploads/webmademovies/popcorn101/popcorn101.ogg">  </audio>  <video id="video" controls="controls">    	<source src="https://videos.cdn.mozilla.net/uploads/webmademovies/popcorntest.mp4">  </video>
like image 37
honzzyk Avatar answered Oct 06 '22 21:10

honzzyk


Easy with a very simple trick ;)

<video id="myvideo" controls muted loop>
    <source src="sample_video_no_sound.mp4" type="video/mp4"/>
    <audio id="myaudio">
        <source src="sound.mp3" type="audio/mpeg"/>
    </audio>
</video>

<script>
    var myvideo = document.getElementById("myvideo");
    var myaudio = document.getElementById("myaudio");

    var change_time_state = true;

    myvideo.onplay = function(){
        myaudio.play();
        if(change_time_state){
            myaudio.currentTime = myvideo.currentTime;
            change_time_state = false;
        }
    }

    myvideo.onpause = function(){
        myaudio.pause();
        change_time_state = true;
    }
</script>
like image 31
Max Avatar answered Oct 06 '22 22:10

Max