ckplayer-plus 1.0.0 → 1.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/ckplayer.css CHANGED
@@ -87,13 +87,13 @@
87
87
  width: 80px;
88
88
  height: 80px;
89
89
  border-radius: 50%;
90
- background: url(images/loading.png) no-repeat center center;
90
+ background: url(./images/loading.png) no-repeat center center;
91
91
  background-size: 100% 100%;
92
92
  animation: ck-Circle 1.5s linear infinite;
93
93
  -webkit-animation: ck-Circle 1.5s linear infinite
94
94
  }
95
95
  .ckplayer-ckplayer .ck-main .ck-center-play{
96
- background: url(images/play.png) no-repeat 70% center;
96
+ background: url(./images/play.png) no-repeat 70% center;
97
97
  background-size:60% 60%;
98
98
  border: 8px solid rgba(255,255,255,.3);
99
99
  border-radius: 50%;
@@ -127,7 +127,7 @@
127
127
  height: 120px;
128
128
  }
129
129
  .ckplayer-ckplayer .ck-main .ck-buffer{
130
- background: url(images/buffer.png) no-repeat center center;
130
+ background: url(./images/buffer.png) no-repeat center center;
131
131
  background-size:100% 100%;
132
132
  border-radius: 50%;
133
133
  width: 60px;
@@ -501,7 +501,7 @@
501
501
  /*显示广告时的底部按钮-共用*/
502
502
  .ckplayer-ckplayer .ck-main .ck-yytf .ck-yytf-bottom .ck-yytf-btn{
503
503
  background-color: rgba(0,0,0,.6);
504
- background-image: url(images/ckplayer.png);
504
+ background-image: url(./images/ckplayer.png);
505
505
  background-size: auto 100%;
506
506
  border: none;
507
507
  outline: none;
@@ -634,7 +634,7 @@
634
634
  width: 30px;
635
635
  height: 30px;
636
636
  background-color: transparent;
637
- background-image: url(images/adclose.png);
637
+ background-image: url(./images/adclose.png);
638
638
  border: none;
639
639
  outline: none;
640
640
  cursor: pointer;
@@ -691,7 +691,7 @@
691
691
  /*按钮公用样式*/
692
692
  .ckplayer-ckplayer .ck-main .ck-bar-btn{
693
693
  background-color: transparent;
694
- background-image: url(images/ckplayer.48.png);
694
+ background-image: url(./images/ckplayer.48.png);
695
695
  background-size: auto 100%;
696
696
  border: none;
697
697
  outline: none;
@@ -701,7 +701,7 @@
701
701
  background-repeat: no-repeat ;
702
702
  }
703
703
  .ckplayer-ckplayer .ck-main.ck-main-full .ck-bar-btn{
704
- background-image: url(images/ckplayer.png);
704
+ background-image: url(./images/ckplayer.png);
705
705
  width: 70px;
706
706
  height: 70px;
707
707
  }
@@ -87,13 +87,13 @@
87
87
  width: 80px;
88
88
  height: 80px;
89
89
  border-radius: 50%;
90
- background: url(images/loading.png) no-repeat center center;
90
+ background: url(./images/loading.png) no-repeat center center;
91
91
  background-size: 100% 100%;
92
92
  animation: ck-Circle 1.5s linear infinite;
93
93
  -webkit-animation: ck-Circle 1.5s linear infinite
94
94
  }
95
95
  .ckplayer-ckplayer .ck-main .ck-center-play{
96
- background: url(images/play.png) no-repeat 70% center;
96
+ background: url(./images/play.png) no-repeat 70% center;
97
97
  background-size:60% 60%;
98
98
  border: 8px solid rgba(255,255,255,.3);
99
99
  border-radius: 50%;
@@ -127,7 +127,7 @@
127
127
  height: 120px;
128
128
  }
129
129
  .ckplayer-ckplayer .ck-main .ck-buffer{
130
- background: url(images/buffer.png) no-repeat center center;
130
+ background: url(./images/buffer.png) no-repeat center center;
131
131
  background-size:100% 100%;
132
132
  border-radius: 50%;
133
133
  width: 60px;
@@ -501,7 +501,7 @@
501
501
  /*显示广告时的底部按钮-共用*/
502
502
  .ckplayer-ckplayer .ck-main .ck-yytf .ck-yytf-bottom .ck-yytf-btn{
503
503
  background-color: rgba(0,0,0,.6);
504
- background-image: url(images/ckplayer_ixigua.png);
504
+ background-image: url(./images/ckplayer_ixigua.png);
505
505
  background-size: auto 100%;
506
506
  border: none;
507
507
  outline: none;
@@ -634,7 +634,7 @@
634
634
  width: 30px;
635
635
  height: 30px;
636
636
  background-color: transparent;
637
- background-image: url(images/adclose.png);
637
+ background-image: url(./images/adclose.png);
638
638
  border: none;
639
639
  outline: none;
640
640
  cursor: pointer;
@@ -692,7 +692,7 @@
692
692
  /*按钮公用样式*/
693
693
  .ckplayer-ckplayer .ck-main .ck-bar-btn{
694
694
  background-color: transparent;
695
- background-image: url(images/ckplayer_ixigua.48.png);
695
+ background-image: url(./images/ckplayer_ixigua.48.png);
696
696
  background-size: auto 100%;
697
697
  border: none;
698
698
  outline: none;
@@ -702,7 +702,7 @@
702
702
  background-repeat: no-repeat ;
703
703
  }
704
704
  .ckplayer-ckplayer .ck-main.ck-main-full .ck-bar-btn{
705
- background-image: url(images/ckplayer_ixigua.png);
705
+ background-image: url(./images/ckplayer_ixigua.png);
706
706
  width: 70px;
707
707
  height: 70px;
708
708
  }
package/dist/ckplayer.js CHANGED
@@ -136,10 +136,12 @@
136
136
  keyVolume:2,//是否启用键盘控制音量调节,0=不启用,1=启用,2=全屏时才启用
137
137
  errorShow:true,//是否显示错误信息
138
138
  pluginPath:'',//插件与语言包根路径(bundler 下建议配置或设置 window.ckplayerBasePath)
139
- autoPlug:true//未指定 plug 时,根据视频地址后缀自动选择 hls.js / flv.js / mpegts.js
139
+ autoPlug:true,//未指定 plug 时,根据视频地址后缀自动选择 hls.js / flv.js / mpegts.js
140
+ preferBuiltinPlug:true,//优先加载本包内置插件脚本,避免复用页面上其它版本的全局 Hls/flvjs/mpegts
141
+ cdnFallback:true// getPath 失败时是否回退到 jsDelivr(内网可设 false,并配置 pluginPath)
140
142
  };
141
143
  // 打包时替换为真实版本;用于 bundler 下 getPath 失效时的 CDN 回退
142
- var ckplayerPlusDefaultCdn='https://cdn.jsdelivr.net/npm/ckplayer-plus@1.0.0/dist/';
144
+ var ckplayerPlusDefaultCdn='https://cdn.jsdelivr.net/npm/ckplayer-plus@1.0.2/dist/';
143
145
  function ckplayerEmbed(videoObj){
144
146
  /*
145
147
  * rightMenu
@@ -392,7 +394,12 @@
392
394
  if(fromScript && fromScript.indexOf(folder+'/')>-1 && fromScript.indexOf('undefined')===-1){
393
395
  return fromScript;
394
396
  }
397
+ var allowCdn=!vars || vars['cdnFallback']!==false;
395
398
  var cdn=(typeof window!=='undefined' && window.ckplayerPlusCdn) ? window.ckplayerPlusCdn : ckplayerPlusDefaultCdn;
399
+ if(!allowCdn || !cdn || cdn.indexOf('1.0.2')>-1){
400
+ // 避免占位版本或显式关闭 CDN 时请求坏地址;交给相对路径或业务 pluginPath
401
+ return folder+'/'+file;
402
+ }
396
403
  if(cdn.slice(-1)!=='/'){
397
404
  cdn+='/';
398
405
  }
@@ -764,12 +771,21 @@
764
771
  if(valType(vars['seek'])=='number' && vars['seek']>0){
765
772
  seekTime=vars['seek'];
766
773
  }
767
- if(valType(vars['seek'])=='string' && vars['seek']=='cookie' && cookieName){
774
+ else if(valType(vars['seek'])=='string' && vars['seek']=='cookie' && cookieName){
768
775
  var cke=player.cookie(cookieName);
769
776
  if(cke){
770
777
  seekTime=cke['time'];
771
778
  }
772
-
779
+ }
780
+ else if(valType(vars['seek'])=='string' && vars['seek']!=='' && !isNaN(parseFloat(vars['seek']))){
781
+ seekTime=parseFloat(vars['seek']);
782
+ }
783
+ // 与旧版对齐:续播 seek 同步进度水位,避免 timeScheduleAdjust=5 时被打回 0
784
+ if(seekTime && seekTime>0){
785
+ maxSeeTime=Math.max(maxSeeTime,seekTime);
786
+ if(firstSeekTime<0){
787
+ firstSeekTime=seekTime;
788
+ }
773
789
  }
774
790
  }
775
791
  },
@@ -816,6 +832,9 @@
816
832
  hls = new Hls();
817
833
  hls.loadSource(url);
818
834
  hls.attachMedia(video);
835
+ hls.on(Hls.Events.MANIFEST_PARSED, function(){
836
+ applyPendingSeek();
837
+ });
819
838
  hls.on(Hls.Events.ERROR, function(event, data){
820
839
  var code=9;
821
840
  var message=language['error']['loadingFailed'];
@@ -844,7 +863,7 @@
844
863
  video.attr('src',url);
845
864
  }
846
865
  };
847
- if(typeof Hls!=='undefined' && !isUndefined(Hls)){
866
+ if(typeof Hls!=='undefined' && !isUndefined(Hls) && !vars['preferBuiltinPlug']){
848
867
  startHls();
849
868
  return;
850
869
  }
@@ -887,7 +906,7 @@
887
906
  });
888
907
  }
889
908
  };
890
- if(typeof flvjs!=='undefined' && !isUndefined(flvjs)){
909
+ if(typeof flvjs!=='undefined' && !isUndefined(flvjs) && !vars['preferBuiltinPlug']){
891
910
  startFlv();
892
911
  return;
893
912
  }
@@ -931,7 +950,7 @@
931
950
  });
932
951
  }
933
952
  };
934
- if(typeof mpegts!=='undefined' && !isUndefined(mpegts)){
953
+ if(typeof mpegts!=='undefined' && !isUndefined(mpegts) && !vars['preferBuiltinPlug']){
935
954
  startMpegts();
936
955
  return;
937
956
  }
@@ -1582,6 +1601,36 @@
1582
1601
  }
1583
1602
  }
1584
1603
  },
1604
+ /*
1605
+ * applyPendingSeek
1606
+ * 功能:在媒体就绪后应用挂起的 seekTime
1607
+ */
1608
+ applyPendingSeek=function(){
1609
+ if(!seekTime || !video){
1610
+ return;
1611
+ }
1612
+ if(!isUndefined(vars['live']) && ((valType(vars['live'])=='boolean' && vars['live']) || valType(vars['live'])=='number')){
1613
+ return;
1614
+ }
1615
+ var t=seekTime;
1616
+ var dur=duration || video.duration || 0;
1617
+ if(dur && isFinite(dur) && dur>0 && t>=dur){
1618
+ t=Math.max(0,dur-0.3);
1619
+ }
1620
+ // 续播水位同步(mode=5 依赖 maxSeeTime)
1621
+ if(t>0){
1622
+ maxSeeTime=Math.max(maxSeeTime,t);
1623
+ if(firstSeekTime<0){
1624
+ firstSeekTime=t;
1625
+ }
1626
+ }
1627
+ seekTime=0;
1628
+ try{
1629
+ video.currentTime=t;
1630
+ }catch(event){
1631
+ seekTime=t;
1632
+ }
1633
+ },
1585
1634
  /*
1586
1635
  * loadedMetaData
1587
1636
  * 功能:获取元数据后执行的函数
@@ -1633,6 +1682,7 @@
1633
1682
  canPlay:function(){
1634
1683
  C['loading'].hide();
1635
1684
  eventTarget('canplay');
1685
+ applyPendingSeek();
1636
1686
  },
1637
1687
  loadedData:function(){
1638
1688
  eventTarget('loadeddata');
@@ -1662,6 +1712,7 @@
1662
1712
  if(CT.videoWidth || CT.videoHeight || duration){
1663
1713
  loadedMetaData();
1664
1714
  }
1715
+ applyPendingSeek();
1665
1716
  var len = 0;
1666
1717
  if(!isUndefined(this.buffered)){
1667
1718
  len=this.buffered.length;
@@ -1719,6 +1770,7 @@
1719
1770
  if(CT.videoWidth || CT.videoHeight || duration){
1720
1771
  loadedMetaData();
1721
1772
  }
1773
+ applyPendingSeek();
1722
1774
  }
1723
1775
  oldTime=playTime;
1724
1776
  playTime=this.currentTime;
@@ -1939,9 +1991,8 @@
1939
1991
  }
1940
1992
  }
1941
1993
  }
1942
- if(seekTime && (isUndefined(vars['live']) || (!isUndefined(vars['live']) && valType(vars['live'])=='boolean' && !vars['live'])) && seekTime<parseInt(duration*100)*0.01){//如果默认需要跳转,则进行seek
1943
- player.seek(seekTime);
1944
- seekTime=0;
1994
+ if(seekTime && (isUndefined(vars['live']) || (!isUndefined(vars['live']) && valType(vars['live'])=='boolean' && !vars['live']))){//如果默认需要跳转,则进行seek
1995
+ applyPendingSeek();
1945
1996
  }
1946
1997
  },
1947
1998
  pause:function(){
@@ -2797,52 +2848,98 @@
2797
2848
  /*
2798
2849
  * seek
2799
2850
  * 功能:监听跳转/执行跳转操作
2800
- * @fn为函数时则监听视频跳转动作,@fn为数字时执行跳转操作
2851
+ * @fn为函数时则监听视频跳转动作,@fn为数字(或数字字符串)时执行跳转操作
2801
2852
  */
2802
2853
  seek:function(fn){
2803
2854
  if(!isUndefined(fn)){
2804
2855
  if(valType(fn)=='function'){
2805
2856
  newEvent.addEventListener('seek',fn);
2806
2857
  }
2807
- if(valType(fn)=='number' && video){
2808
- switch(vars['timeScheduleAdjust']){
2809
- case 0://禁止拖动
2810
- message(language['timeScheduleAdjust']['prohibit']);
2811
- return;
2812
- break;
2813
- case 1://可以拖动
2814
- break;
2815
- case 2://只能前进(向右拖动
2816
- if(fn<oldTime){
2817
- message(language['timeScheduleAdjust']['prohibitBackOff']);
2818
- return;
2819
- }
2820
- break;
2821
- case 3://是只能后退
2822
- if(fn>oldTime){
2823
- message(language['timeScheduleAdjust']['prohibitForward']);
2824
- return;
2858
+ else{
2859
+ var target=null;
2860
+ if(valType(fn)=='number' && !isNaN(fn)){
2861
+ target=fn;
2862
+ }
2863
+ else if(valType(fn)=='string' && fn!=='' && fn!=='cookie' && !isNaN(parseFloat(fn))){
2864
+ target=parseFloat(fn);
2865
+ }
2866
+ if(target!==null && video){
2867
+ // 续播水位需在 timeScheduleAdjust 校验前同步,否则 mode=5 会把 seek 打回 0
2868
+ if(target>0 && ((seekTime && Math.abs(seekTime-target)<0.5) || (vars['seek'] && parseFloat(vars['seek'])>0 && Math.abs(parseFloat(vars['seek'])-target)<0.5))){
2869
+ maxSeeTime=Math.max(maxSeeTime,target);
2870
+ if(firstSeekTime<0){
2871
+ firstSeekTime=target;
2825
2872
  }
2826
- break;
2827
- case 4://只能前进但能回到第一次拖动时的位置
2828
- if(fn<firstSeekTime){
2829
- waitingMessage=false;
2830
- video.currentTime=firstSeekTime;
2831
- message(language['timeScheduleAdjust']['prohibitLookBack']);
2832
- return;
2873
+ }
2874
+ switch(vars['timeScheduleAdjust']){
2875
+ case 0://禁止拖动
2876
+ message(language['timeScheduleAdjust']['prohibit']);
2877
+ return player;
2878
+ case 1://可以拖动
2879
+ break;
2880
+ case 2://只能前进(向右拖动
2881
+ if(target<oldTime){
2882
+ message(language['timeScheduleAdjust']['prohibitBackOff']);
2883
+ return player;
2884
+ }
2885
+ break;
2886
+ case 3://是只能后退
2887
+ if(target>oldTime){
2888
+ message(language['timeScheduleAdjust']['prohibitForward']);
2889
+ return player;
2890
+ }
2891
+ break;
2892
+ case 4://只能前进但能回到第一次拖动时的位置
2893
+ if(target<firstSeekTime){
2894
+ waitingMessage=false;
2895
+ try{video.currentTime=firstSeekTime;}catch(event){}
2896
+ message(language['timeScheduleAdjust']['prohibitLookBack']);
2897
+ return player;
2898
+ }
2899
+ break;
2900
+ case 5://看过的地方可以随意拖动
2901
+ if(target>maxSeeTime){
2902
+ waitingMessage=false;
2903
+ try{video.currentTime=maxSeeTime;}catch(event){}
2904
+ message(language['timeScheduleAdjust']['prohibitForwardNotViewed']);
2905
+ return player;
2906
+ }
2907
+ break;
2908
+ }
2909
+ pSliderMouseDown=false;
2910
+ // 媒体未就绪时先记录,待 canplay/时长就绪后再应用
2911
+ var ready=video.readyState>=2 || (duration && isFinite(duration) && duration>0);
2912
+ if(!ready){
2913
+ seekTime=target;
2914
+ if(target>0){
2915
+ maxSeeTime=Math.max(maxSeeTime,target);
2916
+ if(firstSeekTime<0){
2917
+ firstSeekTime=target;
2918
+ }
2833
2919
  }
2834
- break;
2835
- case 5://看过的地方可以随意拖动
2836
- if(fn>maxSeeTime){
2837
- waitingMessage=false;
2838
- video.currentTime=maxSeeTime;
2839
- message(language['timeScheduleAdjust']['prohibitForwardNotViewed']);
2840
- return;
2920
+ try{video.currentTime=target;}catch(event){}
2921
+ return player;
2922
+ }
2923
+ if(duration && isFinite(duration) && duration>0 && target>duration){
2924
+ target=Math.max(0,duration-0.3);
2925
+ }
2926
+ if(target<0){
2927
+ target=0;
2928
+ }
2929
+ // API 续播:若水位仍低于目标且目标等于初始化 seek,抬高水位
2930
+ if(vars['timeScheduleAdjust']==5 && target>maxSeeTime && seekTime && Math.abs(seekTime-target)<0.5){
2931
+ maxSeeTime=Math.max(maxSeeTime,target);
2932
+ }
2933
+ try{
2934
+ video.currentTime=target;
2935
+ seekTime=0;
2936
+ if(target>maxSeeTime && vars['timeScheduleAdjust']!=5){
2937
+ maxSeeTime=target;
2841
2938
  }
2842
- break;
2939
+ }catch(event){
2940
+ seekTime=target;
2941
+ }
2843
2942
  }
2844
- pSliderMouseDown=false;
2845
- video.currentTime=fn;
2846
2943
  }
2847
2944
  }
2848
2945
  return player;