javascript 将 HTML5 <video> 与 <audio> 播放同步

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6433900/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-25 20:40:01  来源:igfitidea点击:

Syncing HTML5 <video> with <audio> playback

javascripthtmlvideoaudio

提问by Mikko Ohtamaa

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.

我有一个来源的音轨,静音,我想使用 element.js 在它上面播放背景音乐。曲目包含一些时间关键元素。

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.

在 HTML5 / Javascript 中同步这两个不同的媒体播放器的选项是什么?会给主时钟,因为它的音频播放对时间非常敏感 - 偶尔丢失视频帧并不重要。

采纳答案by jwegner

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.

Mikko Ohtamaa 在评论中提供了一个解决方案,我实际上认为这是这里的最佳选择 - 它不需要框架,也不需要您编辑视频文件。

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();

}

回答by honzzyk

Hereis a simple solution using Popcorn.js inspired by thisarticle.

下面是使用Popcorn.js灵感来自一个简单的解决这个文章。

$(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>

回答by Max

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>

回答by themihai

There is no reliable solution. The only html5 feature that supported sync of multiple streams is mediaGroup. It was unshipped by Chrome and deprecated by w3c.

没有可靠的解决方案。支持多流同步的唯一 html5 功能是 mediaGroup。它被 Chrome 取消并被 w3c 弃用。

回答by bhagyas

The same effect can be achieved by including the music in your video file itself. The html5 video player controls will have the ability to mute the sound.

通过在视频文件本身中包含音乐,可以实现相同的效果。html5 视频播放器控件将能够静音。

回答by bhagyas

Try VideoJS. At the time when the video playback starts when the page is loaded and ready, you are able to trigger a function which would start playing the music that is contained in the page separately.

试试 VideoJS。在页面加载并准备好视频播放开始时,您可以触发一个功能,该功能将开始播放单独包含在页面中的音乐。

http://videojs.com/

http://videojs.com/