ckplayer-plus 1.0.8 → 1.1.1
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/README.md +3 -1
- package/dist/ckplayer.js +226 -59
- package/dist/ckplayer.min.js +2 -2
- package/dist/index.cjs +583 -458
- package/dist/index.js +582 -458
- package/dist/mpegts.js/LICENSE +202 -0
- package/dist/react.cjs +602 -464
- package/dist/react.js +601 -464
- package/dist/vue.cjs +586 -458
- package/dist/vue.js +585 -458
- package/package.json +9 -2
- package/types/vue.d.ts +1 -1
package/README.md
CHANGED
|
@@ -108,7 +108,7 @@ React:
|
|
|
108
108
|
|
|
109
109
|
```vue
|
|
110
110
|
<template>
|
|
111
|
-
<CkPlayer :video="url" poster="/poster.png" height="400px" @play="onPlay" />
|
|
111
|
+
<CkPlayer :video="url" :seek="16" poster="/poster.png" height="400px" @play="onPlay" />
|
|
112
112
|
</template>
|
|
113
113
|
|
|
114
114
|
<script>
|
|
@@ -125,6 +125,8 @@ export default {
|
|
|
125
125
|
</script>
|
|
126
126
|
```
|
|
127
127
|
|
|
128
|
+
断点续播:`seek` 用 `:seek` 或 `options.seek` 在创建时传入;**不要**在 `@ready` 里再 `player.seek(16)`,否则会重复加载 HLS、取消 `.ts` 分片导致卡住。
|
|
129
|
+
|
|
128
130
|
SSR(Nuxt 等)请用 `<ClientOnly>`,仅在浏览器初始化。
|
|
129
131
|
|
|
130
132
|
## React
|
package/dist/ckplayer.js
CHANGED
|
@@ -93,7 +93,7 @@
|
|
|
93
93
|
backLive:false,//显示返回直播按钮
|
|
94
94
|
seek: 0,//默认需要跳转的秒数
|
|
95
95
|
next: null,//下一集按钮动作
|
|
96
|
-
loaded:
|
|
96
|
+
loaded: null,//加载播放器后调用的函数(仅支持 function)
|
|
97
97
|
plug: '',//使用插件
|
|
98
98
|
duration:0,//视频总时间
|
|
99
99
|
preview: null,//预览图片对象
|
|
@@ -141,7 +141,7 @@
|
|
|
141
141
|
cdnFallback:true// getPath 失败时是否回退到 jsDelivr(内网可设 false,并配置 pluginPath)
|
|
142
142
|
};
|
|
143
143
|
// 打包时替换为真实版本;用于 bundler 下 getPath 失效时的 CDN 回退
|
|
144
|
-
var ckplayerPlusDefaultCdn='https://cdn.jsdelivr.net/npm/ckplayer-plus@1.
|
|
144
|
+
var ckplayerPlusDefaultCdn='https://cdn.jsdelivr.net/npm/ckplayer-plus@1.1.1/dist/';
|
|
145
145
|
function ckplayerEmbed(videoObj){
|
|
146
146
|
/*
|
|
147
147
|
* rightMenu
|
|
@@ -174,9 +174,11 @@
|
|
|
174
174
|
var seekRetryTimer=null;//续播等待缓冲的重试计时器
|
|
175
175
|
var seekRetryCount=0;//续播重试次数
|
|
176
176
|
var seekApplyLock=false;//防止并发多次 currentTime 赋值
|
|
177
|
+
var autoplayPending=false;//自动播放必须等初始化续播完成后才触发
|
|
177
178
|
var decodeRecoverCount=0;//MEDIA_ERR_DECODE 恢复次数
|
|
178
179
|
var hlsStartPositionUsed=false;//是否已用 hls.js startPosition 处理续播
|
|
179
180
|
var hlsResumeTarget=-1;//HLS 续播目标秒数(避免重复 startLoad 取消分片请求)
|
|
181
|
+
var hlsResumeWarmup=false;//HLS 续播先预热首个可解码分片,再定位目标时间
|
|
180
182
|
var hlsLoadAt=-1;//最近一次 hls.startLoad 目标
|
|
181
183
|
var hlsLoadTs=0;//最近一次 hls.startLoad 时间戳
|
|
182
184
|
var oldTime=0,playTime=0,firstSeekTime=-1,maxSeeTime=0;//oldTime=记录上次播放时间,playTime=当前播放时间,firstSeekTime=记录第一次拖动的时间,maxSeeTime=看过的最大时间
|
|
@@ -213,6 +215,33 @@
|
|
|
213
215
|
var cookieArray=[];//保存当前所有记录
|
|
214
216
|
var focusPause=true;//失去焦点前是否是暂停状态
|
|
215
217
|
var existenceObj=false;//是否使用源码里已有的dom
|
|
218
|
+
/*
|
|
219
|
+
* invokeGlobalFn
|
|
220
|
+
* 功能:安全调用全局函数名(替代 eval(name+'()')),仅允许合法标识符路径,避免任意代码执行
|
|
221
|
+
* @expr 形如 "fnName" 或 "a.b.c" 的全局函数名(可含尾随括号)
|
|
222
|
+
*/
|
|
223
|
+
function invokeGlobalFn(expr){
|
|
224
|
+
if(typeof expr!=='string'){
|
|
225
|
+
return;
|
|
226
|
+
}
|
|
227
|
+
var name=expr.replace(/\(\s*\)\s*;?\s*$/,'').trim();
|
|
228
|
+
if(!/^[A-Za-z_$][\w$]*(\.[A-Za-z_$][\w$]*)*$/.test(name)){
|
|
229
|
+
return;
|
|
230
|
+
}
|
|
231
|
+
var parts=name.split('.');
|
|
232
|
+
var ctx=(typeof window!=='undefined')?window:this;
|
|
233
|
+
var fn=ctx;
|
|
234
|
+
for(var i=0;i<parts.length;i++){
|
|
235
|
+
if(fn==null){
|
|
236
|
+
return;
|
|
237
|
+
}
|
|
238
|
+
ctx=fn;
|
|
239
|
+
fn=fn[parts[i]];
|
|
240
|
+
}
|
|
241
|
+
if(typeof fn==='function'){
|
|
242
|
+
return fn.call(ctx);
|
|
243
|
+
}
|
|
244
|
+
}
|
|
216
245
|
/*
|
|
217
246
|
* into
|
|
218
247
|
* 功能:初始化,调用播放器则首先调用该函数
|
|
@@ -417,7 +446,7 @@
|
|
|
417
446
|
}
|
|
418
447
|
var allowCdn=!vars || vars['cdnFallback']!==false;
|
|
419
448
|
var cdn=(typeof window!=='undefined' && window.ckplayerPlusCdn) ? window.ckplayerPlusCdn : ckplayerPlusDefaultCdn;
|
|
420
|
-
if(!allowCdn || !cdn || cdn.indexOf('1.
|
|
449
|
+
if(!allowCdn || !cdn || cdn.indexOf('1.1.1')>-1){
|
|
421
450
|
// 避免占位版本或显式关闭 CDN 时请求坏地址;交给相对路径或业务 pluginPath
|
|
422
451
|
return folder+'/'+file;
|
|
423
452
|
}
|
|
@@ -562,8 +591,10 @@
|
|
|
562
591
|
player.volume(0);
|
|
563
592
|
player.muted();
|
|
564
593
|
recoveryVolume=true;
|
|
565
|
-
|
|
566
|
-
|
|
594
|
+
// 不使用原生 autoplay 属性:浏览器会在 seek 前开始 play,随后
|
|
595
|
+
// currentTime / pause 等初始化动作会打断其 Promise,导致永久 loading。
|
|
596
|
+
video.attr('preload','auto');
|
|
597
|
+
autoplayPending=true;
|
|
567
598
|
}
|
|
568
599
|
else{
|
|
569
600
|
video.attr('preload','metadata');
|
|
@@ -783,6 +814,7 @@
|
|
|
783
814
|
seekApplyLock=false;
|
|
784
815
|
hlsStartPositionUsed=false;
|
|
785
816
|
hlsResumeTarget=-1;
|
|
817
|
+
hlsResumeWarmup=false;
|
|
786
818
|
hlsLoadAt=-1;
|
|
787
819
|
hlsLoadTs=0;
|
|
788
820
|
decodeRecoverCount=0;
|
|
@@ -958,29 +990,43 @@
|
|
|
958
990
|
if(!resumeAt){
|
|
959
991
|
resumeAt=parseResumeSeekFromVars();
|
|
960
992
|
}
|
|
961
|
-
//
|
|
993
|
+
// 部分旧 HLS 的分片不从关键帧开始。直接以续播点 startPosition / startLoad(target)
|
|
994
|
+
// 起播会触发 Chrome PIPELINE_ERROR_DECODE。策略:
|
|
995
|
+
// 1) 从目标前约一个分片开始加载,让前序关键帧进入缓冲
|
|
996
|
+
// 2) 等 hlsCanSafelySeekTo 后再写 currentTime
|
|
962
997
|
if(resumeAt && resumeAt>0 && (isUndefined(vars['live']) || !vars['live'])){
|
|
963
|
-
hlsConf.startPosition=resumeAt;
|
|
964
998
|
maxSeeTime=Math.max(maxSeeTime,resumeAt);
|
|
965
999
|
if(firstSeekTime<0){
|
|
966
1000
|
firstSeekTime=resumeAt;
|
|
967
1001
|
}
|
|
1002
|
+
seekTime=resumeAt;
|
|
968
1003
|
hlsResumeTarget=resumeAt;
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
seekTime=0;
|
|
972
|
-
hlsStartPositionUsed=true;
|
|
973
|
-
clearSeekRetry();
|
|
1004
|
+
hlsResumeWarmup=true;
|
|
1005
|
+
hlsConf.startPosition=hlsPriorLoadTime(resumeAt);
|
|
974
1006
|
}
|
|
975
1007
|
hls = new Hls(hlsConf);
|
|
976
1008
|
hls.loadSource(url);
|
|
977
1009
|
hls.attachMedia(video);
|
|
978
1010
|
hls.on(Hls.Events.MANIFEST_PARSED, function(){
|
|
1011
|
+
if(hlsResumeWarmup && seekTime>0){
|
|
1012
|
+
try{
|
|
1013
|
+
hls.startLoad(hlsPriorLoadTime(seekTime));
|
|
1014
|
+
}catch(event){}
|
|
1015
|
+
return;
|
|
1016
|
+
}
|
|
979
1017
|
if(!hlsStartPositionUsed){
|
|
980
1018
|
applyPendingSeek();
|
|
981
1019
|
}
|
|
982
1020
|
});
|
|
983
1021
|
hls.on(Hls.Events.FRAG_BUFFERED, function(event, data){
|
|
1022
|
+
if(hlsResumeWarmup && seekTime>0){
|
|
1023
|
+
// 必须等「目标 + 前序分片」都在同一连续缓冲里,再定位
|
|
1024
|
+
if(hlsCanSafelySeekTo(seekTime)){
|
|
1025
|
+
hlsResumeWarmup=false;
|
|
1026
|
+
applySeekToMedia(seekTime);
|
|
1027
|
+
}
|
|
1028
|
+
return;
|
|
1029
|
+
}
|
|
984
1030
|
if(hlsResumeTarget<=0 || !data || !data.frag){
|
|
985
1031
|
return;
|
|
986
1032
|
}
|
|
@@ -1787,6 +1833,38 @@
|
|
|
1787
1833
|
}catch(event){}
|
|
1788
1834
|
return false;
|
|
1789
1835
|
},
|
|
1836
|
+
/*
|
|
1837
|
+
* hlsPriorLoadTime
|
|
1838
|
+
* 功能:续播加载起点——至少回退约一个分片,保证目标分片前仍有关键帧可参考
|
|
1839
|
+
*/
|
|
1840
|
+
hlsPriorLoadTime=function(t){
|
|
1841
|
+
if(isNaN(t) || t<=0){
|
|
1842
|
+
return 0;
|
|
1843
|
+
}
|
|
1844
|
+
return Math.max(0,t-12);
|
|
1845
|
+
},
|
|
1846
|
+
/*
|
|
1847
|
+
* hlsCanSafelySeekTo
|
|
1848
|
+
* 功能:目标已缓冲,且同一连续缓冲区间覆盖目标前约一个分片
|
|
1849
|
+
* 部分旧 TS 分片首帧不是关键帧;若只缓冲目标分片就 seek,Chrome 会报 PIPELINE_ERROR_DECODE
|
|
1850
|
+
*/
|
|
1851
|
+
hlsCanSafelySeekTo=function(t){
|
|
1852
|
+
if(!video || isUndefined(video.buffered) || isNaN(t) || t<0){
|
|
1853
|
+
return false;
|
|
1854
|
+
}
|
|
1855
|
+
try{
|
|
1856
|
+
var buf=video.buffered;
|
|
1857
|
+
var needFrom=hlsPriorLoadTime(t);
|
|
1858
|
+
for(var i=0;i<buf.length;i++){
|
|
1859
|
+
var start=buf.start(i);
|
|
1860
|
+
var end=buf.end(i);
|
|
1861
|
+
if(t<=end+0.15 && needFrom>=start-0.35){
|
|
1862
|
+
return true;
|
|
1863
|
+
}
|
|
1864
|
+
}
|
|
1865
|
+
}catch(event){}
|
|
1866
|
+
return false;
|
|
1867
|
+
},
|
|
1790
1868
|
/*
|
|
1791
1869
|
* clearSeekRetry
|
|
1792
1870
|
* 功能:清理续播等待计时器
|
|
@@ -1798,6 +1876,35 @@
|
|
|
1798
1876
|
}
|
|
1799
1877
|
seekRetryCount=0;
|
|
1800
1878
|
},
|
|
1879
|
+
/*
|
|
1880
|
+
* startPendingAutoplay
|
|
1881
|
+
* 功能:续播定位完成后统一发起一次播放,避免 play/pause 竞态
|
|
1882
|
+
*/
|
|
1883
|
+
startPendingAutoplay=function(){
|
|
1884
|
+
if(!autoplayPending || !video || !vars['autoplay'] || seekTime || seekApplyLock || loadedmetadataNum<1){
|
|
1885
|
+
return;
|
|
1886
|
+
}
|
|
1887
|
+
autoplayPending=false;
|
|
1888
|
+
player.play();
|
|
1889
|
+
},
|
|
1890
|
+
/*
|
|
1891
|
+
* applySeekToMedia
|
|
1892
|
+
* 功能:仅对已建立解码管线的 media 元素写入 currentTime
|
|
1893
|
+
*/
|
|
1894
|
+
applySeekToMedia=function(t){
|
|
1895
|
+
clearSeekRetry();
|
|
1896
|
+
seekApplyLock=true;
|
|
1897
|
+
seekTime=0;
|
|
1898
|
+
try{
|
|
1899
|
+
video.currentTime=t;
|
|
1900
|
+
}catch(event){
|
|
1901
|
+
seekTime=t;
|
|
1902
|
+
seekApplyLock=false;
|
|
1903
|
+
}
|
|
1904
|
+
setTimeout(function(){
|
|
1905
|
+
seekApplyLock=false;
|
|
1906
|
+
},800);
|
|
1907
|
+
},
|
|
1801
1908
|
/*
|
|
1802
1909
|
* applyPendingSeek
|
|
1803
1910
|
* 功能:在媒体就绪且目标时间可解码后再应用挂起的 seekTime
|
|
@@ -1826,15 +1933,44 @@
|
|
|
1826
1933
|
firstSeekTime=t;
|
|
1827
1934
|
}
|
|
1828
1935
|
}
|
|
1829
|
-
// HLS
|
|
1830
|
-
|
|
1831
|
-
|
|
1832
|
-
|
|
1936
|
+
// HLS 首分片尚未完成预热时不能直接 startLoad(target),否则某些
|
|
1937
|
+
// 非关键帧分片会让浏览器解码器永久报错。
|
|
1938
|
+
if(hlsResumeWarmup){
|
|
1939
|
+
if(hlsCanSafelySeekTo(t)){
|
|
1940
|
+
hlsResumeWarmup=false;
|
|
1941
|
+
applySeekToMedia(t);
|
|
1942
|
+
}
|
|
1833
1943
|
return;
|
|
1834
1944
|
}
|
|
1835
|
-
|
|
1836
|
-
|
|
1837
|
-
if(
|
|
1945
|
+
// HLS:用 hls.startLoad 从目标分片加载(去重,避免取消进行中的 .ts)
|
|
1946
|
+
// 若目标附近尚无前序缓冲,改为预热模式从更早处分片加载
|
|
1947
|
+
if(hls && typeof hls.startLoad==='function'){
|
|
1948
|
+
if(!hlsCanSafelySeekTo(t) && t>1){
|
|
1949
|
+
hlsResumeWarmup=true;
|
|
1950
|
+
hlsResumeTarget=t;
|
|
1951
|
+
try{
|
|
1952
|
+
hls.startLoad(hlsPriorLoadTime(t));
|
|
1953
|
+
}catch(event){}
|
|
1954
|
+
seekRetryCount++;
|
|
1955
|
+
if(seekRetryCount<=50){
|
|
1956
|
+
if(seekRetryTimer){
|
|
1957
|
+
clearTimeout(seekRetryTimer);
|
|
1958
|
+
}
|
|
1959
|
+
seekRetryTimer=setTimeout(function(){
|
|
1960
|
+
applyPendingSeek(false);
|
|
1961
|
+
},200);
|
|
1962
|
+
}
|
|
1963
|
+
return;
|
|
1964
|
+
}
|
|
1965
|
+
if(hlsSeekTo(t, !!force)){
|
|
1966
|
+
clearSeekRetry();
|
|
1967
|
+
seekTime=0;
|
|
1968
|
+
return;
|
|
1969
|
+
}
|
|
1970
|
+
}
|
|
1971
|
+
// 对普通 MP4,metadata 后设置 currentTime 会由浏览器自动请求目标 Range。
|
|
1972
|
+
// 等待目标已缓冲会形成循环等待:目标分片只有 seek 后才会下载。
|
|
1973
|
+
if(!force && (!isUndefined(video.readyState) && video.readyState<1)){
|
|
1838
1974
|
seekRetryCount++;
|
|
1839
1975
|
if(seekRetryCount<=50){
|
|
1840
1976
|
if(seekRetryTimer){
|
|
@@ -1846,49 +1982,57 @@
|
|
|
1846
1982
|
return;
|
|
1847
1983
|
}
|
|
1848
1984
|
}
|
|
1849
|
-
|
|
1850
|
-
seekApplyLock=true;
|
|
1851
|
-
seekTime=0;
|
|
1852
|
-
try{
|
|
1853
|
-
video.currentTime=t;
|
|
1854
|
-
}catch(event){
|
|
1855
|
-
seekTime=t;
|
|
1856
|
-
seekApplyLock=false;
|
|
1857
|
-
}
|
|
1858
|
-
setTimeout(function(){
|
|
1859
|
-
seekApplyLock=false;
|
|
1860
|
-
},800);
|
|
1985
|
+
applySeekToMedia(t);
|
|
1861
1986
|
},
|
|
1862
1987
|
/*
|
|
1863
1988
|
* recoverDecodeError
|
|
1864
1989
|
* 功能:断点续播触发的解码错误尝试恢复(Chrome PIPELINE_ERROR_DECODE)
|
|
1990
|
+
* 典型场景:目标 TS 分片首帧不是关键帧,必须回退加载前序分片再建解码管线
|
|
1865
1991
|
*/
|
|
1866
1992
|
recoverDecodeError=function(){
|
|
1867
|
-
if(decodeRecoverCount>=
|
|
1993
|
+
if(decodeRecoverCount>=3){
|
|
1868
1994
|
return false;
|
|
1869
1995
|
}
|
|
1870
1996
|
decodeRecoverCount++;
|
|
1871
|
-
var resumeAt=playTime>0?playTime:(vars['seek']?parseFloat(vars['seek']):0);
|
|
1997
|
+
var resumeAt=hlsResumeTarget>0?hlsResumeTarget:(playTime>0?playTime:(vars['seek']?parseFloat(vars['seek']):0));
|
|
1872
1998
|
if(isNaN(resumeAt) || resumeAt<0){
|
|
1873
1999
|
resumeAt=0;
|
|
1874
2000
|
}
|
|
2001
|
+
// 每次失败再往前多退一个分片,避免反复落到同一坏点
|
|
2002
|
+
var loadFrom=Math.max(0,resumeAt-(12*decodeRecoverCount));
|
|
2003
|
+
seekApplyLock=false;
|
|
2004
|
+
clearSeekRetry();
|
|
1875
2005
|
try{
|
|
1876
2006
|
if(hls && typeof hls.recoverMediaError==='function'){
|
|
1877
2007
|
hls.recoverMediaError();
|
|
1878
|
-
if(resumeAt>0){
|
|
1879
|
-
seekTime=resumeAt;
|
|
1880
|
-
seekApplyLock=false;
|
|
1881
|
-
setTimeout(function(){
|
|
1882
|
-
applyPendingSeek(true);
|
|
1883
|
-
},300);
|
|
1884
|
-
}
|
|
1885
|
-
return true;
|
|
1886
2008
|
}
|
|
1887
2009
|
}catch(event){}
|
|
2010
|
+
if(resumeAt>0 && hls && typeof hls.startLoad==='function'){
|
|
2011
|
+
seekTime=resumeAt;
|
|
2012
|
+
hlsResumeTarget=resumeAt;
|
|
2013
|
+
hlsResumeWarmup=true;
|
|
2014
|
+
hlsLoadAt=-1;
|
|
2015
|
+
hlsLoadTs=0;
|
|
2016
|
+
try{
|
|
2017
|
+
hls.startLoad(loadFrom);
|
|
2018
|
+
}catch(event){}
|
|
2019
|
+
setTimeout(function(){
|
|
2020
|
+
if(hlsCanSafelySeekTo(resumeAt)){
|
|
2021
|
+
hlsResumeWarmup=false;
|
|
2022
|
+
applySeekToMedia(resumeAt);
|
|
2023
|
+
if(video && video.paused && vars['autoplay']){
|
|
2024
|
+
try{video.play();}catch(e2){}
|
|
2025
|
+
}
|
|
2026
|
+
}
|
|
2027
|
+
else{
|
|
2028
|
+
applyPendingSeek(false);
|
|
2029
|
+
}
|
|
2030
|
+
},500);
|
|
2031
|
+
return true;
|
|
2032
|
+
}
|
|
1888
2033
|
try{
|
|
1889
2034
|
var soft=Math.max(0,resumeAt-1.5);
|
|
1890
2035
|
seekTime=resumeAt;
|
|
1891
|
-
seekApplyLock=false;
|
|
1892
2036
|
if(video){
|
|
1893
2037
|
video.currentTime=soft;
|
|
1894
2038
|
}
|
|
@@ -1954,6 +2098,7 @@
|
|
|
1954
2098
|
C['loading'].hide();
|
|
1955
2099
|
eventTarget('canplay');
|
|
1956
2100
|
applyPendingSeek();
|
|
2101
|
+
startPendingAutoplay();
|
|
1957
2102
|
},
|
|
1958
2103
|
loadedData:function(){
|
|
1959
2104
|
eventTarget('loadeddata');
|
|
@@ -2009,6 +2154,7 @@
|
|
|
2009
2154
|
}
|
|
2010
2155
|
pSliderMouseDown=false;
|
|
2011
2156
|
loadedmetadataNum++;
|
|
2157
|
+
startPendingAutoplay();
|
|
2012
2158
|
if(!isUndefined(ad) && !isUndefined(ad['frontPlay']) && ad['frontPlay'] && loadedmetadataNum>1){//如果是贴片广告播放中,则进行播放和计算
|
|
2013
2159
|
player.play();
|
|
2014
2160
|
calculationAdFrontTime(duration);//计算贴片广告的时间
|
|
@@ -2092,10 +2238,8 @@
|
|
|
2092
2238
|
if(!isUndefined(errorInfo.message)){
|
|
2093
2239
|
msg=errorInfo.message;
|
|
2094
2240
|
}
|
|
2095
|
-
// code=3 MEDIA_ERR_DECODE
|
|
2241
|
+
// code=3 MEDIA_ERR_DECODE:续播非关键帧常见,先尝试恢复;恢复中不向业务抛致命 error
|
|
2096
2242
|
if(code===3 && recoverDecodeError()){
|
|
2097
|
-
CT.error={code:code,message:msg};
|
|
2098
|
-
eventTarget('error',CT.error);
|
|
2099
2243
|
return;
|
|
2100
2244
|
}
|
|
2101
2245
|
CT.error={code:code,message:msg};
|
|
@@ -2139,8 +2283,8 @@
|
|
|
2139
2283
|
},
|
|
2140
2284
|
stalled:function(){
|
|
2141
2285
|
eventTarget('stalled');//注册监听error
|
|
2142
|
-
|
|
2143
|
-
|
|
2286
|
+
// HLS 在切片预热、切换清晰度时会短暂触发 stalled,属于可恢复缓冲。
|
|
2287
|
+
// 不把它上报为致命 error,避免业务侧误判已失败而覆盖正常播放状态。
|
|
2144
2288
|
},
|
|
2145
2289
|
suspend:function(){
|
|
2146
2290
|
eventTarget('suspend');//注册监听error
|
|
@@ -2153,9 +2297,7 @@
|
|
|
2153
2297
|
seeked:function(){
|
|
2154
2298
|
seekApplyLock=false;
|
|
2155
2299
|
decodeRecoverCount=0;
|
|
2156
|
-
|
|
2157
|
-
player.play();
|
|
2158
|
-
}
|
|
2300
|
+
startPendingAutoplay();
|
|
2159
2301
|
pSliderMouseDown=false;
|
|
2160
2302
|
eventTarget('seek',{time:this.currentTime,state:'seeked'});
|
|
2161
2303
|
eventTarget('seeked');
|
|
@@ -2711,7 +2853,7 @@
|
|
|
2711
2853
|
}
|
|
2712
2854
|
else if(valType(ad['front']['closeButtonClick'])=='string'){
|
|
2713
2855
|
try{
|
|
2714
|
-
|
|
2856
|
+
invokeGlobalFn(ad['front']['closeButtonClick']);
|
|
2715
2857
|
}
|
|
2716
2858
|
catch(event){console.error(event);}
|
|
2717
2859
|
}
|
|
@@ -3027,7 +3169,14 @@
|
|
|
3027
3169
|
}
|
|
3028
3170
|
else{
|
|
3029
3171
|
if(loadedmetadataNum>0 && video){
|
|
3030
|
-
try{
|
|
3172
|
+
try{
|
|
3173
|
+
var playPromise=video.play();
|
|
3174
|
+
// play() 返回 Promise 时必须消费 rejection,避免 autoplay 策略或
|
|
3175
|
+
// 页面卸载造成未捕获异常;播放状态仍由原生事件同步。
|
|
3176
|
+
if(playPromise && typeof playPromise.catch==='function'){
|
|
3177
|
+
playPromise.catch(function(){});
|
|
3178
|
+
}
|
|
3179
|
+
}catch(event){}
|
|
3031
3180
|
}
|
|
3032
3181
|
}
|
|
3033
3182
|
return player;
|
|
@@ -3215,6 +3364,17 @@
|
|
|
3215
3364
|
applyPendingSeek(false);
|
|
3216
3365
|
return player;
|
|
3217
3366
|
}
|
|
3367
|
+
// HLS:无前序关键帧缓冲时禁止直接 startLoad(target)
|
|
3368
|
+
if(hls && target>1 && !hlsCanSafelySeekTo(target)){
|
|
3369
|
+
seekTime=target;
|
|
3370
|
+
hlsResumeWarmup=true;
|
|
3371
|
+
hlsResumeTarget=target;
|
|
3372
|
+
try{
|
|
3373
|
+
hls.startLoad(hlsPriorLoadTime(target));
|
|
3374
|
+
}catch(event){}
|
|
3375
|
+
applyPendingSeek(false);
|
|
3376
|
+
return player;
|
|
3377
|
+
}
|
|
3218
3378
|
if(hlsSeekTo(target, false)){
|
|
3219
3379
|
seekTime=0;
|
|
3220
3380
|
return player;
|
|
@@ -3608,7 +3768,7 @@
|
|
|
3608
3768
|
fun();
|
|
3609
3769
|
}
|
|
3610
3770
|
if(valType(fun)=='string'){
|
|
3611
|
-
|
|
3771
|
+
invokeGlobalFn(fun);
|
|
3612
3772
|
}
|
|
3613
3773
|
}
|
|
3614
3774
|
else{
|
|
@@ -3641,7 +3801,7 @@
|
|
|
3641
3801
|
fun();
|
|
3642
3802
|
}
|
|
3643
3803
|
if(valType(fun)=='string'){
|
|
3644
|
-
|
|
3804
|
+
invokeGlobalFn(fun);
|
|
3645
3805
|
}
|
|
3646
3806
|
}
|
|
3647
3807
|
else{
|
|
@@ -4201,7 +4361,7 @@
|
|
|
4201
4361
|
var a=createlJsLink(m['title']);
|
|
4202
4362
|
a.attr('data-click',m['click'].toString());
|
|
4203
4363
|
a.click(function(){
|
|
4204
|
-
|
|
4364
|
+
invokeGlobalFn($(this).attr('data-click'));
|
|
4205
4365
|
C['menu'].hide();
|
|
4206
4366
|
});
|
|
4207
4367
|
li.append(a);
|
|
@@ -4936,7 +5096,7 @@
|
|
|
4936
5096
|
vars['next']['click']();
|
|
4937
5097
|
}
|
|
4938
5098
|
else if(valType(vars['next']['click'])=='string'){
|
|
4939
|
-
|
|
5099
|
+
invokeGlobalFn(vars['next']['click']);
|
|
4940
5100
|
}
|
|
4941
5101
|
}
|
|
4942
5102
|
if('link' in vars['next']){
|
|
@@ -7034,7 +7194,7 @@
|
|
|
7034
7194
|
if(!isRetry && (!vars || vars['cdnFallback']!==false)){
|
|
7035
7195
|
var cdn=(typeof window!=='undefined' && window.ckplayerPlusCdn) ? window.ckplayerPlusCdn : ckplayerPlusDefaultCdn;
|
|
7036
7196
|
var m=String(file).match(/\/(hls\.js|flv\.js|mpegts\.js|language)\/([^/?#]+)(?:[?#].*)?$/i);
|
|
7037
|
-
if(cdn && cdn.indexOf('1.
|
|
7197
|
+
if(cdn && cdn.indexOf('1.1.1')===-1 && m){
|
|
7038
7198
|
if(cdn.slice(-1)!=='/'){
|
|
7039
7199
|
cdn+='/';
|
|
7040
7200
|
}
|
|
@@ -7204,7 +7364,14 @@
|
|
|
7204
7364
|
if (xhr.status === 200) {
|
|
7205
7365
|
if (obj.dataType === 'json') {
|
|
7206
7366
|
try {
|
|
7207
|
-
|
|
7367
|
+
var jsonData;
|
|
7368
|
+
try {
|
|
7369
|
+
jsonData = JSON.parse(xhr.responseText);
|
|
7370
|
+
}
|
|
7371
|
+
catch(parseErr) {
|
|
7372
|
+
jsonData = eval('(' + xhr.responseText + ')');
|
|
7373
|
+
}
|
|
7374
|
+
successFun(jsonData); //回调传递参数
|
|
7208
7375
|
}
|
|
7209
7376
|
catch(event) {
|
|
7210
7377
|
successFun(null);
|
|
@@ -7950,4 +8117,4 @@
|
|
|
7950
8117
|
}
|
|
7951
8118
|
}
|
|
7952
8119
|
return ckplayerEmbed;
|
|
7953
|
-
}));
|
|
8120
|
+
}));
|