Демонстрация, представленная на html5demos, работает, но она может легко выйти из синхронизации.
Вот статья, в которой предлагается решение, использующее requestAnimationFrame (информация о нем: Leaner, Meaner, FasterАнимации с requestAnimationFrame , Анимация с помощью javascript: от setInterval до requestAnimationFrame ) и это намного лучше: HTML5 Video: синхронизация воспроизведения двух видео .
Обратите внимание, чтопредоставленная там демонстрация (размещенная на jsfiddle) имеет неверную ссылку на источник js.Я обновил его на этой новой странице:
http://jsfiddle.net/aqUNf/1/
Помните о поддержке браузера, эта функция поддерживается Firefox, Chrome, а также из Safari 6 и IE 10 (см. таблица для получения более подробной информации).В противном случае он возвращается к setInterval, ведьма не обеспечивает такое же преимущество в производительности и экономии батареи.
(Кстати, он использует Popcorn.js , что является действительно хорошим проектомMozilla)
А вот код (прямо взят из демоверсии):
var videos = {
a: Popcorn("#a"),
b: Popcorn("#b"),
},
scrub = $("#scrub"),
loadCount = 0,
events = "play pause timeupdate seeking".split(/\s+/g);
// iterate both media sources
Popcorn.forEach( videos, function( media, type ) {
// when each is ready...
media.listen( "canplayall", function() {
// trigger a custom "sync" event
this.trigger("sync");
// set the max value of the "scrubber"
scrub.attr("max", this.duration() );
// Listen for the custom sync event...
}).listen( "sync", function() {
// Once both items are loaded, sync events
if ( ++loadCount == 2 ) {
// Iterate all events and trigger them on the video B
// whenever they occur on the video A
events.forEach(function( event ) {
videos.a.listen( event, function() {
// Avoid overkill events, trigger timeupdate manually
if ( event === "timeupdate" ) {
if ( !this.media.paused ) {
return;
}
videos.b.trigger( "timeupdate" );
// update scrubber
scrub.val( this.currentTime() );
return;
}
if ( event === "seeking" ) {
videos.b.currentTime( this.currentTime() );
}
if ( event === "play" || event === "pause" ) {
videos.b[ event ]();
}
});
});
}
});
});
scrub.bind("change", function() {
var val = this.value;
videos.a.currentTime( val );
videos.b.currentTime( val );
});
// With requestAnimationFrame, we can ensure that as
// frequently as the browser would allow,
// the video is resync'ed.
function sync() {
videos.b.currentTime(
videos.a.currentTime()
);
requestAnimFrame( sync );
}
sync();