diff --git a/src/av-utils.ts b/src/av-utils.ts index 94c442b..7b53d5a 100644 --- a/src/av-utils.ts +++ b/src/av-utils.ts @@ -103,7 +103,7 @@ export function adjustAudioDataVolume(ad: AudioData, volume: number) { sampleRate: ad.sampleRate, numberOfChannels: ad.numberOfChannels, timestamp: ad.timestamp, - format: ad.format, + format: ad.format!, numberOfFrames: ad.numberOfFrames, data, }); @@ -223,8 +223,8 @@ export function autoReadStream( stream: ST, cbs: { onChunk: ST extends ReadableStream - ? (chunk: DT) => Promise - : never; + ? (chunk: DT) => Promise + : never; onDone: () => void; } ) { diff --git a/src/clips/mp4-clip.ts b/src/clips/mp4-clip.ts index 447ea17..8b2d29f 100644 --- a/src/clips/mp4-clip.ts +++ b/src/clips/mp4-clip.ts @@ -82,9 +82,9 @@ export class MP4Clip implements IClip { video: VideoDecoderConfig | null; audio: AudioDecoderConfig | null; } = { - video: null, - audio: null, - }; + video: null, + audio: null, + }; #opts: MP4ClipOpts = { audio: true }; @@ -114,15 +114,15 @@ export class MP4Clip implements IClip { this.#localFile = isOTFile(source) ? source : "localFile" in source - ? source.localFile // from clone - : tmpfile(); + ? source.localFile // from clone + : tmpfile(); this.ready = ( source instanceof ReadableStream ? initByStream(source).then((s) => parseMP4Stream(s, this.#opts)) : isOTFile(source) - ? source.stream().then((s) => parseMP4Stream(s, this.#opts)) - : Promise.resolve(source) + ? source.stream().then((s) => parseMP4Stream(s, this.#opts)) + : Promise.resolve(source) ).then(async ({ videoSamples, audioSamples, decoderConf }) => { this.#videoSamples = videoSamples; this.#decoderConf = decoderConf; @@ -132,10 +132,10 @@ export class MP4Clip implements IClip { decoderConf.video == null ? null : { - ...decoderConf.video, - hardwareAcceleration: - this.#opts.__unsafe_hardwareAcceleration__, - }, + ...decoderConf.video, + hardwareAcceleration: + this.#opts.__unsafe_hardwareAcceleration__, + }, audio: decoderConf.audio, }, await this.#localFile.createReader(), @@ -147,7 +147,6 @@ export class MP4Clip implements IClip { this.#audioFrameFinder = audioFrameFinder; this.#meta = genMeta(decoderConf, videoSamples, audioSamples); - this.#log.info("MP4Clip meta:", this.#meta); return { ...this.#meta }; }); } @@ -406,22 +405,22 @@ function genDecoder( volume === 0 || decoderConf.audio == null || audioSamples.length === 0 ? null : new AudioFrameFinder( - localFileReader, - audioSamples, - decoderConf.audio, - { - volume, - targetSampleRate: DEFAULT_AUDIO_CONF.sampleRate, - } - ), + localFileReader, + audioSamples, + decoderConf.audio, + { + volume, + targetSampleRate: DEFAULT_AUDIO_CONF.sampleRate, + } + ), videoFrameFinder: decoderConf.video == null || videoSamples.length === 0 ? null : new VideoFrameFinder( - localFileReader, - videoSamples, - decoderConf.video - ), + localFileReader, + videoSamples, + decoderConf.video + ), }; } @@ -456,16 +455,6 @@ async function parseMP4Stream( Error("MP4Clip must contain at least one video or audio track") ); } - Log.info( - "mp4BoxFile moov ready", - { - ...data.info, - tracks: null, - videoTracks: null, - audioTracks: null, - }, - decoderConf - ); } else if (chunkType === "samples") { if (data.type === "video") { if (videoDeltaTS === -1) videoDeltaTS = data.samples[0].dts; @@ -494,7 +483,6 @@ async function parseMP4Stream( firstSample.duration += firstSample.cts; firstSample.cts = 0; } - Log.info("mp4 stream parsed"); resolve({ videoSamples, audioSamples, @@ -530,7 +518,7 @@ class VideoFrameFinder { public localFileReader: LocalFileReader, public samples: ExtMP4Sample[], public conf: VideoDecoderConfig - ) {} + ) { } #ts = 0; #curAborter = { abort: false, st: performance.now() }; @@ -757,9 +745,9 @@ class AudioFrameFinder { frameCnt: number; data: [Float32Array, Float32Array][]; } = { - frameCnt: 0, - data: [], - }; + frameCnt: 0, + data: [], + }; #parseFrame = async ( deltaTime: number, dec: ReturnType | null = null, @@ -953,7 +941,7 @@ function emitAudioFrames( const audio = [new Float32Array(emitCnt), new Float32Array(emitCnt)]; let offset = 0; let i = 0; - for (; i < pcmData.data.length; ) { + for (; i < pcmData.data.length;) { const [chan0, chan1] = pcmData.data[i]; if (offset + chan0.length > emitCnt) { const gapCnt = emitCnt - offset; @@ -990,7 +978,7 @@ async function videosamples2Chunks( return samples.map((s) => { const offset = s.offset - first.offset; let sData = data.subarray(offset, offset + s.size); - if (s.is_idr) sData = removeSEIForIDR(sData); + if (s.is_idr) sData = removeSEIForIDR(sData) as Uint8Array; return new EncodedVideoChunk({ type: s.is_sync ? "key" : "delta", timestamp: s.cts, @@ -1005,7 +993,7 @@ async function videosamples2Chunks( let sData = await reader.read(s.size, { at: s.offset, }); - if (s.is_idr) sData = removeSEIForIDR(new Uint8Array(sData)); + if (s.is_idr) sData = removeSEIForIDR(new Uint8Array(sData)) as unknown as ArrayBuffer; return new EncodedVideoChunk({ type: s.is_sync ? "key" : "delta", timestamp: s.cts, @@ -1071,7 +1059,7 @@ function isIDRFrame(u8Arr: Uint8Array, type: MP4Sample["description"]["type"]) { const dv = new DataView(u8Arr.buffer); let i = 0; - for (; i < u8Arr.byteLength - 4; ) { + for (; i < u8Arr.byteLength - 4;) { if (type === "avc1") { if ((dv.getUint8(i + 4) & 0x1f) === 5) return true; } else if (type === "hvc1") { diff --git a/src/log.ts b/src/log.ts index 7bebff3..c1a7c54 100644 --- a/src/log.ts +++ b/src/log.ts @@ -24,7 +24,6 @@ const lvHandler = ["debug", "info", "warn", "error"].reduce( Object.assign(acc, { [lvName]: (...args: any[]) => { if (THRESHOLD <= lvThres) { - console[lvName as LvName](...args); writer?.write( `[${lvName}][${getTimeStr()}] ${args .map((a) => any2Str(a)) @@ -67,8 +66,6 @@ map.set(Log.error, 3); async function init() { try { writer = await localFile.createWriter(); - Log.info(navigator.userAgent); - Log.info("date: " + new Date().toLocaleDateString()); } catch (err) { if (!(err instanceof Error)) throw err; if (err.message.includes("createSyncAccessHandle is not a function")) { diff --git a/src/mp4-utils/index.ts b/src/mp4-utils/index.ts index 900f9dc..c47c1ac 100644 --- a/src/mp4-utils/index.ts +++ b/src/mp4-utils/index.ts @@ -324,7 +324,7 @@ function encodeAudioTrack( error: Log.error, output: (chunk, meta) => { if (trackId === -1) { - const desc = meta.decoderConfig?.description; + const desc = meta?.decoderConfig?.description; trackId = mp4File.addTrack({ ...audioTrackOpts, description: desc == null ? undefined : createESDSBox(desc), @@ -417,7 +417,7 @@ export function file2stream( let i = sendedBoxIdx; try { - for (; i < boxes.length; ) { + for (; i < boxes.length;) { boxes[i].write(ds); delete boxes[i]; i += 1; @@ -426,8 +426,7 @@ export function file2stream( const errBox = boxes[i]; if (err instanceof Error && errBox != null) { throw Error( - `${err.message} | deltaBuf( boxType: ${errBox.type}, boxSize: ${ - errBox.size + `${err.message} | deltaBuf( boxType: ${errBox.type}, boxSize: ${errBox.size }, boxDataLen: ${errBox.data?.length ?? -1})` ); } @@ -656,7 +655,7 @@ async function concatStreamsToMP4BoxFile( const offsetCTS = type === "video" ? vCTS : aCTS; samples.forEach((s) => { - outfile.addSample(trackId, s.data, { + outfile.addSample(trackId, s.data as unknown as ArrayBuffer, { duration: s.duration, dts: s.dts + offsetDTS, cts: s.cts + offsetCTS, @@ -870,7 +869,7 @@ export function mixinMP4AndAudio( } else if (chunkType === "samples") { const { id, type, samples } = data; if (type === "video") { - samples.forEach((s) => outfile.addSample(id, s.data, s)); + samples.forEach((s) => outfile.addSample(id, s.data as unknown as ArrayBuffer, s)); if (!mp4HasAudio) await addInputAudio2Track(samples); return; @@ -903,7 +902,7 @@ export function mixinMP4AndAudio( const pcmLength = Math.floor( ((lastSamp.cts + lastSamp.duration - firstSamp.cts) / lastSamp.timescale) * - sampleRate + sampleRate ); const audioDataBuf = mixinPCM([getInputAudioSlice(pcmLength)]); if (audioDataBuf.length === 0) return; diff --git a/src/mp4-utils/mp4box-utils.ts b/src/mp4-utils/mp4box-utils.ts index d28f7fc..09a5afb 100644 --- a/src/mp4-utils/mp4box-utils.ts +++ b/src/mp4-utils/mp4box-utils.ts @@ -22,8 +22,8 @@ export function extractFileConfig(file: MP4File, info: MP4Info) { const { descKey, type } = vTrack.codec.startsWith("avc1") ? { descKey: "avcDecoderConfigRecord", type: "avc1" } : vTrack.codec.startsWith("hvc1") - ? { descKey: "hevcDecoderConfigRecord", type: "hvc1" } - : { descKey: "", type: "" }; + ? { descKey: "hevcDecoderConfigRecord", type: "hvc1" } + : { descKey: "", type: "" }; if (descKey !== "") { rs.videoTrackConf = { timescale: vTrack.timescale, @@ -40,7 +40,7 @@ export function extractFileConfig(file: MP4File, info: MP4Info) { codec: vTrack.codec, codedHeight: vTrack.video.height, codedWidth: vTrack.video.width, - description: videoDesc, + description: videoDesc as AllowSharedBufferSource | undefined, }; }