Drop bad mp4 data (#7815)

* Drop bad mp4 data
https://github.com/video-dev/hls.js/issues/7811#issuecomment-4306170831

* Improve logging of empty segment/parts
This commit is contained in:
Rob Walch
2026-04-23 12:01:37 -07:00
committed by GitHub
parent 3e23c7dcd2
commit b1b6a765c2
3 changed files with 47 additions and 39 deletions
+3 -1
View File
@@ -2316,7 +2316,9 @@ export default class BaseStreamController
}
if (mediaNotFound) {
const error = new Error(
`Found no media in fragment ${frag.sn} of ${this.playlistLabel()} ${frag.level} resetting transmuxer to fallback to playlist timing`,
`Found no media in ${this.playlistLabel()} ${frag.level} ${
part ? `part: ${part.index} of ` : ''
}sn: ${frag.sn} at playlist time: ${frag.start}. Resetting transmuxer to fallback to playlist timing`,
);
this.warn(error.message);
this.hls.trigger(Events.ERROR, {
+4 -2
View File
@@ -1124,8 +1124,10 @@ transfer tracks: ${stringify(transferredTracks, (key, value) => (key === 'initSe
};
if (buffersAppendedTo.length === 0) {
this.warn(
`Fragments must have at least one ElementaryStreamType set. type: ${frag.type} level: ${frag.level} sn: ${frag.sn}`,
this.log(
`Fragments must have at least one ElementaryStreamType set. ${frag.type} ${frag.level} ${
part ? `part: ${part.index} of ` : ''
}sn: ${frag.sn}`,
);
}
+40 -36
View File
@@ -215,6 +215,7 @@ class PassThroughRemuxer extends Logger implements Remuxer {
}
if (this.emitInitSegment) {
initSegment.tracks = this.initTracks;
result.initSegment = initSegment;
this.emitInitSegment = false;
}
@@ -268,6 +269,15 @@ class PassThroughRemuxer extends Logger implements Remuxer {
? audioSampleTimestamps
: videoSampleTimestamps;
if (!baseOffsetSamples) {
this.log(
`No media samples found in ${playlistType} ${chunkMeta.level} ${
chunkMeta.part === -1 ? '' : `part: ${chunkMeta.part} of`
} sn: ${chunkMeta.sn} at playlist time: ${timeOffset}`,
);
return result;
}
let data1 = data;
let data2: Uint8Array<ArrayBuffer> | undefined;
if (
@@ -336,46 +346,40 @@ class PassThroughRemuxer extends Logger implements Remuxer {
: videoEndTime - videoStartTime;
}
if (baseOffsetSamples) {
const timescale = baseOffsetSamples.timescale;
const baseTime = baseOffsetSamples.start - timeOffset * timescale;
const trackId = syncOnAudio ? initData.audio!.id : initData.video!.id;
const timescale = baseOffsetSamples.timescale;
const baseTime = baseOffsetSamples.start - timeOffset * timescale;
const trackId = syncOnAudio ? initData.audio!.id : initData.video!.id;
decodeTime = baseOffsetSamples.start / timescale;
decodeTime = baseOffsetSamples.start / timescale;
if (
(accurateTimeOffset || !initPTS) &&
(isInvalidInitPts(initPTS, decodeTime, timeOffset, duration) ||
timescale !== initPTS.timescale)
) {
let detectedDrift = false;
const trackType = syncOnAudio ? 'audio' : 'video';
if (initPTS) {
const driftEstimate =
timeOffset !== 0 ? decodeTime / timeOffset : 1 + decodeTime / 1;
detectedDrift =
decodeTime >= 0 && Math.abs(1 - driftEstimate) < 0.001;
this.log(
`${trackType} timestamps in track ${trackId} at playlist time: ${accurateTimeOffset ? '' : '~'}${timeOffset} maps to ${decodeTime} with initPTS: ${initPTS.baseTime / initPTS.timescale} (${
baseTime / timescale - initPTS.baseTime / initPTS.timescale
}s diff) (${type}) drift estimate: ${driftEstimate} ${detectedDrift ? '(ignoring drift)' : 'remapping timestamps (initPTS)'}`,
);
}
if (!detectedDrift) {
this.log(
`Found initPTS in ${trackType} track ${trackId} at playlist time: ${timeOffset} offset: ${decodeTime - timeOffset} (${baseTime}/${timescale})`,
);
initPTS = null;
initSegment.initPTS = baseTime;
initSegment.timescale = timescale;
initSegment.trackId = trackId;
}
if (
(accurateTimeOffset || !initPTS) &&
(isInvalidInitPts(initPTS, decodeTime, timeOffset, duration) ||
timescale !== initPTS.timescale)
) {
let detectedDrift = false;
const trackType = syncOnAudio ? 'audio' : 'video';
if (initPTS) {
const driftEstimate =
timeOffset !== 0 ? decodeTime / timeOffset : 1 + decodeTime / 1;
detectedDrift = decodeTime >= 0 && Math.abs(1 - driftEstimate) < 0.001;
this.log(
`${trackType} timestamps in track ${trackId} at playlist time: ${accurateTimeOffset ? '' : '~'}${timeOffset} maps to ${decodeTime} with initPTS: ${initPTS.baseTime / initPTS.timescale} (${
baseTime / timescale - initPTS.baseTime / initPTS.timescale
}s diff) (${type}) drift estimate: ${driftEstimate} ${detectedDrift ? '(ignoring drift)' : 'remapping timestamps (initPTS)'}`,
);
}
if (!detectedDrift) {
this.log(
`Found initPTS in ${trackType} track ${trackId} at playlist time: ${timeOffset} offset: ${decodeTime - timeOffset} (${baseTime}/${timescale})`,
);
initPTS = null;
initSegment.initPTS = baseTime;
initSegment.timescale = timescale;
initSegment.trackId = trackId;
}
} else {
this.warn(
`No audio or video samples found for initPTS at playlist time: ${timeOffset}`,
);
}
if (!initPTS) {
if (
!initSegment.timescale ||