HTML5 视频:使用 loadedmetadata 事件包装 timeupdate 事件
HTML5 video: wrapping timeupdate event with loadedmetadata event
我创建了一些代码来将视频观看指标的百分比传回分析平台。我拥有的代码正在运行,但我在使用 IE 时遇到问题,它将我的持续时间和 currentTime 显示为 NaN
.
我发现这个 Whosebug post 关于 loadedmetadataevent
:Problem retrieving HTML5 video duration,但我很难将它添加到我的代码中以使其正常工作。
问题是:如何将 timeupate
事件包装在 loadedmetadata
事件中,以便我可以确定当用户点击视频时我有一个持续时间值?
在很多情况下页面上有多个视频,因此为了帮助说明问题,我创建了一个 JSfiddle。
我尝试将整个代码文件提炼成重要的部分。
jQuery('video').each(function () {
var $video = jQuery(this);
$video.on('timeupdate', function (event) {
console.log(event.target.duration);
console.log(event.target.currentTime);
});
});
完整代码:
/*jslint browser:true*/
var $videos = jQuery('video'),
_ = {
getParamFromInputLink: function (inputLink, param) {
var match = (new RegExp("[?\x26]" + param + "\x3d([^\x26]*)")).exec(inputLink);
return match && decodeURIComponent(match[1].replace(/\+/g, " "));
},
getVideo: function () {
var videoSource = this.attr('src') || this.children().first().attr('src'),
videoName = _.getParamFromInputLink(videoSource, 'n').split('.')[0].replace(/-/g, ' ').toLowerCase() || document.title;
return {
name: videoName
};
},
getInteractionType: function (percentWatched) {
return {
'0%': '100',
'25%': '101',
'50%': '101',
'75%': '101',
'100%': '103'
}[percentWatched];
},
onTimeUpdate: function (event) {
var lastPercentageWatched = event.data.lastPercentageWatched,
videoTitle = event.data.videoName,
currentTime = event.target.currentTime,
duration = event.target.duration,
videoRemaining = duration - currentTime,
videoCompletedBuffer = duration * 0.05,
videoHasCompleted = 1,
currentVideoPercentage = (Math.floor(currentTime / duration * 4) / 4).toFixed(2),
percentOfVideoWatched = videoRemaining <= videoCompletedBuffer ? videoHasCompleted : currentVideoPercentage,
percentOfVideoWatchedCombined,
InteractionType;
if (!lastPercentageWatched || percentOfVideoWatched > event.data.lastPercentageWatched) {
percentOfVideoWatchedCombined = percentOfVideoWatched * 100 + '%';
event.data.lastPercentageWatched = percentOfVideoWatched;
InteractionType = _.getInteractionType(percentOfVideoWatchedCombined);
console.log({
'title': videoTitle,
'type': 'video',
'completionrate': percentOfVideoWatchedCombined,
'video.length': duration,
'interactiontype': InteractionType
});
}
}
},
trackVideo = function () {
var $video = jQuery(this),
videoInfo = _.getVideo.call($video);
$video.on('timeupdate', {
videoName: videoInfo.name,
lastPercentageWatched: false
}, _.onTimeUpdate);
};
/* init */
$videos.each(trackVideo);
最后做了这样的事情:
jQuery('video').each(function () {
var $video = jQuery(this),
videoDuration;
$video.on('loadedmetadata', function(event) {
videoDuration = event.target.duration;
$video.off('loadedmetadata');
$video.on('timeupdate', {
videoDuration: videoDuration
},function (event) {
// access duration like event.data.videoDuration
});
});
});
我创建了一些代码来将视频观看指标的百分比传回分析平台。我拥有的代码正在运行,但我在使用 IE 时遇到问题,它将我的持续时间和 currentTime 显示为 NaN
.
我发现这个 Whosebug post 关于 loadedmetadataevent
:Problem retrieving HTML5 video duration,但我很难将它添加到我的代码中以使其正常工作。
问题是:如何将 timeupate
事件包装在 loadedmetadata
事件中,以便我可以确定当用户点击视频时我有一个持续时间值?
在很多情况下页面上有多个视频,因此为了帮助说明问题,我创建了一个 JSfiddle。
我尝试将整个代码文件提炼成重要的部分。
jQuery('video').each(function () {
var $video = jQuery(this);
$video.on('timeupdate', function (event) {
console.log(event.target.duration);
console.log(event.target.currentTime);
});
});
完整代码:
/*jslint browser:true*/
var $videos = jQuery('video'),
_ = {
getParamFromInputLink: function (inputLink, param) {
var match = (new RegExp("[?\x26]" + param + "\x3d([^\x26]*)")).exec(inputLink);
return match && decodeURIComponent(match[1].replace(/\+/g, " "));
},
getVideo: function () {
var videoSource = this.attr('src') || this.children().first().attr('src'),
videoName = _.getParamFromInputLink(videoSource, 'n').split('.')[0].replace(/-/g, ' ').toLowerCase() || document.title;
return {
name: videoName
};
},
getInteractionType: function (percentWatched) {
return {
'0%': '100',
'25%': '101',
'50%': '101',
'75%': '101',
'100%': '103'
}[percentWatched];
},
onTimeUpdate: function (event) {
var lastPercentageWatched = event.data.lastPercentageWatched,
videoTitle = event.data.videoName,
currentTime = event.target.currentTime,
duration = event.target.duration,
videoRemaining = duration - currentTime,
videoCompletedBuffer = duration * 0.05,
videoHasCompleted = 1,
currentVideoPercentage = (Math.floor(currentTime / duration * 4) / 4).toFixed(2),
percentOfVideoWatched = videoRemaining <= videoCompletedBuffer ? videoHasCompleted : currentVideoPercentage,
percentOfVideoWatchedCombined,
InteractionType;
if (!lastPercentageWatched || percentOfVideoWatched > event.data.lastPercentageWatched) {
percentOfVideoWatchedCombined = percentOfVideoWatched * 100 + '%';
event.data.lastPercentageWatched = percentOfVideoWatched;
InteractionType = _.getInteractionType(percentOfVideoWatchedCombined);
console.log({
'title': videoTitle,
'type': 'video',
'completionrate': percentOfVideoWatchedCombined,
'video.length': duration,
'interactiontype': InteractionType
});
}
}
},
trackVideo = function () {
var $video = jQuery(this),
videoInfo = _.getVideo.call($video);
$video.on('timeupdate', {
videoName: videoInfo.name,
lastPercentageWatched: false
}, _.onTimeUpdate);
};
/* init */
$videos.each(trackVideo);
最后做了这样的事情:
jQuery('video').each(function () {
var $video = jQuery(this),
videoDuration;
$video.on('loadedmetadata', function(event) {
videoDuration = event.target.duration;
$video.off('loadedmetadata');
$video.on('timeupdate', {
videoDuration: videoDuration
},function (event) {
// access duration like event.data.videoDuration
});
});
});