ow
This commit is contained in:
1 parent
3b2ee8523b
commit
b5d2a2ede0
17 files changed
+2061
-1484
No files matched your search
@@ -183,6 +183,13 @@ function attachHls(): void {
|
||||
hls.loadSource(url);
|
||||
hls.attachMedia(el);
|
||||
hls.on(Hls.Events.MANIFEST_PARSED, () => {
|
||||
// m3u8 清单解析完即有总时长:先取 level 的 totalDuration,再兜底读元素
|
||||
const d = Number(hls?.levels?.[0]?.totalDuration) || 0;
|
||||
if (d > 0 && isFinite(d)) {
|
||||
duration.value = d;
|
||||
} else {
|
||||
syncDuration();
|
||||
}
|
||||
if (pending != null) {
|
||||
el.currentTime = pending;
|
||||
}
|
||||
@@ -382,8 +389,24 @@ function onWaiting(): void {
|
||||
function onPlaying(): void {
|
||||
buffering.value = false;
|
||||
}
|
||||
function onCanplay(): void {
|
||||
function onCanplay(e: { detail?: { duration?: number } }): void {
|
||||
buffering.value = false;
|
||||
// 未点播放也先亮总时长:uni canplay 的 detail.duration(H5/App/小程序都有)
|
||||
const d = Number(e?.detail?.duration) || 0;
|
||||
if (d > 0 && isFinite(d)) {
|
||||
duration.value = d;
|
||||
return;
|
||||
}
|
||||
syncDuration();
|
||||
}
|
||||
/** H5 兜底:从内层 <video> 元素读 duration(loadedmetadata 后即可用) */
|
||||
function syncDuration(): void {
|
||||
// #ifdef H5
|
||||
const d = Number(getInnerVideo()?.duration) || 0;
|
||||
if (d > 0 && isFinite(d)) {
|
||||
duration.value = d;
|
||||
}
|
||||
// #endif
|
||||
}
|
||||
function onTimeUpdate(e: { detail: { currentTime: number; duration: number } }): void {
|
||||
// 画面在推进就说明已经播出来了,清掉缓冲转圈(uni video 的 playing/canplay 在 H5 不一定派发)
|
||||
@@ -392,12 +415,33 @@ function onTimeUpdate(e: { detail: { currentTime: number; duration: number } }):
|
||||
if (e.detail?.duration && isFinite(e.detail.duration)) {
|
||||
duration.value = e.detail.duration;
|
||||
}
|
||||
syncBuffer();
|
||||
}
|
||||
function onProgress(e: { detail: { buffered: number } }): void {
|
||||
const b = e.detail?.buffered;
|
||||
if (typeof b === "number") {
|
||||
bufferedRatio.value = Math.min(1, Math.max(bufferedRatio.value, b / 100));
|
||||
}
|
||||
syncBuffer();
|
||||
}
|
||||
/**
|
||||
* H5 校准缓冲条:原生 buffered 常留最后零点几秒不放(要播到才认),
|
||||
* 导致进度条尾部永远露出一截轨道底色、与缓冲条不重合;距结束 1s 内视为满缓冲。
|
||||
*/
|
||||
function syncBuffer(): void {
|
||||
// #ifdef H5
|
||||
const el = getInnerVideo();
|
||||
if (!el?.buffered?.length || !duration.value) {
|
||||
return;
|
||||
}
|
||||
let end = 0;
|
||||
for (let i = 0; i < el.buffered.length; i++) {
|
||||
end = Math.max(end, Number(el.buffered.end(i)) || 0);
|
||||
}
|
||||
if (end >= duration.value - 1) {
|
||||
bufferedRatio.value = 1;
|
||||
}
|
||||
// #endif
|
||||
}
|
||||
function onLoadedmetadata(e: { detail: { width: number; height: number } }): void {
|
||||
const w = e.detail?.width ?? 0;
|
||||
@@ -405,6 +449,8 @@ function onLoadedmetadata(e: { detail: { width: number; height: number } }): voi
|
||||
if (w && h) {
|
||||
landscape.value = w > h;
|
||||
}
|
||||
// 元数据就绪即可拿时长,不等播放(H5)
|
||||
syncDuration();
|
||||
if (pendingSeek != null) {
|
||||
ensureCtx();
|
||||
ctx?.seek(pendingSeek);
|
||||
|
||||
Reference in new issue
Block a user