fix: sanitize packet-scan range against NaN/Infinity duration
mediaInfo.duration from web-demuxer can be NaN or Infinity on Chromium Linux (same MediaRecorder bug this PR otherwise addresses). That value flowed straight into Math.max + demuxer.read() as scanEndSec, producing an invalid range argument and breaking the ground-truth packet scan. Guard both mediaInfo.duration and videoStream.duration with Number.isFinite before Math.max; validateDuration() already handled the downstream use. Drop redundant WebDemuxer.read() / getDecoderConfig() type casts while here — the generics infer the chunk/config type from the media string literal, so the `as ReadableStream<EncodedVideoChunk>` and `as AudioDecoderConfig` are no-ops.
This commit is contained in:
@@ -62,7 +62,7 @@ export class AudioProcessor {
|
||||
): Promise<void> {
|
||||
let audioConfig: AudioDecoderConfig;
|
||||
try {
|
||||
audioConfig = (await demuxer.getDecoderConfig("audio")) as AudioDecoderConfig;
|
||||
audioConfig = await demuxer.getDecoderConfig("audio");
|
||||
} catch {
|
||||
console.warn("[AudioProcessor] No audio track found, skipping");
|
||||
return;
|
||||
@@ -87,11 +87,10 @@ export class AudioProcessor {
|
||||
typeof readEndSec === "number" && Number.isFinite(readEndSec)
|
||||
? Math.max(0, readEndSec)
|
||||
: undefined;
|
||||
const audioStream = (
|
||||
const audioStream =
|
||||
safeReadEndSec !== undefined
|
||||
? demuxer.read("audio", 0, safeReadEndSec)
|
||||
: demuxer.read("audio")
|
||||
) as ReadableStream<EncodedAudioChunk>;
|
||||
: demuxer.read("audio");
|
||||
const reader = audioStream.getReader();
|
||||
|
||||
try {
|
||||
@@ -396,8 +395,8 @@ export class AudioProcessor {
|
||||
|
||||
try {
|
||||
await demuxer.load(file);
|
||||
const audioConfig = (await demuxer.getDecoderConfig("audio")) as AudioDecoderConfig;
|
||||
const reader = (demuxer.read("audio") as ReadableStream<EncodedAudioChunk>).getReader();
|
||||
const audioConfig = await demuxer.getDecoderConfig("audio");
|
||||
const reader = demuxer.read("audio").getReader();
|
||||
let isFirstChunk = true;
|
||||
|
||||
try {
|
||||
|
||||
@@ -231,11 +231,16 @@ export class StreamingVideoDecoder {
|
||||
// MediaRecorder (especially on Linux) writes unreliable container durations.
|
||||
// Packet timestamps are ground truth — no decode needed, just timestamp reads.
|
||||
// Pass explicit range because some containers are truncated without one.
|
||||
const scanEndSec = Math.max(mediaInfo.duration, videoStream?.duration ?? 0, 0) + 0.5;
|
||||
// Sanitize because mediaInfo.duration can be NaN/Infinity (Chromium Linux bug),
|
||||
// which would propagate into demuxer.read() as an invalid endpoint.
|
||||
const containerDurationSec = Number.isFinite(mediaInfo.duration) ? mediaInfo.duration : 0;
|
||||
const streamDurationSec =
|
||||
typeof videoStream?.duration === "number" && Number.isFinite(videoStream.duration)
|
||||
? videoStream.duration
|
||||
: 0;
|
||||
const scanEndSec = Math.max(containerDurationSec, streamDurationSec, 0) + 0.5;
|
||||
let maxPacketEndUs = 0;
|
||||
const scanReader = (
|
||||
this.demuxer.read("video", 0, scanEndSec) as ReadableStream<EncodedVideoChunk>
|
||||
).getReader();
|
||||
const scanReader = this.demuxer.read("video", 0, scanEndSec).getReader();
|
||||
try {
|
||||
while (true) {
|
||||
const { done, value } = await scanReader.read();
|
||||
|
||||
Reference in New Issue
Block a user