因此,我尝试重构一些旧代码,删除视频流,压缩音频流并重新打包 mp4,这应该是只有音频流的视频文件。我稍后打算复制它以与 .wmv 一起使用。
根据作者的说法,它的工作原理如下:
使用 mediainfo.exe 获取 AudioStreamID (1 或 2)
mediaindo --inform=Audio;%ID% "filename.mp4"
使用上面的 mp4box.exe 和 ID 提取音轨。例如,ID=1:
mp4box -raw 1 "filename.mp4" -out "filename.aac"
使用 ffmpeg.exe 和 fdkaac.exe 压缩音轨
ffmpeg -i "filename.aac" -f caf - | fdkaac -b16 -I -p29 - -o "filename.m4a"
删除旧的音频和视频轨道并添加新的压缩音轨
mp4box -rem 1 -rem 2 -add "filename.m4a" "filename.mp4"
然后其他人把它放入批处理中:
@echo off
echo CBFT MP4 to SDVL converter
chcp 65001>nul
echo %~n1
setlocal
set mp4box=P:\progz\multimedia\gpac\mp4box.e xe -quiet
set ffmpeg=P:\progz\multimedia\ffmpeg\bin\ff mpeg.exe -hide_banner -v 0
set fdkaac=P:\progz\multimedia\fdkaac\fdkaac .exe
set mediainfo=P:\progz\multimedia\MediaInfo\ MediaInfo.exe
for /R %1 %%f in (*.mp4) do (
echo.
echo %%~nxf
if exist "%%~dpnf.aac" del "%%~dpnf.aac">nul
if exist "%%~dpnf.m4a" del "%%~dpnf.m4a">nul
for /f "tokens=1,2* delims=:" %%a in (
'%mediainfo% --inform^=Audio^;%%ID%%:%%Duration/String3%% "%%f"') do (
echo %%c
%mp4box% -raw %%a "%%f" -out "%%~dpnf.aac" )
%ffmpeg% -i "%%~dpnf.aac" -f caf - | %fdkaac% -b16 -I -p29 - -o "%%~dpnf.m4a"
%mp4box% -flat -rem 1 -rem 2 -add "%%~dpnf.m4a":name= "%%f"
if exist "%%~dpnf.aac" del "%%~dpnf.aac">nul
if exist "%%~dpnf.m4a" del "%%~dpnf.m4a">nul
)
endlocal
到那时,它似乎可以使用 mp4。现在它在 ffmpeg 部分中断了,这是我迄今为止重建它的尝试:
echo CBFT MP4 to SDVL converter
chcp 65001>nul
echo %~n1
for /R %1 %%f in (*.mp4) do (
echo STARTING
echo %%~nxf
if exist "%%~dpnf.aac" del "%%~dpnf.aac"
if exist "%%~dpnf.m4a" del "%%~dpnf.m4a"
echo start ABOVE
echo mediainfo BELOW
pause
for /f "tokens=1,2* delims=:" %%a in (
'mediainfo --inform^=Audio^;%%ID%%:%%Duration/String3%% "%%f"') do (
echo %%c
mp4box -raw %%a "%%f" -out "%%~dpnf.aac" )
echo mp4box ABOVE
echo ffmpeg BELOW
pause
## This line should compress the audio stream ##
echo ffmpeg ABOVE
echo mp4box BELOW
pause
mp4box -flat -rem 1 -rem 2 -add "%%~dpnf.m4a":name= "%%f"
if exist "%%~dpnf.aac" del "%%~dpnf.aac"
if exist "%%~dpnf.m4a" del "%%~dpnf.m4a"
)
endlocal
请注意,它缺少流压缩部分,而且我完全删除了 fdkaac。我还猜测整个过程可以通过单个 ffmpeg 命令(加上循环部分)完成,这在我尝试让它与 .wmv 文件一起工作时特别有用。
您能指点一下我应该怎么做吗?如果可能的话,请提供单个 ffmpeg 命令,或者帮助我使用多个命令,以便让它们一起工作?
澄清一下:我的目标是用 ffmpeg 重现步骤 1 到 4。我相信是过滤流的功能,可能比旧代码更经济。我应该如何使用 ffmpeg 来实现这一点?
答案1
我知道有一个最终的、可以运行的版本,尽管它可以在以下-f
部分进行一些改进:
整个过程(在检查 ffmpeg 是否可用之后)
:: Actual converting ::
for /r "%~1" %%V in (*.mp4, *.wmv, *.mkv, *.avi, *.webm, *.mov, *.m4v) do (
for /f "tokens=* delims=." %%A in ("%%~xV") do set ext=%%A
if !ext!==mkv set ext=matroska
if !ext!==webm set ext=matroska
if !ext!==wmv set ext=asf
ffmpeg -err_detect ignore_err -fflags +igndts -i "%%~fV" -f !ext! -codec:a copy -map 0 -map -0:v -map -0:s -b:a 32k "%%~pnxV.tmpsdvl"
)
:: Moving and Renaming ::
robocopy "%~f1" "SDVL\%~n1" *.tmpsdvl /s /mov
for /r "SDVL\%~n1" %%B in (*.TMPSDVL) do ren %%~fB %%~nB
分解
FFmpeg 字符串
ffmpeg -err_detect ignore_err -fflags +igndts -i "%%~fV" -f !ext! -codec:a copy -map 0 -map -0:v -map -0:s -b:a 32k "%%~pnxV.tmpsdvl"
它能做什么
-err_detect ignore_err
并-fflags +igndts
采取了一些措施来纠正一些常见的错误;-i "%%~fV"
是我输入的完整限定路径,因为我正在运行循环for
;-f !ext!
确保输出使用先前指定的变量的格式。这种方法将在下面阐明;-codec:a copy
告诉 fmmpeg 对音频流使用相同的编码器;-map 0
从文件中选择所有流;-map -0:v
然后取消选择所有视频流;-map -0:s
取消选择每个字幕流;-b:a 32k
将音频质量设置为32kbps CBR;"%%~pnxV.tmpsdvl"
在与输入相同的目录中生成输出,但.tmpsdvl
添加了扩展。
循环
for /r "%~1" %%V in (*.mp4, *.wmv, *.mkv, *.avi, *.webm, *.mov, *.m4v) do (
for /f "tokens=* delims=." %%A in ("%%~xV") do set ext=%%A
if !ext!==mkv set ext=matroska
if !ext!==webm set ext=matroska
if !ext!==wmv set ext=asf
它能做什么
此for
循环遍历()
输入文件夹中括号中指定的每个文件类型(这是第一个传递的参数"%~1"
),并将每个匹配项用作%%V
。在实际运行之前ffmpeg
,我们需要定义一个变量 !ext!,因为简单地将扩展名传递给ffmpeg -f
不一定有效。我们还需要修剪.
%%xV 中的前导。这是我认为唯一需要改进的地方,因为我必须手动转换mkv
为本matroska
节中的 eg。
搬迁和改名
robocopy "%~f1" "SDVL\%~n1" *.tmpsdvl /s /mov
for /r "SDVL\%~n1" %%B in (*.TMPSDVL) do ren %%~fB %%~nB
它能做什么
这有点微不足道,但为了彻底起见,它会从应用此命令的文件夹中取出每个 .tmpsdvl 文件并将其移动到单独的文件夹,保留原始结构。然后,它会巧妙地将每个文件重命名为没有扩展名的版本,而且由于我们有file.ext.tmpsdvl
,我们很容易得到file.ext
笔记
- 选择的质量为 32kbps,因为 .wmv 文件至少需要 24kbps 的音频流;
- 在需要指定的部分仍有改进的空间
ffmpeg -f
。也许可以使用ffprobe
。
参考
- FFmpeg 编码与编辑课程,作者:Werner Robitza;
- FFmpeg 文档;
- 这个答案在负映射上,洛根@堆栈溢出。
- Steve Jansen 的出色批次课程;
- 非常有帮助批次部分在 Rob van der Weude 的网站上;
- 电脑希望的部分操作系统
- DosTips - DOS 批处理指南;
- StackExchange 上还有大量分散的答案!
答案2
ffmpeg -v 错误 -stats -i 输入.mp4 -vn -sn -dn -acodec libmp3lame -ab 192k -ar 41000 输出.mp3
或者
-acodec aac -ab 265k 输出.m4a
或-acodec copy
不压缩