jQuery TML5播放器连续播放分段视频方法

首先多播放器窗口,除了一个以外display:none,一般需求中两个就足够了。然后监听是否结束(关于监听,稍后再发一篇讲讲Javascript的监听问题),监听本P播放结束之后将下一个的链接赋值到隐藏的那个,交替display,进度条当然需要重做,这里就需要统计总时长了。

当然理论上很好想,实际在用的时候还是遇到了一些问题:
最近由于工作需要在研究HTML5的播放器,HTML5其实自带的已经很全了,但是当我们需要把切割的视频整合播放的时候就遇到了麻烦,这里我想到了一个思路,正好发现网上也提到了很多这种思路:

首先多播放器窗口,除了一个以外display:none,一般需求中两个就足够了。然后监听是否结束(关于监听,稍后再发一篇讲讲Javascript的监听问题),监听本P播放结束之后将下一个的链接赋值到隐藏的那个,交替display,进度条当然需要重做,这里就需要统计总时长了。

当然理论上很好想,实际在用的时候还是遇到了一些问题:

首先我们来看一下,在加载过程中,依次会发生什么:
当音频/视频处于加载过程中时,会依次发生以下事件:

loadstart
durationchange
loadedmetadata
loadeddata
progress
canplay
canplaythrough

并且这些步骤全部都不是瞬时发生的,试网速而定,正因为如此所以当时我测试替换URL-获取时间-替换URL时才因此失败了。结果得到了一串 NULL,正确的做法是需要监听并执行以上操作。

如果你需要提前缓冲,需要监听timeupdate并且返回值,然后与总时长相减,根据条件判断并加载就行了^ ^

此外的一些,自取函数,之所以打上jQuery标签,是因为懒……:
url使用飞驴获取,时效性很短需要测试请替换数组内容

 代码如下 复制代码
var videos = new Array('视频1', '视频2', '视频3');
        var timeline = new Array(0);    // 记录各点时间
        var nowVideoLocation = 0;   // 目前所在的位置
        var playerNum = 0; // 目前使用的video标签位置
        var str;        // 输出信息
        var totalTime = 0;      // 视频总时长
        var currentVideoTime = 0;
        var i = 0;  // 初始化计数器
        var targetTime = 0; // 目标时间
        var targetPlayer = 0;   // 记录目标播放器
        var loadNextSource = false; // 是否已经将下一个url写入src
        $('document').ready(function() {
initTimeline();     // 运行初始化函数
        // $('.video:eq(' + playerNum + ')').attr('src', videos[i]);
        /*          setInterval(function(){
str = $('#video-meta').html();
$('#video-meta').html(str + '目前时间')
        }, 100)
        */
/*          $('.video')[playerNum].addEventListener('');
*/
$('#btn-play').click(function() {
    if ($('.video')[playerNum].paused)
        $('.video')[playerNum].play();
    else
        $('.video')[playerNum].pause();
});
$('#set-time').click(function() {
    setToTime($('#time').val());
})
        });
function initHandler() {
    timeline[i] = $('.video') [1].duration;
    totalTime += timeline[i];
    if (i < videos.length - 1) {
        $('.video')[1].src = videos[++i]
    } else {
        $('.video')[1].src = '';
        $('.video')[1].removeEventListener('loadedmetadata', initHandler, true);
    }
}
function currentTimeHandler() {
    currentVideoTime = $('.video')[playerNum].currentTime;
    if (timeline[nowVideoLocation] - currentVideoTime < 20 && !loadNextSource) {
        loadNextVideo(nowVideoLocation + 1);
        loadNextSource = true;
    }
    console.log(currentVideoTime);      // 定期返回监控时间
}
function initTimeline () {
    $('.video')[1].preload = 'auto';
    $('.video')[1].src = videos[i];
    $('.video')[0].src = videos[i];
    $('.video')[1].addEventListener('loadedmetadata', initHandler, true);
    $('.video')[0].addEventListener('timeupdate', currentTimeHandler, true);
    $('.video')[0].addEventListener('ended', switchNextVideo, true);
}
function loadNextVideo(nextLocation) {
    var nextPlayer = Number(!playerNum);
    if (nextLocation < videos.length) {
        $('.video')[nextPlayer].preload = 'auto';
        $('.video')[nextPlayer].src = videos[nextLocation];
    }
}
function setToTime(time) {
    var videoChapter;
    var nextPlayer = Number(!playerNum);
    if (time >= totalTime) {
        videoChapter = videos.length - 1;
        time = totalTime;
    } else {
        for (videoChapter = 0; videoChapter < videos.length - 1; videoChapter++) {
if (time - timeline[videoChapter] < 0) {
    break;
} else {
    console.log('videoTime:' + time);
    time -= timeline[videoChapter];
}
        }
    }
    console.log('videoChapter: '+videoChapter);
    if (videoChapter == nowVideoLocation) {
        $('.video')[playerNum].currentTime = time;
    } else {
        loadNextVideo(videoChapter);
        console.log(time);
        targetTime = time;
        /*$('.video')[nextPlayer].currentTime = time;*/
        targetPlayer = nextPlayer;
        $('.video')[targetPlayer].addEventListener('durationchange', jumpToTime, true);
        switchToVideo();
        nowVideoLocation = videoChapter;
        console.log('nowVideoLocation: '+nowVideoLocation);
    }
}
function jumpToTime() {
    $('.video')[targetPlayer].currentTime = targetTime;
    console.log('hello');
    $('.video')[targetPlayer].removeEventListener('durationchange', jumpToTime, true);
}
function switchNextVideo() {
    var nextPlayer = Number(!playerNum);
    loadNextSource = false;
    console.log('SwitchNow!');
    if (nowVideoLocation < videos.length - 1) {
        $('.video:eq(' + nextPlayer + ')').css('display', '');
        $('.video:eq(' + playerNum + ')').css('display', 'none');
        $('.video')[playerNum].pause();
        $('.video')[playerNum].removeEventListener('timeupdate', currentTimeHandler, true);
        $('.video')[playerNum].removeEventListener('ended', switchNextVideo, true);
        $('.video')[playerNum].src = '';
        $('.video')[nextPlayer].addEventListener('timeupdate', currentTimeHandler, true);
        $('.video')[nextPlayer].addEventListener('ended', switchNextVideo, true);
        $('.video')[nextPlayer].play();
        nowVideoLocation++;
        playerNum = nextPlayer;
    } else {
        $('.video')[playerNum].removeEventListener('ended', switchNextVideo, true);
    }
}
function switchToVideo() {
    var nextPlayer = Number(!playerNum);
    console.log('SwitchNow!');
    loadNextSource = false;
    $('.video:eq(' + nextPlayer + ')').css('display', '');
    $('.video:eq(' + playerNum + ')').css('display', 'none');
    $('.video')[playerNum].pause();
    $('.video')[playerNum].removeEventListener('timeupdate', currentTimeHandler, true);
    $('.video')[playerNum].removeEventListener('ended', switchToVideo, true);
    $('.video')[playerNum].src = '';
    $('.video')[nextPlayer].addEventListener('timeupdate', currentTimeHandler, true);
    $('.video')[nextPlayer].addEventListener('ended', switchToVideo, true);
    $('.video')[nextPlayer].play();
}

后记:后来在这里看到类似思路,加载点略不同,测试了一下似乎在提前在网速不佳的情况下表现效果会so bad,还是这样就好了,进度条需要诸君利用setToTime函数自行重写,请自便

ps:可以使用jPlayer,jPlayer对HTML5中的<audio>和<video>标签做了很好的封装。在浏览器支持HTML5的情况下用HTML5标签,在浏览器不支持HTML5的情况下用flash代替。更重要的是jPlayer提供对播放器界面的完全定制,保证无论是在何种浏览器下播放器外观都能够一致。由于可以定制播放器界面,你提出来的要求便可以满足。
下面是我自己一个项目的代码片段,我精简了一下。你找一下timeupdate: function(event) {这一行代码,里面有更新进度条的代码

时间: 2024-11-22 17:05:05

jQuery TML5播放器连续播放分段视频方法的相关文章

c#-想要获取当前播放器正在播放的视频文件的名称该怎么写?

问题描述 想要获取当前播放器正在播放的视频文件的名称该怎么写? 想要获取当前播放器正在播放的视频文件的名称该怎么写?想做一个小实例,但是到这里不知道该怎么写了. 解决方案 你们用jquery吗,可以获取到节点的名称在操作吗

android音乐播放器中播放模式的设计

在音乐播放器中,播放模式一般放在音乐播放完毕后自动识别,如下给出逻辑代码,可根据需要添加合适 的代码 public static final int ALL = 0;//全部循环 public static final int SINGLE = 1;//单曲循环 public static final int RANDOM = 2;//随机 // 一首歌播放完成后(这里设置播放模式) public class Completed implements OnCompletionListener {

VLC播放器中文字幕乱码问题解决方法

  VLC对于Mac用户来说算得上是必备软件.其相当于PC上的"暴风影音",但Mac新手使用VLC播放avi时都会碰到字幕乱码的问题.avi字幕的格 式有多种,这里假设你使用常见的.srt字幕.VLC默认支持的字幕内码为utf-8,而网上提供的.srt字幕基本上都是GBK码,所以在初装 VLC后的默认状态下,加载.srt字幕都会出现乱码.VLC播放器中文字幕乱码问题解决方法如下 正如上面所说的,VLC默认支持的字幕内码为utf-8,而我们从网上下载的.srt字幕基本上都是GBK码,因此

嵌入播放器-网站中用realplayer播放器不能播放电影名为中文的电影

问题描述 网站中用realplayer播放器不能播放电影名为中文的电影 网站中用realplayer播放器不能播放电影名为中文的电影.怎么解决啊?非常感谢

java播放器-嵌入windowsplayer播放器怎么播放放在服务器上的音乐文件

问题描述 嵌入windowsplayer播放器怎么播放放在服务器上的音乐文件 就是用这个读取windowsplayer的播放器的注册表,现在要达到的一个功能是要播放服务器上的音乐文件,音乐文件是放在服务器的本地上的

怎么实现音乐播放器的播放模式

问题描述 怎么实现音乐播放器的播放模式 为了进一步完善音乐播放器,怎么实现音乐播放器的播放模式(单曲播放,循环播放,随机播放,顺序播放)?由于涉及的知识点还没学,求大神帮帮忙吧 解决方案 用一个值来保存播放模式 在每首歌播放结束的逻辑(mediaplayer 的OnSeekCompleteListener中)去处理播放逻辑, 如果单曲循环, 继续播放当前歌曲; 如果是循环播放模式: 当前播放歌曲 = (当前播放歌曲+1 ) % (歌曲总数);如果是随机播放, 当前歌曲 = random() (范

android播放器点播放后,出现以下错误,求大神帮忙解决

问题描述 android播放器点播放后,出现以下错误,求大神帮忙解决 解决方案 权限设置没设置,要在配置文件把android.permission.access_network_state这个权限加进去

flash-问: 10 我想做一个winform的播放器来播放斗鱼的直播,求大神指点。

问题描述 问: 10 我想做一个winform的播放器来播放斗鱼的直播,求大神指点. 目前没有思路,希望大神出来指点一二.我试过了很多种,利用flash 的插件也无法实现. 解决方案 webbrowser里面加载http://www.douyutv.com/ 解决方案二: 想做一个推荐系统,求志同道合者...

VLC 获取播放器H.264格式视频

问题描述 C#调用vlcdll获取本地视频文件的持续播放时间(播放总时间)格式是:h.264 解决方案