我一直在努力解决这个问题,运气不好。 浏览了所有关于stackoverflow的类似问题,但没有一个解决方案对我有用。
我正在播放一系列视频。我需要将每个视频插入音频元素,以快速获取其持续时间以及确切的时间出现在播放列表中。
我本来是这样的:
// Set time in playlist for each video
for (let index=0; index<this.playlist.length; index++) {
var audio = document.getElementById('audio');
console.log('INDEX: ' + index);
self.playlist[index].timeInPlaylist = [];
self.playlist[index].duration = 0;
audio.setAttribute('src', self.playlist[index].bucketRef);
audio.addEventListener('canplaythrough', function(e){
videoDuration = Math.round(e.currentTarget.duration);
console.log("Duration of video number " + index + ": " +
videoDuration + " seconds");
self.playlist[index].duration = videoDuration;
self.playlist[index].timeInPlaylist[0] = playlistLength;
playlistLength = playlistLength + videoDuration;
self.playlist[index].timeInPlaylist[1] = playlistLength;
});
};
运行此代码可使索引保持不变,并且输出是数组中记录的3次视频的最后一个视频的长度。然后,在深入研究之后,我意识到我需要某种类型的闭包,因为在循环内添加了事件侦听器。因此,我做了一些重构,来到了当前版本:
function log(e, index) {
videoDuration = Math.round(e.currentTarget.duration);
console.log("Duration of video number " + index + ": " + videoDuration + " seconds");
self.playlist[index].duration = videoDuration;
self.playlist[index].timeInPlaylist[0] = playlistLength;
playlistLength = playlistLength + videoDuration;
self.playlist[index].timeInPlaylist[1] = playlistLength;
}
// Set time in playlist for each video
for (let index=0; index<this.playlist.length; index++) {
var audio = document.getElementById('audio');
console.log('INDEX: ' + index);
self.playlist[index].timeInPlaylist = [];
self.playlist[index].duration = 0;
audio.setAttribute('src', self.playlist[index].bucketRef);
debugger;
(function() {
var i = index;
audio.addEventListener("canplaythrough", function(e) { log(e, i); });
})();
};
这解决了我的索引问题;但是,我仍然只获得数组中最后一个视频的时长。
我非常感谢您的反馈。这个问题使我丧命。
答案 0 :(得分:0)
您创建了一个关闭,但是方式不正确。
将此部分替换为您的代码
(function() {
var i = index;
audio.addEventListener("canplaythrough", function(e) { log(e, i); });
})();
与
audio.addEventListener("canplaythrough", (function(audioObj, index) {
return function(){
log(audioObj, index);
}
})(this, index)
);
这样做应该可以直接访问 log 函数中的音频对象以获取其持续时间,而不是依赖于事件对象。
答案 1 :(得分:0)
您将在循环中同步重置同一音频元素的source属性,并将额外的事件侦听器添加到一个音频元素。
在循环终止并且音频元素为其设置的最后一个src
属性加载音频之后,将调用所有事件监听器,并提供相同的详细信息上一个播放列表项。
您将需要重新设计代码以异步运行,并依次为一个音频元素加载不同的音频源,或者为每个播放列表项创建一个新的AUDIO元素。或者,将持续时间留为空白,直到用户选择要播放的项目(只是一个想法)。
请注意,您不需要创建闭包来保存index
的值-这是调试时的错误:let
的for循环声明中的index
创建了一个单独的对每个循环迭代的变量的词法引用。在循环内的函数表达式中看到的index
的值是对表达式求值时的迭代的值。