From 97931887ecb956e557e9b775344e99a5ee29c523 Mon Sep 17 00:00:00 2001 From: Mikael Finstad Date: Sun, 3 Dec 2023 00:00:09 +0800 Subject: [PATCH] read audio fps too closes #1754 --- src/App.jsx | 11 +++++++++-- src/ffmpeg.js | 34 +++++++++++++++++++++++++++++----- 2 files changed, 38 insertions(+), 7 deletions(-) diff --git a/src/App.jsx b/src/App.jsx index 30f11060..0561893b 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -311,7 +311,7 @@ const App = memo(() => { }, [seekRel, zoomedDuration]); const shortStep = useCallback((direction) => { - // If we don't know fps, just assume 30 (for example if audio file) + // If we don't know fps, just assume 30 (for example if unknown audio file) const fps = detectedFps || 30; // try to align with frame @@ -1492,8 +1492,15 @@ const App = memo(() => { // throw new Error('test'); + // eslint-disable-next-line no-inner-declarations + function getFps() { + if (haveVideoStream) return getStreamFps(videoStream); + if (haveAudioStream) return getStreamFps(audioStream); + return undefined; + } + if (timecode) setStartTimeOffset(timecode); - setDetectedFps(haveVideoStream ? getStreamFps(videoStream) : undefined); + setDetectedFps(getFps()); if (!haveVideoStream) setWaveformMode('big-waveform'); setMainFileMeta({ streams: fileMeta.streams, formatData: fileMeta.format, chapters: fileMeta.chapters }); setMainVideoStream(videoStream); diff --git a/src/ffmpeg.js b/src/ffmpeg.js index 5c3b6a7f..6b06f882 100644 --- a/src/ffmpeg.js +++ b/src/ffmpeg.js @@ -523,12 +523,36 @@ export function isProblematicAvc1(outFormat, streams) { return isMov(outFormat) && streams.some((s) => s.codec_name === 'h264' && s.codec_tag === '0x31637661' && s.codec_tag_string === 'avc1' && s.pix_fmt === 'yuv422p10le'); } -export function getStreamFps(stream) { +function parseFfprobeFps(stream) { const match = typeof stream.avg_frame_rate === 'string' && stream.avg_frame_rate.match(/^([0-9]+)\/([0-9]+)$/); - if (stream.codec_type === 'video' && match) { - const num = parseInt(match[1], 10); - const den = parseInt(match[2], 10); - if (den > 0) return num / den; + if (!match) return undefined; + const num = parseInt(match[1], 10); + const den = parseInt(match[2], 10); + if (den > 0) return num / den; + return undefined; +} + +export function getStreamFps(stream) { + if (stream.codec_type === 'video') { + const fps = parseFfprobeFps(stream); + return fps; + } + if (stream.codec_type === 'audio') { + if (typeof stream.sample_rate === 'string') { + const sampleRate = parseInt(stream.sample_rate, 10); + if (!Number.isNaN(sampleRate) && sampleRate > 0) { + if (stream.codec_name === 'mp3') { + // https://github.com/mifi/lossless-cut/issues/1754#issuecomment-1774107468 + const frameSize = 1152; + return sampleRate / frameSize; + } + if (stream.codec_name === 'aac') { + // https://stackoverflow.com/questions/59173435/aac-packet-size + const frameSize = 1024; + return sampleRate / frameSize; + } + } + } } return undefined; }