動画をループ再生したい。何らかの理由で、終了したイベントでビデオの送信元を変更したくありません。そこで、ループ内の各ビデオのビデオ要素を作成しました。また、配列にビデオsrcと再生時間があります。
これが私のアイデアです。現在再生中のビデオタグのみが表示されます。その他は非表示になります。終了イベントを使用する代わりに、setTimeout関数を使用したいと思います。ビデオの長さは遅延パラメータになります。
しかし、それらはすべて一緒に遊びます。順番にプレイさせることができませんでした。
これが私がこれまでに行ったことです:
videoArray = [
{"video":video1.mp4, "duration": 5},
{"video":video2.mp4, "duration": 7},
{"video":video3.mp4, "duration": 9},
{"video":video4.mp4, "duration": 10},
]
for (var j = 0; j < videoArray.length; j++){
var video = document.createElement("video");
video.src=videoArray[j];
video.id="video-"+j;
video.preload = "metadata";
video.type="video/mp4";
video.autoplay = true;
video.style.display="none";
document.body.appendChild(video);
}
for (var count = 0; count < videoArray.length; count++) {
(function(num){
setTimeout(function() {
videoArray[num].video.style.display="block";
videoArray[num].video.play();
}, 1000 * videoArray[num].duration);
videoArray[num].video.style.display="none";
})(count);
}
あなたが何か奇妙なことを達成しようとしていること、そしてあなたのコード例がコンパイルされないという事実は別として。私がそれを見ると、あなたはそれを手に入れました。欠けているのはpause()
と_display = "none"
_だけです。最小限の編集で、必要なものが手に入ります。
_const videoArray = [
{"video":"video1.mp4", "duration": 5}, // of cause you need ""
{"video":"video2.mp4", "duration": 7},
{"video":"video3.mp4", "duration": 9},
{"video":"video4.mp4", "duration": 10},
]
for (let j = 0; j < videoArray.length; j++){
const video = document.createElement("video");
// you need to save DOM nodes somewhere to use them in the second loop
videoArray[j].video_el = video
video.src=videoArray[j].video; // `.video` is added
video.id="video-"+j;
video.preload = "metadata";
video.type="video/mp4";
video.autoplay = true;
video.style.display="none";
document.body.appendChild(video);
}
for (var count = 0; count < videoArray.length; count++) {
(function(num){
setTimeout(function() {
// add this to hide previous video node and stop video from playing
if( num ) {
videoArray[num-1].video_el.style.display="none";
videoArray[num-1].video_el.pause()
}
// videoArray[num].video - is a string, not a DOM node
// so, you need to change this:
// videoArray[num].video.style.display="block";
// for this:
videoArray[num].video_el.style.display="block";
// no need. `autoplay` is set to `true` in the first loop
// videoArray[num].video_el.play();
}, 1000 * videoArray[num].duration);
// no need. already done in the first loop
// videoArray[num].video_el.style.display="none";
})(count);
}
_
しかし多くの欠陥があります:
setTimeout
はネットワークの遅延やその他の時間関連の問題を考慮しないため、おそらくビデオシーケンスがシームレスに再生されません。duration
の値が正確であるとは思えないため、pause()
を使用する必要があります。play/pause
_を使用することはそれほど単純ではありません。ユーザーがページを開いてそれ以上何もしない場合は、次のようになります。
キャッチされていない(約束どおり)DOMException:play()は、ユーザーが最初にドキュメントを操作しなかったために失敗しました。
chromeで。そして
自動再生は、ユーザーによって承認された場合、サイトがユーザーによってアクティブ化された場合、またはメディアがミュートされている場合にのみ許可されます。
NotAllowedError:おそらくユーザーが権限を拒否したため、現在のコンテキストではユーザーエージェントまたはプラットフォームによって再生メソッドが許可されていません。
firefoxで。
ですから、結局、ended
イベントとmuted
属性(最後の問題を軽減するため)を使用する方が良いでしょう。
_for (let j = 0; j < videoArray.length; j++){
const video = document.createElement("video")
videoArray[j].video_el = video
video.src = videoArray[j].video
video.id = "video-"+j
video.preload = "metadata"
video.type = "video/mp4"
video.autoplay = true
// show the first video right away
if( j !== 0 ) video.style.display = "none"
// set muted attribute
video.muted = "muted"
// play next video after the previous had ended
video.addEventListener('ended', (num => function() {
this.style.display = "none";
if( num !== videoArray.length-1 ) {
videoArray[num+1].video_el.style.display="block";
// only needed if `muted` is not set
videoArray[num+1].video_el.play();
}
})(j), false);
document.body.appendChild(video);
}
_
muted
属性がオプションでない場合は、body
にいくつかのイベントリスナーを追加して、ユーザーがページとの対話を開始するとすぐに最初の動画でplay()
を呼び出すことができます。また、autoplay
の詳細については、こちらをご覧ください: https://developer.mozilla.org/en-US/docs/Web/Media/Autoplay_guide