ckplayer-plus 1.1.1 → 1.1.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.js +116 -46
- package/dist/ckplayer.min.js +2 -2
- package/dist/index.cjs +98 -38
- package/dist/index.js +98 -38
- package/dist/react.cjs +98 -38
- package/dist/react.js +98 -38
- package/dist/vue.cjs +98 -38
- package/dist/vue.js +98 -38
- package/package.json +1 -1
package/dist/ckplayer.js
CHANGED
|
@@ -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.1.
|
|
144
|
+
var ckplayerPlusDefaultCdn='https://cdn.jsdelivr.net/npm/ckplayer-plus@1.1.2/dist/';
|
|
145
145
|
function ckplayerEmbed(videoObj){
|
|
146
146
|
/*
|
|
147
147
|
* rightMenu
|
|
@@ -446,7 +446,7 @@
|
|
|
446
446
|
}
|
|
447
447
|
var allowCdn=!vars || vars['cdnFallback']!==false;
|
|
448
448
|
var cdn=(typeof window!=='undefined' && window.ckplayerPlusCdn) ? window.ckplayerPlusCdn : ckplayerPlusDefaultCdn;
|
|
449
|
-
if(!allowCdn || !cdn || cdn.indexOf('1.1.
|
|
449
|
+
if(!allowCdn || !cdn || cdn.indexOf('1.1.2')>-1){
|
|
450
450
|
// 避免占位版本或显式关闭 CDN 时请求坏地址;交给相对路径或业务 pluginPath
|
|
451
451
|
return folder+'/'+file;
|
|
452
452
|
}
|
|
@@ -990,10 +990,8 @@
|
|
|
990
990
|
if(!resumeAt){
|
|
991
991
|
resumeAt=parseResumeSeekFromVars();
|
|
992
992
|
}
|
|
993
|
-
//
|
|
994
|
-
//
|
|
995
|
-
// 1) 从目标前约一个分片开始加载,让前序关键帧进入缓冲
|
|
996
|
-
// 2) 等 hlsCanSafelySeekTo 后再写 currentTime
|
|
993
|
+
// HLS 续播:不要用精确秒数做 startPosition(易在分片中部起播导致解码失败/永久 loading)。
|
|
994
|
+
// 对齐目标分片起点加载,等分片从起点缓冲到目标后再一次 currentTime,并强制 play。
|
|
997
995
|
if(resumeAt && resumeAt>0 && (isUndefined(vars['live']) || !vars['live'])){
|
|
998
996
|
maxSeeTime=Math.max(maxSeeTime,resumeAt);
|
|
999
997
|
if(firstSeekTime<0){
|
|
@@ -1002,16 +1000,28 @@
|
|
|
1002
1000
|
seekTime=resumeAt;
|
|
1003
1001
|
hlsResumeTarget=resumeAt;
|
|
1004
1002
|
hlsResumeWarmup=true;
|
|
1005
|
-
hlsConf.startPosition=hlsPriorLoadTime(resumeAt);
|
|
1006
1003
|
}
|
|
1007
1004
|
hls = new Hls(hlsConf);
|
|
1008
1005
|
hls.loadSource(url);
|
|
1009
1006
|
hls.attachMedia(video);
|
|
1010
1007
|
hls.on(Hls.Events.MANIFEST_PARSED, function(){
|
|
1011
1008
|
if(hlsResumeWarmup && seekTime>0){
|
|
1009
|
+
var loadAt=hlsPriorLoadTime(seekTime);
|
|
1012
1010
|
try{
|
|
1013
|
-
hls.startLoad(
|
|
1011
|
+
hls.startLoad(loadAt);
|
|
1014
1012
|
}catch(event){}
|
|
1013
|
+
// 超时兜底:仍未定位则对齐分片起点起播,避免一直转圈
|
|
1014
|
+
setTimeout(function(){
|
|
1015
|
+
if(!hlsResumeWarmup || !seekTime){return;}
|
|
1016
|
+
var target=seekTime;
|
|
1017
|
+
if(hlsCanSafelySeekTo(target)){
|
|
1018
|
+
finishResumeSeek(target);
|
|
1019
|
+
return;
|
|
1020
|
+
}
|
|
1021
|
+
var snap=hlsPriorLoadTime(target);
|
|
1022
|
+
hlsResumeWarmup=false;
|
|
1023
|
+
finishResumeSeek(snap);
|
|
1024
|
+
},5000);
|
|
1015
1025
|
return;
|
|
1016
1026
|
}
|
|
1017
1027
|
if(!hlsStartPositionUsed){
|
|
@@ -1020,10 +1030,8 @@
|
|
|
1020
1030
|
});
|
|
1021
1031
|
hls.on(Hls.Events.FRAG_BUFFERED, function(event, data){
|
|
1022
1032
|
if(hlsResumeWarmup && seekTime>0){
|
|
1023
|
-
// 必须等「目标 + 前序分片」都在同一连续缓冲里,再定位
|
|
1024
1033
|
if(hlsCanSafelySeekTo(seekTime)){
|
|
1025
|
-
|
|
1026
|
-
applySeekToMedia(seekTime);
|
|
1034
|
+
finishResumeSeek(seekTime);
|
|
1027
1035
|
}
|
|
1028
1036
|
return;
|
|
1029
1037
|
}
|
|
@@ -1033,7 +1041,6 @@
|
|
|
1033
1041
|
var fragStart=data.frag.start;
|
|
1034
1042
|
var fragEnd=fragStart+data.frag.duration;
|
|
1035
1043
|
if(hlsResumeTarget>=fragStart-0.5 && hlsResumeTarget<=fragEnd+0.5){
|
|
1036
|
-
// 续播分片已进入缓冲,解除 waiting
|
|
1037
1044
|
if(!waited){
|
|
1038
1045
|
waited=true;
|
|
1039
1046
|
if(C['buffer']){
|
|
@@ -1833,38 +1840,109 @@
|
|
|
1833
1840
|
}catch(event){}
|
|
1834
1841
|
return false;
|
|
1835
1842
|
},
|
|
1843
|
+
/*
|
|
1844
|
+
* hlsFragAround
|
|
1845
|
+
* 功能:查找覆盖指定时间的 HLS 分片(用于对齐关键帧起点)
|
|
1846
|
+
*/
|
|
1847
|
+
hlsFragAround=function(t){
|
|
1848
|
+
if(!hls || isNaN(t) || t<0){
|
|
1849
|
+
return null;
|
|
1850
|
+
}
|
|
1851
|
+
try{
|
|
1852
|
+
var level=-1;
|
|
1853
|
+
if(typeof hls.currentLevel==='number' && hls.currentLevel>=0){
|
|
1854
|
+
level=hls.currentLevel;
|
|
1855
|
+
}
|
|
1856
|
+
else if(typeof hls.firstLevel==='number' && hls.firstLevel>=0){
|
|
1857
|
+
level=hls.firstLevel;
|
|
1858
|
+
}
|
|
1859
|
+
else{
|
|
1860
|
+
level=0;
|
|
1861
|
+
}
|
|
1862
|
+
var details=hls.levels && hls.levels[level] && hls.levels[level].details;
|
|
1863
|
+
var frags=details && details.fragments;
|
|
1864
|
+
if(!frags || !frags.length){
|
|
1865
|
+
return null;
|
|
1866
|
+
}
|
|
1867
|
+
for(var i=0;i<frags.length;i++){
|
|
1868
|
+
var f=frags[i];
|
|
1869
|
+
if(!f){continue;}
|
|
1870
|
+
var start=f.start||0;
|
|
1871
|
+
var end=start+(f.duration||0);
|
|
1872
|
+
if(t>=start-0.05 && t<end+0.05){
|
|
1873
|
+
return f;
|
|
1874
|
+
}
|
|
1875
|
+
}
|
|
1876
|
+
// 超出末片时回退最后一片
|
|
1877
|
+
return frags[frags.length-1];
|
|
1878
|
+
}catch(event){}
|
|
1879
|
+
return null;
|
|
1880
|
+
},
|
|
1836
1881
|
/*
|
|
1837
1882
|
* hlsPriorLoadTime
|
|
1838
|
-
*
|
|
1883
|
+
* 功能:续播加载起点——优先对齐目标分片起点(该流分片开头通常有 IDR)
|
|
1839
1884
|
*/
|
|
1840
1885
|
hlsPriorLoadTime=function(t){
|
|
1841
1886
|
if(isNaN(t) || t<=0){
|
|
1842
1887
|
return 0;
|
|
1843
1888
|
}
|
|
1889
|
+
var frag=hlsFragAround(t);
|
|
1890
|
+
if(frag && !isUndefined(frag.start)){
|
|
1891
|
+
return Math.max(0,frag.start);
|
|
1892
|
+
}
|
|
1844
1893
|
return Math.max(0,t-12);
|
|
1845
1894
|
},
|
|
1846
1895
|
/*
|
|
1847
1896
|
* hlsCanSafelySeekTo
|
|
1848
|
-
*
|
|
1849
|
-
*
|
|
1897
|
+
* 功能:目标分片已从分片起点连续缓冲到目标点,才允许 currentTime
|
|
1898
|
+
* 避免分片未完整进入 MSE 时中途 seek 触发 PIPELINE_ERROR_DECODE / 永久 loading
|
|
1850
1899
|
*/
|
|
1851
1900
|
hlsCanSafelySeekTo=function(t){
|
|
1852
1901
|
if(!video || isUndefined(video.buffered) || isNaN(t) || t<0){
|
|
1853
1902
|
return false;
|
|
1854
1903
|
}
|
|
1904
|
+
if(!timeInBuffered(t)){
|
|
1905
|
+
return false;
|
|
1906
|
+
}
|
|
1907
|
+
var fragStart=hlsPriorLoadTime(t);
|
|
1908
|
+
// 同一连续区间需覆盖分片起点→目标
|
|
1855
1909
|
try{
|
|
1856
1910
|
var buf=video.buffered;
|
|
1857
|
-
var needFrom=hlsPriorLoadTime(t);
|
|
1858
1911
|
for(var i=0;i<buf.length;i++){
|
|
1859
1912
|
var start=buf.start(i);
|
|
1860
1913
|
var end=buf.end(i);
|
|
1861
|
-
if(t<=end+0.15
|
|
1914
|
+
if(fragStart>=start-0.35 && t<=end+0.15){
|
|
1862
1915
|
return true;
|
|
1863
1916
|
}
|
|
1864
1917
|
}
|
|
1865
1918
|
}catch(event){}
|
|
1866
1919
|
return false;
|
|
1867
1920
|
},
|
|
1921
|
+
/*
|
|
1922
|
+
* finishResumeSeek
|
|
1923
|
+
* 功能:完成续播定位并恢复播放(清除 loading 卡住)
|
|
1924
|
+
*/
|
|
1925
|
+
finishResumeSeek=function(t){
|
|
1926
|
+
hlsResumeWarmup=false;
|
|
1927
|
+
applySeekToMedia(t);
|
|
1928
|
+
// seeked 可能因解码抖动延迟;主动再拉一次播放,避免永久转圈
|
|
1929
|
+
setTimeout(function(){
|
|
1930
|
+
if(!video){return;}
|
|
1931
|
+
if(C['buffer']){
|
|
1932
|
+
C['buffer'].hide();
|
|
1933
|
+
}
|
|
1934
|
+
waited=true;
|
|
1935
|
+
if(vars['autoplay'] || autoplayPending){
|
|
1936
|
+
try{
|
|
1937
|
+
var p=video.play();
|
|
1938
|
+
if(p && typeof p.then==='function'){
|
|
1939
|
+
p.catch(function(){});
|
|
1940
|
+
}
|
|
1941
|
+
}catch(event){}
|
|
1942
|
+
autoplayPending=false;
|
|
1943
|
+
}
|
|
1944
|
+
},120);
|
|
1945
|
+
},
|
|
1868
1946
|
/*
|
|
1869
1947
|
* clearSeekRetry
|
|
1870
1948
|
* 功能:清理续播等待计时器
|
|
@@ -1933,17 +2011,14 @@
|
|
|
1933
2011
|
firstSeekTime=t;
|
|
1934
2012
|
}
|
|
1935
2013
|
}
|
|
1936
|
-
// HLS 首分片尚未完成预热时不能直接 startLoad(target)
|
|
1937
|
-
// 非关键帧分片会让浏览器解码器永久报错。
|
|
2014
|
+
// HLS 首分片尚未完成预热时不能直接 startLoad(target)
|
|
1938
2015
|
if(hlsResumeWarmup){
|
|
1939
2016
|
if(hlsCanSafelySeekTo(t)){
|
|
1940
|
-
|
|
1941
|
-
applySeekToMedia(t);
|
|
2017
|
+
finishResumeSeek(t);
|
|
1942
2018
|
}
|
|
1943
2019
|
return;
|
|
1944
2020
|
}
|
|
1945
|
-
// HLS:用 hls.startLoad
|
|
1946
|
-
// 若目标附近尚无前序缓冲,改为预热模式从更早处分片加载
|
|
2021
|
+
// HLS:用 hls.startLoad 从目标分片起点加载(去重,避免取消进行中的 .ts)
|
|
1947
2022
|
if(hls && typeof hls.startLoad==='function'){
|
|
1948
2023
|
if(!hlsCanSafelySeekTo(t) && t>1){
|
|
1949
2024
|
hlsResumeWarmup=true;
|
|
@@ -1998,8 +2073,11 @@
|
|
|
1998
2073
|
if(isNaN(resumeAt) || resumeAt<0){
|
|
1999
2074
|
resumeAt=0;
|
|
2000
2075
|
}
|
|
2001
|
-
//
|
|
2002
|
-
var loadFrom=
|
|
2076
|
+
// 优先对齐分片起点(有 IDR);多次失败再往前一片
|
|
2077
|
+
var loadFrom=hlsPriorLoadTime(resumeAt);
|
|
2078
|
+
if(decodeRecoverCount>=2){
|
|
2079
|
+
loadFrom=Math.max(0,loadFrom-10);
|
|
2080
|
+
}
|
|
2003
2081
|
seekApplyLock=false;
|
|
2004
2082
|
clearSeekRetry();
|
|
2005
2083
|
try{
|
|
@@ -2008,7 +2086,9 @@
|
|
|
2008
2086
|
}
|
|
2009
2087
|
}catch(event){}
|
|
2010
2088
|
if(resumeAt>0 && hls && typeof hls.startLoad==='function'){
|
|
2011
|
-
|
|
2089
|
+
// 第 3 次直接落到分片起点起播,保证能出画面
|
|
2090
|
+
var target=(decodeRecoverCount>=3)?loadFrom:resumeAt;
|
|
2091
|
+
seekTime=target;
|
|
2012
2092
|
hlsResumeTarget=resumeAt;
|
|
2013
2093
|
hlsResumeWarmup=true;
|
|
2014
2094
|
hlsLoadAt=-1;
|
|
@@ -2017,31 +2097,20 @@
|
|
|
2017
2097
|
hls.startLoad(loadFrom);
|
|
2018
2098
|
}catch(event){}
|
|
2019
2099
|
setTimeout(function(){
|
|
2020
|
-
if(hlsCanSafelySeekTo(
|
|
2021
|
-
|
|
2022
|
-
|
|
2023
|
-
|
|
2024
|
-
|
|
2025
|
-
}
|
|
2100
|
+
if(hlsCanSafelySeekTo(target)){
|
|
2101
|
+
finishResumeSeek(target);
|
|
2102
|
+
}
|
|
2103
|
+
else if(decodeRecoverCount>=2){
|
|
2104
|
+
finishResumeSeek(loadFrom);
|
|
2026
2105
|
}
|
|
2027
2106
|
else{
|
|
2028
2107
|
applyPendingSeek(false);
|
|
2029
2108
|
}
|
|
2030
|
-
},
|
|
2109
|
+
},600);
|
|
2031
2110
|
return true;
|
|
2032
2111
|
}
|
|
2033
2112
|
try{
|
|
2034
|
-
|
|
2035
|
-
seekTime=resumeAt;
|
|
2036
|
-
if(video){
|
|
2037
|
-
video.currentTime=soft;
|
|
2038
|
-
}
|
|
2039
|
-
setTimeout(function(){
|
|
2040
|
-
applyPendingSeek(true);
|
|
2041
|
-
if(video && video.paused && vars['autoplay']){
|
|
2042
|
-
try{video.play();}catch(e2){}
|
|
2043
|
-
}
|
|
2044
|
-
},400);
|
|
2113
|
+
finishResumeSeek(Math.max(0,resumeAt-1.5));
|
|
2045
2114
|
return true;
|
|
2046
2115
|
}catch(event){}
|
|
2047
2116
|
return false;
|
|
@@ -2303,7 +2372,8 @@
|
|
|
2303
2372
|
eventTarget('seeked');
|
|
2304
2373
|
},
|
|
2305
2374
|
seeking:function(){
|
|
2306
|
-
|
|
2375
|
+
// 续播预热/定位过程中不要抢先 play,否则会打断 play Promise 导致永久 loading
|
|
2376
|
+
if(paused && !seekApplyLock && !hlsResumeWarmup && !seekTime){
|
|
2307
2377
|
player.play();
|
|
2308
2378
|
}
|
|
2309
2379
|
var seekingTime=this.currentTime;
|
|
@@ -7194,7 +7264,7 @@
|
|
|
7194
7264
|
if(!isRetry && (!vars || vars['cdnFallback']!==false)){
|
|
7195
7265
|
var cdn=(typeof window!=='undefined' && window.ckplayerPlusCdn) ? window.ckplayerPlusCdn : ckplayerPlusDefaultCdn;
|
|
7196
7266
|
var m=String(file).match(/\/(hls\.js|flv\.js|mpegts\.js|language)\/([^/?#]+)(?:[?#].*)?$/i);
|
|
7197
|
-
if(cdn && cdn.indexOf('1.1.
|
|
7267
|
+
if(cdn && cdn.indexOf('1.1.2')===-1 && m){
|
|
7198
7268
|
if(cdn.slice(-1)!=='/'){
|
|
7199
7269
|
cdn+='/';
|
|
7200
7270
|
}
|