更改批处理脚本导致 ffprobe 比特率读取失败

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

好的,这是一个使用

ffprobe
读取视频文件中使用的比特率的脚本。

@echo off
cd /d "%~dp0"
set "manifest=%~dpn0.txt"
set "temporary=%temp%\%~n0.tmp"
:: input must exist and be no duplicate
if exist "%~1" findstr /c:"%~1" "%manifest%" >nul || echo "%~1">>"%manifest%"
:: exit all but first instance
tasklist /fi "imagename eq handbrakecli.exe" | find /i "handbrakecli" && exit

:manifest
for /f "delims=" %%f in (%manifest%) do (
    set "in=%%~ff"
    set "out=%%~dpnf-2.mkv"
    call :transcode )
for %%a in ("%manifest%") do if not %%~za lss 4 goto :manifest
exit /b

:transcode
if not exist "%in%" goto :cleanup
if exist "%out%" goto :cleanup
    
ffprobe "%in%" -v 0 -select_streams v:0 -show_entries stream=bit_rate -print_format compact=p=0:nokey=1 >"%temporary%"
set /p bitrate=<%temporary%
if not defined bitrate echo failed to fetch bitrate & goto :cleanup
:: reduce to full kilobytes
set "bitrate=%bitrate:~0,-3%"
if %bitrate% gtr 7000 set bitrate=7000

HandBrakeCLI -i "%in%" -o "%out%" --encoder x265_10bit --vb %bitrate% --two-pass --turbo --audio 1-9 --aencoder copy --audio-copy-mask aac,ac3,mp2,mp3,opus --audio-fallback opus --ab 160 --drc 2.0

:cleanup
findstr /v /c:"%in%" "%manifest%">"%temporary%"
move /y "%temporary%" "%manifest%">nul

该命令很可靠,但根据我对脚本其余部分的工作,它不断地被破坏。请注意,

ffprobe
命令本身、变量等一直是相同的,但它仍然时不时地中断。我怀疑这与
"
引号或脚本中其他地方类似的内容有关。目前,我得到的是
N/A
,而不是代表视频轨道比特率的数字。是的,这已经在视频上进行了测试,这些视频已被证明可以与早期脚本版本配合良好,通过
ffprobe
传递比特率信息。

windows batch-file cmd command-line batch-processing
2个回答
0
投票

这确实可能与您处理文件路径和变量的方式有关,尤其是在引号的情况下。让我们一步一步地解决潜在的问题:

  1. 确保正确使用引号: 确保所有文件路径都正确引用,特别是如果它们可能包含空格或特殊字符。

  2. 检查

    ffprobe
    命令: 验证 ffprobe 命令的正确性并确保它与您正在处理的视频兼容。如果我理解正确的话,这不是问题(但我只是想确定一下)。

  3. 强大的错误检查: 添加检查以处理

    ffprobe
    可能失败或返回意外结果的情况。

  4. 比特率的处理: 确保处理

    ffprobe
    返回的比特率的逻辑是健壮的并且可以处理各种场景。

  5. 简化和调试: 尽可能简化脚本并添加调试语句以帮助识别可能出现问题的位置。

这是脚本的修订版本,其中实施了其中一些建议:

@echo off
cd /d "%~dp0"
set "manifest=%~dpn0.txt"
set "temporary=%temp%\%~n0.tmp"

:: Check if input file exists
if not exist "%~1" (
    echo Input file not found.
    exit /b
)

:: Add to manifest if not a duplicate
findstr /c:"%~1" "%manifest%" >nul || echo "%~1">>"%manifest%"

:: Exit if HandBrakeCLI is already running
tasklist /fi "imagename eq handbrakecli.exe" | find /i "handbrakecli" && exit

:manifest
for /f "delims=" %%f in (%manifest%) do (
    set "in=%%~ff"
    set "out=%%~dpnf-2.mkv"
    call :transcode
)

for %%a in ("%manifest%") do if not %%~za lss 4 goto :manifest
exit /b

:transcode
if not exist "%in%" goto :cleanup
if exist "%out%" goto :cleanup

:: Retrieve bitrate
ffprobe "%in%" -v error -select_streams v:0 -show_entries stream=bit_rate -of default=noprint_wrappers=1:nokey=1 >"%temporary%"
set /p bitrate=<"%temporary%"

:: Check if bitrate was successfully retrieved
if not defined bitrate (
    echo Failed to fetch bitrate for "%in%"
    goto :cleanup
)

:: Reduce to full kilobytes and limit to 7000 Kbps
set /a bitrate=bitrate/1000
if %bitrate% gtr 7000 set bitrate=7000

:: Run HandBrakeCLI
HandBrakeCLI -i "%in%" -o "%out%" --encoder x265_10bit --vb %bitrate%K --two-pass --turbo --audio 1-9 --aencoder copy --audio-copy-mask aac,ac3,mp2,mp3,opus --audio-fallback opus --ab 160 --drc 2.0

:cleanup
findstr /v /c:"%in%" "%manifest%" > "%temporary%"
move /y "%temporary%" "%manifest%" >nul

主要变化:

  • 添加了在开始时检查输入文件是否存在。
  • 简化了比特率检索和计算部分。
  • -v error
    命令添加了
    ffprobe
    以抑制非错误消息。
  • 添加了针对未定义比特率的情况的错误处理。
  • 将比特率计算更改为千比特每秒 (Kbps)。

您应该使用各种视频文件测试此修订后的脚本,以确保其在不同场景下的行为符合预期。如果遇到特定错误,可以根据需要调整或添加更多调试信息。

我正在运行 macOS,所以我无法在您的环境下真正重新测试,但我认为这应该有效,或者至少提供一些关于您的脚本可能表现不同的地方的指示。


-2
投票

问题似乎可能与文件路径或变量中使用引号有关。使用文件路径时,正确处理空格和特殊字符至关重要。这是脚本的修改版本,进行了一些调整,以更可靠地处理带有空格的路径:

@echo off
cd /d "%~dp0"
set "manifest=%~dpn0.txt"
set "temporary=%temp%\%~n0.tmp"

:: input must exist and be no duplicate
if exist "%~1" findstr /c:"%~1" "%manifest%" >nul || echo "%~1">>"%manifest%"

:: exit all but the first instance
tasklist /fi "imagename eq handbrakecli.exe" | find /i "handbrakecli" && exit

:manifest
for /f "delims=" %%f in (%manifest%) do (
    set "in=%%~ff"
    set "out=%%~dpnf-2.mkv"
    call :transcode
)
for %%a in ("%manifest%") do if not %%~za lss 4 goto :manifest
exit /b

:transcode
if not exist "%in%" goto :cleanup
if exist "%out%" goto :cleanup

ffprobe "%in%" -v 0 -select_streams v:0 -show_entries stream=bit_rate -print_format compact=p=0:nokey=1 >"%temporary%"
set /p bitrate=<"%temporary%"
if not defined bitrate (
    echo Failed to fetch bitrate
    goto :cleanup
)

:: reduce to full kilobytes
set "bitrate=%bitrate:~0,-3%"
if %bitrate% gtr 7000 set bitrate=7000

HandBrakeCLI -i "%in%" -o "%out%" --encoder x265_10bit --vb %bitrate% --two-pass --turbo --audio 1-9 --aencoder copy --audio-copy-mask aac,ac3,mp2,mp3,opus --audio-fallback opus --ab 160 --drc 2.0

:cleanup
findstr /v /c:"%in%" "%manifest%" >"%temporary%"
move /y "%temporary%" "%manifest%" >nul
© www.soinside.com 2019 - 2024. All rights reserved.