我正在使用 ffprobe 获取媒体文件中字幕的编解码器名称。但是当我尝试获取编解码器扩展时,它失败了。我做错了什么?
我编辑了这篇文章以解决评论并包含完整的批处理文件
re ns.txt - 该命令输出字幕的流编号
C:\ffmpeg\bin\ffprobe -loglevel error -select_streams s -show_entries stream=index:stream_tags=language -of csv=p=0 -i "%~dpnx1">ns.txt
txt 文件中的输出为:
2
3
现在我需要计算这个文本文件中的行数,这将告诉我我的媒体文件有多少个字幕:
set "cmd=findstr /R /N "^^" ns.txt | find /C ":""
for /f %%a in ('!cmd!') do set nums=%%a
set /A nums=%nums%-1
在本例中 nums = 2 但在 ffprobe 中第一个字幕是 s:0,所以我从 nums 中减去 1
我的迭代循环是:
FOR %%i in (1,1,%nums%) DO (
C:\ffmpeg\bin\ffprobe.exe -v quiet -select_streams s:%%i -show_entries stream=%arg% -of default=noprint_wrappers=1:nokey=1 -i "%~dpnx1" >sub.txt
set /p codecs=<sub.txt
将编解码器名称放入 sub.txt 中,然后创建变量编解码器来存储该值
然后我需要为字幕确定适当的容器[扩展名] - 在这里我更改了我之前发布的代码:
if !codecs! == mov_text set codecs1=srt
if !codecs! == subrip set codecs1=srt
if !codecs! == ass set codecs1=ass
if !codecs! == webvtt set codecs1=vtt
if !codecs! == ttml set codecs1=ttml
if !codecs! == dvb_subtitle set codecs1=dvbsub
if !codecs! == dvd_subtitle set codecs1=dvdsub
if !codecs! == hdmv_pgs_subtitle setcodecs1=sup
if !codecs! == xsub set codecs1=xsub
然后我使用 ffmpeg 解复用[提取]字幕:
c:\ffmpeg\bin\ffmpeg -i "%~dpnx1" -an -vn -c:s "!codecs!" "%~n1_d."!codecs1!"
这是有效的,除了我有一个额外的迭代,我的输出是:
Mediafile: C:\Users\UNOIT\Desktop\Tears of Steel_2sub.mkv
subtile: Tears of Steel_2sub_d.srt
subtile: Tears of Steel_2sub_d.ass
subtile: Tears of Steel_2sub_d.ass
File 'Tears of Steel_2sub_d.ass' already exists. Overwrite? [y/N]
如果媒体文件只有一个字幕,我的 ffmpeg 输出是
Mediafile: C:\Users\UNOIT\Desktop\_Jan2024-Media\mkv\Tears of Steel_ass.mkv
subtile: Tears of Steel_ass_d.ass
subtile: Tears of Steel_ass_d.ass
File 'Tears of Steel_ass_d.ass' already exists. Overwrite? [y/N]
subtile: Tears of Steel_ass_d.ass
File 'Tears of Steel_ass_d.ass' already exists. Overwrite? [y/N]
我可以选择不覆盖文件 - 但显然我的迭代循环有问题 - 也许子例程可以工作
这是批处理文件:
ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
set "arg=codec_name"
set "arg1=codec_name"
set "arg2=codec_name"
echo Mediafile: %~dpnx1
C:\ffmpeg\bin\ffprobe -v quiet -loglevel error -select_streams s -show_entries stream=index:stream_tags=language -of csv=p=0 -i "%~dpnx1" >ns.txt
set "cmd=findstr /R /N "^^" ns.txt | find /C ":""
for /f %%a in ('!cmd!') do set nums=%%a
set /A nums=%nums%-1
FOR %%i in (0,1,%nums%) DO (
C:\ffmpeg\bin\ffprobe.exe -v quiet -select_streams s:%%i -show_entries stream=%arg% -of default=noprint_wrappers=1:nokey=1 -i "%~dpnx1" >sub%%i.txt
set /p codecs=<sub%%i.txt
if !codecs! == mov_text set codecs1=srt
if !codecs! == subrip set codecs1=srt
if !codecs! == ass set codecs1=ass
if !codecs! == webvtt set codecs1=vtt
if !codecs! == ttml set codecs1=ttml
if !codecs! == dvb_subtitle set codecs1=dvbsub
if !codecs! == dvd_subtitle set codecs1=dvdsub
if !codecs! == hdmv_pgs_subtitle setcodecs1=sup
if !codecs! == xsub set codecs1=xsub
echo subtile: %~n1_d.!codecs1!
c:\ffmpeg\bin\ffmpeg -v quiet -i "%~dpnx1" -an -vn -c:s "!codecs!" "%~n1_d."!codecs1!"
)
嗯..这让我很困惑。我不明白为什么您选择“最复杂的方式”来执行代码中的几乎每一步。如果我正确理解你想要什么,那么这些是关于你的代码的一系列注释:
在ns.txt
有多少个字幕,因此 ns.txt 文件的内容列表(包含行
2
和 3
)与此代码的目的完全无关。 您选择
ns.txt
文件中的行数。确定字幕扩展名的方法可以借助/L
FOR %%i in (0,1,%nums%) DO (
开关。
@ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
set "arg=codec_name"
set "arg1=codec_name"
set "arg2=codec_name"
echo Mediafile: %~dpnx1
rem Define the "codec to container" mapping array
set "extension[mov_text]=srt"
set "extension[subrip]=srt"
set "extension[ass]=ass"
set "extension[webvtt]=vtt"
set "extension[ttml]=ttml"
set "extension[dvb_subtitle]=dvbsub"
set "extension[dvd_subtitle]=dvdsub"
set "extension[hdmv_pgs_subtitle]=sup"
set "extension[xsub]=xsub"
C:\ffmpeg\bin\ffprobe -v quiet -loglevel error -select_streams s -show_entries stream=index:stream_tags=language -of csv=p=0 -i "%~dpnx1" >ns.txt
for /F "tokens=3" %%a in ('find /V /C "" ns.txt') do set /A nums=%%a-1
FOR /L %%i in (0,1,%nums%) DO (
C:\ffmpeg\bin\ffprobe.exe -v quiet -select_streams s:%%i -show_entries stream=%arg% -of default=noprint_wrappers=1:nokey=1 -i "%~dpnx1" > sub.txt
for /F %%a in (sub.txt) do set "codecs=%%a" & set "codecs1=!extension[%%a]!"
echo subtile: %~n1_d.!codecs1!
c:\ffmpeg\bin\ffmpeg -v quiet -i "%~dpnx1" -an -vn -c:s "!codecs!" "%~n1_d.!codecs1!"
)