打造一个简单的视频同步网站

打造一个简单的视频同步网站

任务需求

主要实现的任务就是大家通过加入同一个房间,然后能够观看到同一部视频,并且可以在一方设置了一些状态,比如暂停等, 其他同房间的用户可以捕获到并更新自己的状态。

在这里对于观看同一部视频而言,视频的来源来自一个m3u8视频源,这样直接用videojs就可以播,并且因为m3u8这样的视频可以在网上找并且也可以自己做,所以灵活性大,比如大家想看一部aa的电影,我们如果能找到这部电影的m3u8地址,那么就不用下载直接用即可,如果网上没有,那么我们可以下载下来然后转码成m3u8来看,所以更灵活。

对于大家同步而言,这里的考虑是对于每个房间,用房间号做key,然后视频的播放状态封装成一个类,做value,大家的获取和更新都可以基于这一份播放状态来更新,保持一致。而这个key-value保存到webcontext里面即可,大家都可以看得到。

下面就通过前端和后端两部分来进行开发。

前端部分

界面搭建

主要两部分,第一个就是输入房间信息,这个用一个模态框,还有就是视频播放,这里用videojs控制:

<div class="modal fade" tabindex="-1" role="dialog" id="join_room">
    <div class="modal-dialog" role="document">
        <div class="modal-content">
            <div class="modal-header">
                <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
                <h4 class="modal-title">加入房间</h4>
            </div>
            <div class="modal-body">
                <form class="form-horizontal">
                    <div class="form-group">
                        <label class="col-sm-2 control-label">用户名</label>
                        <div class="col-sm-10">
                            <input type="text" class="form-control" id="userName" name="userName" placeholder="">
                        </div>
                    </div>

                    <div class="form-group">
                        <label class="col-sm-2 control-label">房间号</label>
                        <div class="col-sm-10">
                            <input type="text" class="form-control" id="roomId" name="roomId" placeholder="">
                        </div>
                    </div>

                    <div class="form-group">
                        <label class="col-sm-2 control-label">房间密码</label>
                        <div class="col-sm-10">
                            <input type="text" class="form-control" id="roomPasswd" name="roomPasswd" placeholder="">
                            <span class="help-block"></span>
                        </div>
                    </div>
                </form>

            </div>
            <div class="modal-footer">
                <button type="button" class="btn btn-default" data-dismiss="modal">关闭</button>
                <button type="button" class="btn btn-primary" id = "join" >保存</button>
            </div>
        </div><!-- /.modal-content -->
    </div><!-- /.modal-dialog -->
</div><!-- /.modal -->

<div class="container" >
    <div class="row">
        <div class="col-md-4" id="room_id"></div>
        <div class="col-md-4" id="movie_url_area"></div>
        <div class="col-md-4" id="update_url_btn_area"></div>
    </div>
    <div class="row">
        <div class="col-md-12" id="video_area" style="display:none;">
            <video id="my_video" class="video-js" controls preload="auto" width="960" height="400" data-setup="{}" >
                <p class="vjs-no-js">Not support</p>
            </video>
        </div>
    </div>
</div>

进入房间

var vid = document.getElementById("my_video");
var userName;
var roomId;
var movieSyc;
$(function(){
    reset_form("#join_room form");
    $('#join_room').modal({
        backdrop: "static"
    });
});

当输入网址后,第一件事情是需要输入用户名,房间名和密码(也就是上面的弹出一个模态框join_room),然后到后台查询,有三种情况:

1、房间不存在,则后台创建一个空房,并返回对应视频同步状态

2、房间存在且密码正确,则返回该房间的视频同步状态

3、房间存在且密码错误,返回错误码

$("#join").click(function(){
    roomId = $("#roomId").val();
    var roomPasswd = $("#roomPasswd").val();
    userName = $("#userName").val();
    $.ajax({url:"${BASE_PATH}/get",
        type:"GET",
        data:{"roomId":roomId,"roomPasswd":roomPasswd,"userName":userName},
        success:function(result){
            if(result.code==100){
                $("#join_room").modal('hide');
                $("#room_id").text("房间号:"+roomId);
                $("#movie_url_area").append($("<input type='text' class='form-control' id='movie_url' placeholder='地址m3u8'></input>"));
                $("#update_url_btn_area").append($("<button type='button' class='btn btn-primary' id = 'update_url_btn' >更新</button>"));
                $("#video_area").attr("style","");
                videojs("my_video").ready(function() {});

                if(result.extend.movieSyc.movieUrl!=null){
                    update_url(result.extend.movieSyc.movieUrl);
                }
                get_update();
                report_time();
            }else{
                $("#roomPasswd").addClass("has-error");
                $(".help-block").text(result.msg);
            }
        }});
});
function update_url(url){
        $("#movie_url").val(url);
        videojs("my_video").src(url);
    }

如果成功进入房间里,则需要构建这个房间,主要包括一个输入框,输入电影地址,一个按钮用来提交,一个videojs用来播放视频。result.code==100里面就是做这些内容的,并且如果进入的房间里面本来就有人在播放电影,这里需要进行一个把当前的电影地址更新一下。

除此之外里面还有另外的两个函数get_update();report_time();,get_update是一个死循环函数,主要是持续向后台发请求,如果后台发现电影播放状态更新了,就响应get_update,如果状态没更新就阻塞,这样达到保持自己最新。而report_time主要是将当前播放时间汇报给后台,这样可以让大家都知道彼此的进度,保持大家一致。稍后会简单分析这两个函数。

get_update

function get_update(){
    //持续更新,进入房间后使用
    $.ajax({url:"${BASE_PATH}/getupdate",
        type:"GET",
        data:{"roomId":roomId,"userName":userName},
        success:function(result){
            movieSyc = result.extend.movieSyc;
            console.log(result);
            update_status(movieSyc);
            get_update(); // 持续更新
        }});
}

从上面可以看出,get_update里面是发送了一个ajax请求,如果请求成功了还会继续调用这个函数,如果后台阻塞,则这里也会等待。获取完成后,会对状态做一个简单的更新update_status(movieSyc);

function update_status(movieSyc) {
    if(movieSyc.movieUrl!=null){
        if(movieSyc.movieUrl!= $("#movie_url").val()){
          update_url(movieSyc.movieUrl); //因为更新url会重新加载视频,如果未更改则不修改
        }
        if(movieSyc.time!=null){
            set_time(vid,movieSyc.time);
        }
        if(movieSyc.play==true){
            videojs("my_video").autoplay();
            videojs("my_video").play();
        }else {
            videojs("my_video").pause();
        }
    }
}

可以看出其主要就是根据后台信息,来更新当前的状态。

report_time

这个主要是按照一定时钟,来报告自己的状态:

function report_time(){
    setInterval(function(){
        if(movieSyc.play){
            var currentTime = Math.floor(videojs("my_video").currentTime());
            click_update(roomId,null,null,currentTime);
        }

    },10000);
}

如果视频是播放的状态,则按照每10s来报告一次自己的进度条状态,这里涉及到一个函数click_update(roomId,null,null,currentTime);,这个函数就是向后台发送请求,来更新后台的房间状态:

function click_update(roomId,movie_url,play,time){
    $.ajax({url:"${BASE_PATH}/update",
        type:"GET",
        data:{"roomId":roomId,"movieUrl":movie_url,"play":play,"time":time}
    });
}

这里不仅仅可以更新时间,还有播放状态,url等。

其他事件的更新

除了按照10s一次来更新自己的时间状态来避免进度不一致,如果发生了一些事件,比如播放暂停等,我们也需要报告状态,而这个事件可以通过事件函数捕获:

videojs("my_video").on("play",function()
{
   click_update(roomId,null,true,Math.floor(videojs("my_video").currentTime()));
});
videojs("my_video").on("pause", function(){
    click_update(roomId,null,false,Math.floor(videojs("my_video").currentTime()));
});

上面两个就可以对播放暂停进行上报状态,并且对拖动进度条也可以上报,因为拖动进度条会触发播放和暂停事件,而播放和暂停里面也上报了当前时间。

更新url的上报:

$(document).on("click","#update_url_btn", function () {
    var movie_url = $("#movie_url").val();
    click_update(roomId,movie_url,true,0);
    update_url(movie_url)
});

直接通过点击更新这个按钮来上报,播放时间置为0。

其他函数

上面还用到了一个set_time,其实就是设置时间,这里主要是想着如果时间差距不大,可以不重置,所以封装了一下:

function set_time(vid,time){
    if(Math.abs(videojs("my_video").currentTime()-time)<5){
        return;
    }else{
        videojs("my_video").currentTime(time);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值