Windows 批处理 - 无法在迭代 for 循环中分配变量

问题描述 投票:0回答:1

我正在使用 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!"
)
batch-file ffmpeg
1个回答
0
投票

嗯..这让我很困惑。我不明白为什么您选择“最复杂的方式”来执行代码中的几乎每一步。如果我正确理解你想要什么,那么这些是关于你的代码的一系列注释:

    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!" )

© www.soinside.com 2019 - 2024. All rights reserved.