[Javascript] Автоматическое воспроизведение видео не работает в браузере Safari и Chrome


Answers

Случается, что Safari и Chrome на рабочем столе не любят манипуляции с DOM вокруг тега видео. Они не будут запускать порядок воспроизведения, если атрибут autoplay установлен, даже если событие canplaythrough было запущено, когда DOM вокруг тега видео изменилась после начальной загрузки страницы. В основном у меня была такая же проблема, пока я не удалил jQuery .wrap () jQuery вокруг тега видео, и после этого он автоматически запускается, как ожидалось.

Question

Я потратил немало времени, пытаясь понять, почему видео встроено, как здесь:

<video height="256" loop="true" autoplay="autoplay" controls="controls" id="vid">
         <source type="video/mp4" src="video_file.mp4"></source>
         <source type="video/ogg" src="video_file.ogg"></source>
</video>

автоматически запускается, как только страница загружается в FireFox, но не может выполнять автозапуск в браузерах на основе Webkit. Это произошло только на некоторых случайных страницах. Пока я не смог найти причину. Я подозреваю, что некоторые закрытые теги или обширные JS созданы редакторами CMS.




Я начал играть все видимые видео, но старые телефоны плохо работали. Поэтому прямо сейчас я воспроизвожу одно видео, которое ближе всего к центру окна, и останавливает остальные. Vanilla JS. Вы можете выбрать, какой алгоритм вы предпочитаете.

//slowLooper(playAllVisibleVideos);
slowLooper(playVideoClosestToCenter);

function isVideoPlaying(elem) {
    if (elem.paused || elem.ended || elem.readyState < 2) {
        return false;
    } else {
        return true;
    }
}
function isScrolledIntoView(el) {
    var elementTop = el.getBoundingClientRect().top;
    var elementBottom = el.getBoundingClientRect().bottom;
    var isVisible = elementTop < window.innerHeight && elementBottom >= 0;
    return isVisible;
}
function playVideoClosestToCenter() {
    var vids = document.querySelectorAll('video');
    var smallestDistance = null;
    var smallestDistanceI = null;
    for (var i = 0; i < vids.length; i++) {
        var el = vids[i];
        var elementTop = el.getBoundingClientRect().top;
        var elementBottom = el.getBoundingClientRect().bottom;
        var elementCenter = (elementBottom + elementTop) / 2.0;
        var windowCenter = window.innerHeight / 2.0;
        var distance = Math.abs(windowCenter - elementCenter);
        if (smallestDistance === null || distance < smallestDistance) {
            smallestDistance = distance;
            smallestDistanceI = i;
        }
    }
    if (smallestDistanceI !== null) {
        vids[smallestDistanceI].play();
        for (var i = 0; i < vids.length; i++) {
            if (i !== smallestDistanceI) {
                vids[i].pause();
            }
        }
    }
}
function playAllVisibleVideos(timestamp) {
    // This fixes autoplay for safari
    var vids = document.querySelectorAll('video');
    for (var i = 0; i < vids.length; i++) {
        if (isVideoPlaying(vids[i]) && !isScrolledIntoView(vids[i])) {
            vids[i].pause();
        }
        if (!isVideoPlaying(vids[i]) && isScrolledIntoView(vids[i])) {
            vids[i].play();
        }
    }
}
function slowLooper(cb) {
    // Throttling requestAnimationFrame to a few fps so we don't waste cpu on this
    // We could have listened to scroll+resize+load events which move elements
    // but that would have been more complicated.
    function repeats() {
        cb();
        setTimeout(function() {
            window.requestAnimationFrame(repeats);
        }, 200);
    }
    repeats();
}



Попробуй это:

    <video height="256" loop autoplay controls id="vid">
     <source type="video/mp4" src="video_file.mp4"></source>
     <source type="video/ogg" src="video_file.ogg"></source>

Так я обычно это делаю. цикл, элементы управления и автовоспроизведение не требуют значения, которое они являются логическими атрибутами.




Ни один из других ответов не работал для меня. Мое обходное решение заключалось в том, чтобы вызвать клик на самом видео; hacky (из-за таймаута, который необходим), но он отлично работает:

function startVideoIfNotStarted () {
    $(".id_of_video_tag").ready(function () {
        window.setTimeout(function(){
            videojs("id_of_video_tag").play()
        }, 1000);
    });
}
$(startVideoIfNotStarted);



Я только что получил ту же самую проблему с моим видео

<video preload="none" autoplay="autoplay" loop="loop">
  <source src="Home_Teaser.mp4" type="video/mp4">
  <source src="Home_Teaser" type="video/webm">
  <source src="Home_Teaser.ogv" type="video/ogg">
</video>

После поиска я нашел решение:

Если я установил атрибуты «preload» в «true», видео начнется нормально