Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 52 additions & 0 deletions packages/xgplayer-hls/__tests__/hls.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,58 @@ describe('Hls', () => {
expect(removeAllListeners).toHaveBeenCalled()
})

test('vod stops preloading when discontinuous buffered islands exceed preloadTime', async () => {
const hls = new Hls({ media, url: 'url', preloadTime: 30 })
const loadSegmentDirect = jest.spyOn(hls, '_loadSegmentDirect').mockImplementation(() => Promise.resolve())
const tryEos = jest.spyOn(hls, '_tryEos').mockImplementation(() => {})
hls._playlist.nextSegment = { sn: 4, start: 37.4, end: 46.6 }
hls._playlist.lastSegment = { duration: 9.2 }
Buffer.info = () => ({
start: 0,
end: 9.2,
index: 0,
nextStart: 9.4,
remaining: 9.2,
buffers: [
[0, 9.2],
[9.4, 18.6],
[18.8, 27.9],
[28.1, 37.3]
]
})

await hls._loadSegment()

expect(tryEos).toHaveBeenCalled()
expect(loadSegmentDirect).not.toHaveBeenCalled()
})

test('vod keeps loading when next segment starts at the next buffered island', async () => {
const hls = new Hls({ media, url: 'url', preloadTime: 30 })
const loadSegmentDirect = jest.spyOn(hls, '_loadSegmentDirect').mockImplementation(() => Promise.resolve())
const tryEos = jest.spyOn(hls, '_tryEos').mockImplementation(() => {})
hls._playlist.nextSegment = { sn: 1, start: 9.4, end: 18.6 }
hls._playlist.lastSegment = { duration: 9.2 }
Buffer.info = () => ({
start: 0,
end: 9.2,
index: 0,
nextStart: 9.4,
remaining: 9.2,
buffers: [
[0, 9.2],
[9.4, 18.6],
[18.8, 27.9],
[28.1, 37.3]
]
})

await hls._loadSegment()

expect(tryEos).not.toHaveBeenCalled()
expect(loadSegmentDirect).toHaveBeenCalled()
})

test('switchStream', async () => {
const hls = new Hls({ media })

Expand Down
20 changes: 19 additions & 1 deletion packages/xgplayer-hls/src/hls/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,23 @@ export class Hls extends EventEmitter {
return Buffer.info(Buffer.get(this.media), this.media?.currentTime, maxHole)
}

_getPreloadBufferLength (bInfo, nextSegment) {
const remaining = bInfo?.remaining || 0
const buffers = bInfo?.buffers
const nextStart = bInfo?.nextStart
if (!buffers?.length || !nextSegment || !nextStart || nextSegment.start <= nextStart) return remaining

let fullBufferLength = remaining
const bufferedIndex = bInfo.end ? bInfo.index : -1
for (let i = buffers.length - 1; i > bufferedIndex; i--) {
const item = buffers[i]
if (item[0] < nextSegment.start) {
fullBufferLength += item[1] - item[0]
}
}
return fullBufferLength
}

/**
* @returns {Stats}
*/
Expand Down Expand Up @@ -520,8 +537,9 @@ export class Hls extends EventEmitter {
bInfo = this.bufferInfo(bInfo.nextStart || 0.5)
}
const bufferThroughout = Math.abs(bInfo.end - this.media.duration) < maxBufferThroughout
const preloadBufferLength = this._getPreloadBufferLength(bInfo, nextSegment)
// Only stop loading if we've buffered enough preload time or reached end AND all segments are loaded
if (bInfo.remaining >= config.preloadTime || (bufferThroughout && !nextSegment)) {
if (preloadBufferLength >= config.preloadTime || (bufferThroughout && !nextSegment)) {
this._tryEos()
return
}
Expand Down
Loading