HTML 5 Видео: Воспроизведение нескольких «клипов» с помощью JavaScript - PullRequest
0 голосов
/ 17 декабря 2018

У меня проблема с HTML-видео и JavaScript, поэтому я написал простой код для демонстрации.Есть одно видео, которое содержит три «клипа» длиной всего пять секунд (очевидно, в реальном мире они намного длиннее).Один на 25 - 30 секунд, один на 55 - 60 секунд и последний на 85 - 90 секунд.Я хочу, чтобы пользователь мог нажимать соответствующую кнопку для каждого пятисекундного клипа.

Есть две проблемы:

  1. Ошибка Chrome currenttimer (), которая, похоже, непозволяет изменить время начала внешнего видео (видео будет сохранено в BLOB-объекте Azure).Похоже, что есть несколько сообщений об этом, но без исправления.
  2. Когда вы проигрываете первый клип, а затем пытаетесь воспроизвести второй клип, потому что время начала клипа 2 больше времени окончания клипа 1, он не воспроизводится, потому что AddEventListener все еще действует.Есть ли способ отбросить оригинальный EventListener или заменить его новым временем окончания?

Вот код, который используется:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title></title>
</head>
<body>
    <div style="width: 700px; height: 400px; margin: auto; text-align: center;">
        <video id="video1" width="620" controls>
            <source type="video/mp4" src="external video link here" />
            Your browser does not support HTML5 video.
        </video>

        <input type="button" value="Play Clip 1 (25 - 30 seconds" onclick="javascript: showvid(25);" /><br />
        <input type="button" value="Play Clip 2 (55 - 60 seconds" onclick="javascript: showvid(55);" /><br />
        <input type="button" value="Play Clip 3 (85 - 90 seconds" onclick="javascript: showvid(85);" /><br />
    </div>

    <script type="text/javascript">
        function showvid(timer) {
            var myVideo = document.getElementById("video1");
            myVideo.currentTime = timer;
            myVideo.play();

            myVideo.addEventListener("timeupdate", function () {
                if (this.currentTime >= (timer + 5)) {
                    this.pause();
                }
            });
        }
    </script>
</body>
</html>

ОБНОВЛЕНИЕ 1

Я изменил проверку прослушивателя событий, чтобы приостановить видео, только если текущее время находится в пределах секунды после времени окончания.Поэтому, если до следующего клипа больше секунды, слушатель не остановит клип до его запуска.

Все еще изучая проблему Chrome.

1 Ответ

0 голосов
/ 18 декабря 2018

Я не знаю, о какой ошибке Chrome вы говорите, но для более чистого кода вас может заинтересовать #t=start[,end] Media Fragment , который позволит вам установить временной диапазон непосредственно какисточник вашего :

onclick =e=> {
  const data = e.target.dataset;
  if(!data.start) return;
  vid.src = vid.src.split('#')[0] +
    '#t=' + data.start + ',' + data.end;
  // url.vid#t=start,end
  vid.play();
}
<button data-start="5" data-end="10">play [5,10]</button>
<button data-start="35" data-end="40">play [35,40]</button>
<button data-start="00:01:25" data-end="00:01:30">play [00:01:25,00:01:30]</button>
<video id="vid" src="https://upload.wikimedia.org/wikipedia/commons/transcoded/2/22/Volcano_Lava_Sample.webm/Volcano_Lava_Sample.webm.360p.webm" muted></video>

Теперь, если вы действительно хотите идти по своему пути, тогда вам придется немного изменить свой код.

Никогда не добавляйте новый прослушиватель событий из сгенерированного пользователем события.

Добавляйте его один раз и запускайте только семафоры / обновляйте переменные из пользовательских событий.

Поэтому мы сначала добавляем timeupdate событие в нашем , тогда, если никакого события, сгенерированного пользователем, не произошло, мы завершаем работу рано.В противном случае мы проверяем переменную, которая доступна обоим слушателям наших событий (здесь она называется next_stop), если мы должны сделать паузу или нет.

Затем в обработчиках событий кнопок мы обновляем currentTime, запрашиваем его воспроизведение и обновляем next_stop.

ДваСлушатели событий могут взаимодействовать благодаря общей переменной next_stop, но больше нет конфликтов.

let next_stop = Infinity; // a variable shared by both event listeners

// add the event listeners only once
vid.addEventListener('timeupdate', handleTimeupdate, {passive: true});
document.addEventListener('click', handleClick);

function handleTimeupdate(evt) {
  // not set? exit early
  if(!isFinite(next_stop)) return;
  // a single action
  if(this.currentTime > next_stop) {
    this.pause();
    // if you want to disable the range once it's done
    // e.g to allow default controls interactions
//    next_stop = Infinity;
  }
}

function handleClick(evt) {
  const times = parseTime(evt.target);
  if(!times) return;
  // update the video's current time  
  vid.currentTime = times.start;
  // update the shared variable
  next_stop = times.end;
  // start playing if needed
  if(vid.paused) {
    vid.play();
  }
}

function parseTime(target) {
  const data = target.dataset;
  if(!data || !data.start) return null;
  return {start: +data.start, end: +data.end};
}
<button data-start="5" data-end="10">play [5,10]</button>
<button data-start="35" data-end="40">play [35,40]</button>
<button data-start="85" data-end="90">play [00:01:25,00:01:30]</button>
<video id="vid" src="https://upload.wikimedia.org/wikipedia/commons/transcoded/2/22/Volcano_Lava_Sample.webm/Volcano_Lava_Sample.webm.360p.webm" controls></video>
...