mirror of
https://github.com/zhw2590582/ArtPlayer.git
synced 2026-10-23 05:41:20 -08:00
fix(dash): [PKG-DASH-SEEK-01] recover paused boundary seeks in SDK 4.5.2
This commit is contained in:
1 parent
442e1dcc96
commit
30f646be97
22 files changed
+1725
-57
No files matched your search
@@ -1,4 +1,5 @@
|
||||
import type { Cleanup, Dash, SDKEventName } from './types'
|
||||
import { createSeekRecovery } from './seek-buffer'
|
||||
|
||||
interface Binding<Level extends object, Track extends object> {
|
||||
dash: Dash<Level, Track>
|
||||
@@ -108,6 +109,9 @@ export function observeSDK<Level extends object, Track extends object>(options:
|
||||
record.suspended = false
|
||||
schedule(record)
|
||||
}])
|
||||
const recoverSeek = createSeekRecovery(dash, () => active(record) && !record.suspended)
|
||||
if (recoverSeek)
|
||||
entries.push(['playbackSeeking', recoverSeek])
|
||||
entries.push(['playbackTimeUpdated', () => {
|
||||
if (!active(record) || record.suspended)
|
||||
return
|
||||
|
||||
@@ -0,0 +1,85 @@
|
||||
import type { Cleanup, Valid } from './types'
|
||||
|
||||
type MediaType = 'audio' | 'video'
|
||||
|
||||
interface BufferController {
|
||||
getRangeAt?: (time: number) => { end: number } | null
|
||||
getIsPruningInProgress?: () => boolean
|
||||
getAllRangesWithSafetyFactor?: (time: number) => unknown[]
|
||||
}
|
||||
|
||||
interface Stream {
|
||||
getProcessors?: () => {
|
||||
getType?: () => string
|
||||
getBufferController?: () => BufferController | null
|
||||
}[]
|
||||
}
|
||||
|
||||
interface LegacySDK {
|
||||
getVersion?: () => string
|
||||
getVideoElement?: () => { currentTime: number, seeking: boolean } | null
|
||||
getActiveStream?: () => Stream | null
|
||||
getDashMetrics?: () => {
|
||||
getCurrentBufferLevel?: (type: MediaType) => number
|
||||
addBufferLevel?: (type: MediaType, at: Date, level: 0) => void
|
||||
} | null
|
||||
}
|
||||
|
||||
export function createSeekRecovery(value: object, active: Valid): Cleanup | undefined {
|
||||
const sdk = value as LegacySDK
|
||||
try {
|
||||
if (typeof sdk.getVersion !== 'function' || sdk.getVersion() !== '4.5.2')
|
||||
return
|
||||
if (typeof sdk.getVideoElement !== 'function' || typeof sdk.getActiveStream !== 'function' || typeof sdk.getDashMetrics !== 'function')
|
||||
return
|
||||
}
|
||||
catch {
|
||||
return
|
||||
}
|
||||
let running = false
|
||||
return () => {
|
||||
if (running || !active())
|
||||
return
|
||||
running = true
|
||||
try {
|
||||
const video = sdk.getVideoElement?.()
|
||||
if (!video?.seeking || !Number.isFinite(video.currentTime))
|
||||
return
|
||||
const time = video.currentTime
|
||||
const stream = sdk.getActiveStream?.()
|
||||
const metrics = sdk.getDashMetrics?.()
|
||||
const processors = stream?.getProcessors?.()
|
||||
if (!Array.isArray(processors) || typeof metrics?.getCurrentBufferLevel !== 'function' || typeof metrics.addBufferLevel !== 'function')
|
||||
return
|
||||
for (const processor of processors) {
|
||||
if (!active())
|
||||
return
|
||||
const type = processor.getType?.()
|
||||
if (type !== 'audio' && type !== 'video')
|
||||
continue
|
||||
const buffer = processor.getBufferController?.()
|
||||
if (typeof buffer?.getRangeAt !== 'function' || typeof buffer.getIsPruningInProgress !== 'function' || typeof buffer.getAllRangesWithSafetyFactor !== 'function')
|
||||
continue
|
||||
const cached = metrics.getCurrentBufferLevel(type)
|
||||
const range = buffer.getRangeAt(time)
|
||||
const empty = range === null || (range && Number.isFinite(range.end) && range.end <= time)
|
||||
if (!Number.isFinite(cached) || cached <= 0 || !empty || buffer.getIsPruningInProgress() !== false)
|
||||
continue
|
||||
const removals = buffer.getAllRangesWithSafetyFactor(time)
|
||||
if (!Array.isArray(removals) || removals.length !== 0)
|
||||
continue
|
||||
if (!active() || sdk.getActiveStream?.() !== stream || sdk.getDashMetrics?.() !== metrics || sdk.getVideoElement?.() !== video || video.currentTime !== time || !video.seeking || !active())
|
||||
return
|
||||
// SDK 4.5.2 schedules from metric history, not BufferController's getter.
|
||||
// Record the measured empty range; leave buffers, media events and time intact.
|
||||
metrics.addBufferLevel(type, new Date(), 0)
|
||||
}
|
||||
}
|
||||
catch (error) {
|
||||
console.warn('ArtPlayer DASH seek buffer refresh failed:', error)
|
||||
}
|
||||
finally {
|
||||
running = false
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5,7 +5,7 @@ export type Identifier = string | number
|
||||
export type Valid = () => boolean
|
||||
export type Cleanup = () => void
|
||||
export type EventName = 'ready' | 'restart' | 'destroy'
|
||||
export type SDKEventName = 'qualityChangeRequested' | 'qualityChangeRendered' | 'trackChangeRendered' | 'streamUpdated' | 'streamInitialized' | 'playbackTimeUpdated' | 'streamTeardownComplete'
|
||||
export type SDKEventName = 'qualityChangeRequested' | 'qualityChangeRendered' | 'trackChangeRendered' | 'streamUpdated' | 'streamInitialized' | 'playbackTimeUpdated' | 'playbackSeeking' | 'streamTeardownComplete'
|
||||
|
||||
export interface QualityFields {
|
||||
height?: number
|
||||
|
||||
Reference in new issue
Block a user