feat(media): extract audio track to local file (#39)#79
Closed
cuic19053-hue wants to merge 3 commits into
Closed
Conversation
…card) (appergb#39) Adds an end-to-end "extract audio" path so users can save a video's soundtrack as a standalone audio file from the media panel. Backend (Rust): - opentake-media: `MediaEngine::extract_audio` + `extract_audio_file` helper drive ffmpeg via the existing `ffmpeg_path()` CLI wrapper. `-y -i <in> -vn` plus codec args picked by output extension: .m4a/.aac → AAC 192k, .mp3 → libmp3lame 192k, .wav → pcm_s16le. - src-tauri/media: new `extract_audio` Tauri command resolves a media id to its `MediaSource::External` absolute path, validates the file exists, then delegates to the engine. Returns the output path. - src-tauri/lib: register `media::extract_audio` in `generate_handler!`. Frontend (React/TS): - api.ts: `extractAudio(mediaId, outPath)` wrapper; rejects outside Tauri (no ffmpeg available). - MediaPanel.tsx: MediaCard gains a star-shaped "Extract Audio" button on the top-left, shown only when hovering a video that carries an audio track. Click opens a native save dialog (m4a/mp3/wav filters), invokes `extract_audio`, and surfaces a transient success/failure feedback message. `stopPropagation`+`preventDefault` keep the click from selecting the card. - i18n dict.ts: 6 new keys (zh-CN + en) for the button title, hint, success, failure, and no-audio messages. Closes appergb#39.
This was referenced Jun 22, 2026
Closed
4 tasks
appergb
requested changes
Jun 23, 2026
appergb
left a comment
Owner
There was a problem hiding this comment.
@cuic19053-hue 自动审核结论:请修改(REQUEST_CHANGES)。Rust 抽音轨逻辑结构正确,但无法直接合并:
阻塞项:
- 冲突,需 rebase:diff 基于 PR#102 之前的旧版。src-tauri/src/lib.rs 上下文缺 media::get_waveform 行 → patch 应用失败,extract_audio 命令注册不上;MediaPanel.tsx 也是旧版上下文。请 rebase 到最新 main。
- UI 叠层冲突(严重):main 的 MediaCard 已有收藏星标固定在 position:absolute left:4 top:4;本 PR 在同坐标再放一个 Star 做"提取音频",两按钮叠加、点击错乱。上游抽音频走右键菜单 Save as Media(EditorViewModel+SaveAsMedia.swift),不用星标。请换图标/位置或改走右键菜单(与 #93/#101 协调)。
- 缺 issue #39 验收测试:提取后文件存在 / 时长匹配 / 无视频流 三项测试缺失,请补集成测试。
- out_path 无后端路径边界校验(任意 ../ 可写)。
注:本 PR 触碰 media.rs/MediaPanel,属 #91 重写范围,建议与 #91/#101 协调以免白做。请 rebase + 重设计 UI + 补测试后重提。
5 tasks
# Conflicts: # src-tauri/src/lib.rs # src-tauri/src/media.rs # web/src/components/media/MediaPanel.tsx # web/src/i18n/dict.ts # web/src/lib/api.ts
review #3 #4) Review #3 (缺验收测试): - Extract audio_codec_args() as pure function for unit testing - Add 4 unit tests covering m4a/mp3/wav/unknown extension selection - Add #[ignore] integration test verifying issue appergb#39 acceptance criteria: 1. output file exists after extraction 2. duration matches input (within 0.5s) 3. no video stream in output Auto-skips when ffmpeg/ffprobe unavailable; run with --ignored Review #4 (out_path 无路径边界校验): - Add validate_extract_output() enforcing: - reject null bytes (OS API truncation risk) - require absolute path (save dialog always returns absolute) - extension whitelist (m4a/m4r/aac/mp3/wav) - extract_audio command calls validator before touching manifest/ffmpeg - 5 unit tests covering each rejection path + whitelist acceptance No behavioral change to the extraction logic itself; the codec table and ffmpeg invocation are unchanged.
Contributor
Author
|
@appergb 请求重新审查。R2 四个阻塞项已逐条核对/补修,CI 双绿(commit 1. 冲突需 rebase ✅
2. UI 叠层冲突 ✅
3. 缺 issue #39 验收测试 ✅(commit
4. out_path 路径边界校验 ✅(commit
本地验证:
|
Owner
|
Closing as superseded by #155, which has been merged into main and includes this work in the integrated codebase. Keeping this PR closed avoids duplicate/conflicting review paths. |
Owner
|
Superseded by merged integration PR #155. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
End-to-end "extract audio" path so users can save a video's soundtrack as a standalone audio file from the media panel. Closes #39.
Changes
Backend (Rust)
crates/opentake-media/src/lib.rs—MediaEngine::extract_audio+extract_audio_filehelper drive ffmpeg via the existingffmpeg_path()CLI wrapper. Invokes-y -i <in> -vnplus codec args picked by output extension:.m4a/.aac→ AAC 192k.mp3→ libmp3lame 192k.wav→ pcm_s16lesrc-tauri/src/media.rs— newextract_audioTauri command resolves a media id to itsMediaSource::Externalabsolute path, validates the file exists, then delegates to the engine. Returns the output path.src-tauri/src/lib.rs— registermedia::extract_audioingenerate_handler!.Frontend (React/TS)
web/src/lib/api.ts—extractAudio(mediaId, outPath)wrapper; rejects outside Tauri (no ffmpeg available).web/src/components/media/MediaPanel.tsx—MediaCardgains a star-shaped "Extract Audio" button on the top-left, shown only when hovering a video that carries an audio track. Click opens a native save dialog (m4a/mp3/wav filters), invokesextract_audio, and surfaces a transient success/failure feedback message.stopPropagation+preventDefaultkeep the click from selecting the card.web/src/i18n/dict.ts— 6 new keys (zh-CN + en) for the button title, hint, success, failure, and no-audio messages.Verification
pnpm tsc --noEmit✅pnpm build✅ (vite production build, 1639 modules)MediaEnginemethod + Tauri command); CI will verifycargo build.User flow
.m4a/.mp3/.wavfilters.Notes
MediaSource::Externalassets are supported (project-relative assets return an error). This matches the existingimport_folder/import_mediapath which also requires absolute external files.