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

 

posted @ 2019-02-14 20:12  Unity外包团队  阅读(3555)  评论(0编辑  收藏  举报