diff --git a/packages/xgplayer-hls/src/hls/index.js b/packages/xgplayer-hls/src/hls/index.js index caa5e8397..3362e6e00 100644 --- a/packages/xgplayer-hls/src/hls/index.js +++ b/packages/xgplayer-hls/src/hls/index.js @@ -470,10 +470,10 @@ export class Hls extends EventEmitter { */ _loadSegment = async () => { if (this._segmentProcessing || !this.media) return - const nextSeg = this._playlist.nextSegment + const { nextSegment } = this._playlist const { config } = this - if (!nextSeg) return + if (!nextSegment) return if (!this.isLive) { let bInfo = this.bufferInfo() @@ -492,9 +492,9 @@ export class Hls extends EventEmitter { // reset segment pointer by buffer end if (!this._urlSwitching && - this._prevSegSn !== nextSeg.sn - 1 && + this._prevSegSn !== nextSegment.sn - 1 && bInfo.end && - Math.abs(nextSeg.start - bInfo.end) > 1) { + Math.abs(nextSegment.start - bInfo.end) > 1) { this._playlist.setNextSegmentByIndex(this._playlist.findSegmentIndexByTime(bInfo.end + 0.1)) } } @@ -916,7 +916,11 @@ export class Hls extends EventEmitter { const { media } = this const { nextSegment, lastSegment } = this._playlist const eosAllowed = - !nextSegment && + (!nextSegment || + (lastSegment && + // Use the mid-time of lastSegment to determine + // whether the Media Buffer has been buffered to the end + Buffer.isBuffered(media, lastSegment.start + lastSegment.duration / 2))) && media.readyState && media.duration > 0 && this._bufferService?.msIsOpened && diff --git a/packages/xgplayer-streaming-shared/src/buffer.js b/packages/xgplayer-streaming-shared/src/buffer.js index d196d1eb3..dcfdd54f3 100644 --- a/packages/xgplayer-streaming-shared/src/buffer.js +++ b/packages/xgplayer-streaming-shared/src/buffer.js @@ -130,4 +130,25 @@ export class Buffer { length: Buffer.totalLength && Buffer.totalLength(buffers) } } + + /** + * + * @param {HTMLMediaElement} media + * @param {number} pos + * @returns {Boolean} + */ + static isBuffered (media, pos) { + if (media) { + const buffered = Buffer.get(media) + + if (buffered?.length) { + for (let i = 0; i < buffered.length; i++) { + if (pos >= buffered.start(i) && pos <= buffered.end(i)) { + return true + } + } + } + } + return false + } }