• H5外包团队:使用HTML5播放短视频代码分享


    滑动代码

      1 /**
      2      * 滑动处理
      3      */
      4     function Touch() {
      5         this.init();
      6     }
      7     Touch.fn = Touch.prototype;
      8     Touch.fn.init = function (params) {
      9         var self = this;
     10         dataStore.lastY = dataStore.translateY;//记录当前位移
     11         self.startY = 0;
     12         self.moveY = 0;
     13         // self.lock = 0;//如果在回调或上升阶段不允许滑动.
     14         self.bodyHeight = window.innerHeight;
     15         self.resetLimitY();
     16         self.isIOS = /ip(?:hone|ad|od)/.test(navigator.userAgent.toLowerCase());
     17         ['touchstart','touchmove','touchend'].forEach(function (str) {
     18             document.addEventListener(str,self[str].bind(self));
     19         });
     20     }
     21     Touch.fn.touchstart = function(e){
     22         var self = this;
     23         if(dataStore.lock) return;
     24         self.startY = e.touches[0].pageY;
     25         self.start = Date.now();//标识滑动起始时间,也用于标识滑动start
     26     }
     27     Touch.fn.move = function (y) {
     28         dataStore.translateY = y;
     29     }
     30     Touch.fn.touchmove = function(e){
     31         var self = this;
     32         if(dataStore.lock||!self.start) return;//锁定了,或者没有start,主要是手势一直滑动情况,已经加速度划走了,手势需要松开再重新开始
     33         self.moveY = e.touches[0].pageY - self.startY;
     34         self.move(self.moveY+ dataStore.lastY);   
     35         self.detect();     
     36     }
     37     Touch.fn.detect = function(isEnd){
     38         var self = this;
     39         // console.log(self.moveY+"  "+(Date.now()-self.start));
     40         var a = Math.abs(self.moveY)/(Date.now()-self.start)>=0.5;
     41         if(isEnd){
     42             if(a){
     43                 self.limitY = 0;
     44             }
     45             self.movend();
     46             return;
     47         }
     48         if(self.isIOS&&a){//IOS,可以在touchmove时直接滑动,体验流畅。
     49             self.limitY = 0;
     50             self.movend();
     51         }
     52         
     53     }
     54     Touch.fn.resetLimitY = function () {
     55         this.limitY = this.bodyHeight/3;//位移多少才下滑
     56     }
     57     Touch.fn.touchend = function (e) {
     58         var self = this;
     59         if(dataStore.lock||self.moveY==0||!self.start) return;
     60         self.detect(1);     
     61     }
     62     Touch.fn.movend = function () {
     63         // if(dataStore.lock) return;
     64         // dataStore.lock = 1;
     65         var self = this;
     66         /***
     67          * 最后上下位移小于最小值则还原为上一次位移,
     68          * 否则,那么就需要上移或下移一个body宽度,上移则translate加,下移在减去一个body
     69          * 这里是计算出了应该位移高度。
     70          */
     71         var transformY = Math.abs(self.moveY)<self.limitY?dataStore.lastY:dataStore.lastY+self.bodyHeight*(self.moveY>0?1:-1);
     72          
     73         /***
     74          * 还需计算最大下滑高度和最大上滑高度
     75          */
     76         var listUL = document.querySelector(".quan_vcd_list");
     77         var listHeight = listUL.getBoundingClientRect().height;
     78         
     79         //如果是最后一个li,则不能下滑,
     80         var maxBottom = (listHeight - self.bodyHeight)*-1;
     81         var lastComputeY = transformY>0?0:transformY<maxBottom?maxBottom:transformY;
     82         //停止滑动之后,自动滚动距离,transition
     83         listUL.classList.add('trans');
     84         
     85         if(lastComputeY<=0){
     86             var d = lastComputeY-dataStore.lastY;
     87             d&&events.trigger("touch_move",d,(-lastComputeY/self.bodyHeight));
     88         }
     89         self.start = 0;
     90         var raf = window.requestAnimationFrame|| window.webkitRequestAnimationFrame;
     91         raf(function () {
     92             self.move(lastComputeY);
     93             self.moveY = 0;
     94             dataStore.lastY = lastComputeY;//记录确定的位置
     95             if(listHeight+dataStore.lastY<=self.bodyHeight){
     96                 events.trigger("turnPage");
     97             }
     98             setTimeout(function () {
     99                 listUL.classList.remove("trans");
    100                 dataStore.lock = 0;
    101                 self.resetLimitY();
    102             },500);
    103         });
    104     }
      1 exports.init = function (opt) {
      2         var config = {
      3             props:['feedData','index'],
      4             data:function () {
      5                 return {
      6                     play_btn:0,
      7                     bg_name:"",
      8                     anim_like:[],
      9                     vloading:0
     10                 }
     11             },
     12             mounted:function(){
     13                 addEvent(this);
     14                 this.stall = 0;
     15                 this.loaderror = 0;
     16             },
     17             methods:{
     18                 playBtn:function(){
     19                     this.play();
     20                 },
     21                 onerror:function(){
     22                     errors(this,"error:");
     23                 },
     24                 onbort:function(){
     25                     errors(this,"bort:");
     26                 },
     27                 onstalled:function () {
     28                     var self = this;
     29                     if(!self.feedData.start) return;
     30                     self.vloading = 1;
     31                     self.play();
     32                     self.stall++;
     33                     if(self.stall==2){
     34                         util.showTip("网络有点慢哦~");
     35                         store.report(27,1);
     36                     }
     37                 },
     38                 onplaying:function(){
     39                     var self = this;
     40                     compute(self);
     41                     self.play_btn = 0;
     42                     self.wa("138146.34.1");
     43                     store.report(27,0);
     44                 },
     45                 onpause:function(){
     46                     setPlay(this,1);
     47                 },
     48                 waiting:function () {
     49                     var self = this;
     50                     clearInterval(self.timer);
     51                     self.loadTimes = 0;
     52                     self.timer = setInterval(function () {
     53                         self.loadTimes++;
     54                         if (self.loadTimes >= 2) {//连续3次未播放,当作是卡住了
     55                             self.aPause();
     56                             self.vloading = 1;
     57                         }
     58                     }, 1800);
     59                 },
     60                 ondurationchange:function(){
     61                     compute(this);
     62                 },
     63                 onloadedmetadata:function(){
     64                     compute(this);
     65                 },
     66                 ontimeupdate:function(){
     67                     timeupdate(this);
     68                 },
     69                 aPause:function(){
     70                     var self = this;
     71                     self.audio&&self.audio.pause();
     72                 },
     73                 aPlay:function(){
     74                     var self = this;
     75                     self.audio&&self.audio.play();
     76                 },
     77                 pause:function(){
     78                     var self= this;
     79                     self.video.pause();
     80                     self.aPause();
     81                     self.vloading = 0;
     82                     clearInterval(self.timer);
     83                 },
     84                 play:function(isMove){
     85                     videoPlay(this,isMove);
     86                 },
     87                 checkLoading:function(){
     88                     checkLoading(this);
     89                 },
     90                 show_ani:function (e) {
     91                     showAni(this,e);
     92                 },
     93                 click_pause:function (e) {
     94                     clickPause(this,e);
     95                 },
     96                 onx5videoexitfullscreen:function (params) {
     97                     this.video.play();
     98                 },
     99                 hideAll:function () {
    100                     console.log("hideAll");
    101                 }
    102                 
    103             }
    104         };
    105         Vue.component('video-com',util.assign(config,opt));
    106     }
    107     /**
    108      * 视频暂停
    109      * @param {*} self 
    110      */
    111     function clickPause(self,e) {
    112         var feed = self.feedData;
    113         if(feed.goods_show){
    114             feed.goods_show = 0;
    115             feed.hideOpt = 0;
    116             return;
    117         }
    118         if(feed.input_show==0&&feed.comments_show){
    119             feed.hideOpt = 0;
    120             feed.comments_show = 0;
    121             return;
    122         }
    123         if(feed.input_show){//评论的时候,不允许操作。
    124             return;
    125         }
    126         if(self.dt>0){
    127             self.show_ani(e);
    128             return;
    129         }
    130         self.dt = setTimeout(function () {
    131             self.dt = 0;
    132         },400);
    133  
    134         if(self.t||Date.now-self.dbclick<1500){//dbclick之后,1.5秒不响应点击播放暂停
    135             return;
    136         }
    137         self.t = setTimeout(function () {
    138             self.t = 0;
    139             if(self.play_btn){
    140                 self.play();
    141             }else{
    142                 self.pause();
    143             }
    144         },600);
    145     }
    146     /**
    147      * 双击视频动画
    148      * @param {*} self 
    149      */
    150     function showAni(self,e) {
    151         clearTimeout(self.t);
    152         self.t = 0;
    153         clearTimeout(self.dt);
    154         self.dt = 0;
    155         self.dbclick = Date.now();
    156         var feed = self.feedData;
    157         if(!(feed.commentid>0)&&!self.praising){
    158             self.praising = 1;
    159             store.add_praise(feed,function () {
    160                 self.praising = 0;
    161             },detailUtil.getOnePic(feed));
    162         }
    163         var like = self.anim_like;
    164         var len = like.length;
    165         if(len>=8){
    166             like.splice(0,len-5);
    167         }
    168         like.push({x:e.pageX-100,y:height*this.index+e.pageY - 100});
    169     }
    170     /**
    171      * 检测下载是否完成
    172      * @param {*} self 
    173      */
    174     function checkLoading(self) {
    175         var interval = window.setInterval(getLoaded,100);
    176         // 获取视频已经下载的时长
    177         function getLoaded() {
    178             var end = 0;
    179             try {
    180                 end = parseInt(self.video.buffered.end(0) || 0)+2;
    181             } catch(e) {
    182             }
    183             if(end>=self.duration){
    184                 clearInterval(interval);
    185                 self.loadedAll = 1;
    186                 var nextItem = store.store.feedList[self.index+1];
    187                 if(nextItem){//存在下一条
    188                     //没有播放视频,既还没有加载完成。
    189                     if(!nextItem.playurl) nextItem.playurl = nextItem.videourl;
    190                     //有背景音乐,但是播放的背景音乐未加载完成,则开始加载
    191                     if(!nextItem.bgmurl_p&&nextItem.bgmurl){
    192                         nextItem.bgmurl_p = nextItem.bgmurl;
    193                     }
    194                 }
    195  
    196             }
    197             return end
    198         }
    199     }
    200     /**
    201      * 播放视频
    202      * @param {*} self 
    203      */
    204     function videoPlay(self,isMove) {
    205         self.play_btn = 0;
    206                     
    207         self.aPlay();
    208         
    209         isMove&&(self.video.currentTime = 0);
    210         if(self.audio){
    211             self.video.volume = 0;
    212             self.video.muted =1;
    213         }
    214         var feed = self.feedData; 
    215         if(!feed.playurl){
    216             feed.playurl = feed.videourl;
    217             self.video.load();
    218         }
    219         self.video.play();
    220         isMove&&setTimeout(function (paras) {
    221             
    222             if(isIOS&&!feed.start&&window.isXCX==1){
    223                 self.play_btn = 1;
    224                 clearInterval(self.timer);
    225             }else if(!feed.start){
    226                 setTimeout(function () {
    227                     if(feed.start) return;
    228                     setPlay(self,1);
    229                     clearInterval(self.timer);
    230                 },2000);
    231             }
    232         },1000);
    233         self.waiting();
    234     }
    235     /**
    236      * 播放中处理
    237      * @param {*} self 
    238      */
    239     function timeupdate(self) {
    240         var ct = self.video.currentTime;
    241         if(!self.duration) return;
    242         self.feedData.play_time = ct*100/self.duration;//设置到住storage
    243         // console.log("timeupdate");
    244         self.loadTimes>=2&&self.aPlay();
    245         var feed = self.feedData;
    246         if(!feed.start&&ct>0){
    247             feed.hide = 0;//video is hide or show
    248             feed.start = 1;//video is start ,should hide poster
    249         }
    250         self.vloading = 0;
    251         self.play_btn = 0;
    252         self.loadTimes = 0;
    253         self.loaderror = 0;
    254         if(!self.move&&ct+1>=self.duration/2){
    255             self.feedData.goodsMove = 1;
    256             self.move = 1;
    257         }
    258         if(Math.round(ct)%3==0){
    259             self.wa("138146.35.1");
    260         }
    261         if(!self.waDone&&Math.ceil(ct+1)>=self.duration){
    262             self.wa("138146.9.1");
    263             self.waDone = 1;
    264         }
    265     }
    266     /**
    267      * 处理视频和背景音乐
    268      * @param {*} self 
    269      */
    270     function addEvent(self) {
    271         self.$nextTick(function () {
    272             self.video = self.$el.querySelector("video");
    273             var arry = ['stalled','playing', 'timeupdate', 'abort', 'error','durationchange','loadedmetadata','pause','x5videoexitfullscreen'];
    274             arry.forEach(function (str) {
    275                 self.video.addEventListener(str,self['on'+str]);
    276             });
    277             if(self.index==0){
    278                 loadWX(function (env) {
    279                     if(env&&isAndroid) return;
    280                     self.play();
    281                 });
    282             }
    283         });
    284         var feed = self.feedData;
    285         handleBGM(feed,self);
    286         
    287         events.listen("touch_move",function (direct,i) {
    288             handleMove(self,feed,direct,i);
    289         });
    290     }
    291     /**
    292      * 处理滑动播放
    293      * @param {*} self 
    294      * @param {*} feed 
    295      * @param {*} direct 
    296      * @param {*} i 
    297      */
    298     function handleMove(self,feed,direct,i) {
    299         if(i==self.index){
    300             detailUtil.setShare(self.feedData);
    301             if(!feed.playurl){
    302                 feed.playurl = feed.videourl;
    303                 if(!feed.bgmurl_p&&feed.bgmurl){
    304                     feed.bgmurl_p = feed.bgmurl;
    305                     self.audio.load();
    306                 }
    307                 self.video.load();
    308             }
    309             self.$nextTick(function () {
    310                 store.addPlayNum(feed.shareid);
    311                 if(self.audio&&!self.audioLoaded){
    312                     var int = setInterval(function () {
    313                         if(self.audioLoaded){
    314                             clearInterval(int);
    315                             self.play(1);
    316                         }
    317                     },100);
    318                 }else{
    319                     self.play(1);
    320                 }
    321             });
    322         }
    323         //direct>0 则是下滑,页面出现上一个视频,则当前位置的下一个视频要暂停,
    324         //direct<0则是上滑,页面要播放下一个视频了,则当前位置的上一个视频要暂停
    325         if(self.index == i+(direct>0?1:-1)){
    326             self.pause();
    327             if(!self.loadedAll){
    328                 feed.playurl = "";//如果是未加载完成,那么就不要加载了。
    329                 feed.start = 0;
    330                 feed.hide = 1;
    331             }
    332             if(!self.audioLoaded){
    333                 feed.bgmurl_p = "";
    334             }
    335         }
    336         if(self.index>=i+7||self.index<=i-7){
    337             feed.maxHide = 1;//最大超过16个节点,则隐藏。
    338             feed.playurl = "";//最大超过16个节点,则把其他视频干掉。
    339             feed.start = 0;
    340             feed.hide = 1;            
    341         }else{
    342             feed.maxHide = 0;
    343         }
    344     }
    345     function loadWX(cb) {
    346         if(device.scene=="weixin"){
    347             if(window.WeixinJSBridge){
    348                 cb(1);
    349             }else{
    350                 document.addEventListener("WeixinJSBridgeReady", function() {
    351                     cb(1);
    352                 });
    353             }
    354         }else{
    355             cb();
    356         }
    357     }
    358     /**
    359      * 处理背景
    360      * @param {*} feed 
    361      * @param {*} self 
    362      */
    363     function handleBGM(feed,self) {
    364         //背景音乐
    365         var bgm=feed.bgm;
    366         if(bgm&&window.bgmlist&&bgmlist[bgm]){
    367             self.bg_name = bgmlist[bgm].bgmname;
    368             feed.bgmurl = bgm+".mp3";
    369             if(self.index==0){
    370                 feed.bgmurl_p = feed.bgmurl;
    371             }
    372             self.audio = self.$el.querySelector("audio");
    373             setPlay(self,0);
    374             var t = setTimeout(function () {//超时处理
    375                 done();
    376             },4000);
    377             loadWX(throuth);
    378             function throuth(){
    379                 self.audio.addEventListener("canplaythrough",function () {
    380                     done();
    381                 });
    382             }
    383             function done(){
    384                 clearTimeout(t);
    385                 self.vloading = 0;
    386                 self.audioLoaded = 1;
    387                 !feed.start&&(setPlay(self,1));//还没播放,则吧播放按钮弹出来
    388             }
    389             
    390         }else{
    391             setPlay(self,1);
    392         }
    393     }
    394     function compute(self) {
    395         if(self.isCd) return;
    396         var d = self.video.duration;
    397         if (d>0) {
    398             self.isCd = true;
    399             self.duration = d;
    400             self.checkLoading();
    401         }
    402     }
    403     function setPlay(self,f){
    404         self.play_btn = f;
    405         self.vloading = !f;
    406     }
    407     function errors(self,msg) {
    408         if(!self.video||!self.feedData.start) return;
    409         self.loaderror++;
    410         if(self.loaderror<=2){
    411             self.play();
    412             return;
    413         }
    414         setPlay(self,1);
    415         msg += JSON.stringify(self.video.error)+","+self.video.src;
    416         store.report(26,0,msg);
    417     }


    有H5项目需求欢迎联系我们 我们提供免费的项目评估报价

    QQ:372900288

    WX:Liuxiang0884

  • 相关阅读:
    SegmentFault 巨献 1024 程序猿游戏「红岸的呼唤」第二天任务攻略
    POJ 2263 Heavy Cargo(ZOJ 1952)
    EEPlat 主子表和对象引用配置实例
    tornado websocket
    android android:duplicateParentState=&quot;true&quot; &quot;false&quot;
    掌握4个有效的数据分析要点,切实解决用户痛点
    掌握4个有效的数据分析要点,切实解决用户痛点
    没有基础,如何成为数据分析师?
    没有基础,如何成为数据分析师?
    数据的无量纲化处理和标准化处理的区别是什么
  • 原文地址:https://www.cnblogs.com/slteam/p/10379325.html
Copyright © 2020-2023  润新知