吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 289|回复: 7
收起左侧

[其他求助] 求大佬帮忙把这个ffmpeg脚本转成bat脚本

[复制链接]
小情歌 发表于 2024-10-16 17:24
100吾爱币
求大佬帮忙把这个ffmpeg脚本转成bat脚本,并且实现批量处理video文件夹下的所有mp4文件,同名输出到video/output/。
我自己修改后不是gif计算出错就是进度条误差大各种问题。

[Shell] 纯文本查看 复制代码
#!/bin/bash
data=`ffprobe -hide_banner -show_format -show_streams input.mp4 2>&1`
time=`echo $data |awk -F 'duration=' '{print $2}' | awk -F ' ' '{print $1}'`
width=`echo $data |awk -F 'width=' '{print $2}' | awk -F ' ' '{print $1}'`
height=`echo $data |awk -F 'height=' '{print $2}' | awk -F ' ' '{print $1}'`

gif_h=$(($((height))/30))
gif_w=$gif_h
box_w=$(($((width))-$((gif_w))/2))
box_h=$gif_h
input_file=input.mp4
gif=input.gif
overlay_x=(W-w)*t/$time
overlay_y=H-h

ffmpeg -i $input_file -c:v libx264 -filter_complex "color=#[email]EEA9B8@0.2[/email]:"$box_w"x"$box_h"[box];movie=$gif:loop=0,setpts=N/FRAME_RATE/TB,scale="$gif_w"x"$gif_h" [mov];[0:v][box]overlay=shortest=1:x=t/"$time"*(W-"$gif_w")-(w-"$gif_w"/2):y=H-h[cache];[cache][mov]overlay=x='$overlay_x':y='$overlay_y'" -c:a copy -shortest output.mp4

最佳答案

查看完整内容

这个用cmd做,处理浮点数和复杂的字符串操作可能会比较棘手。我试了好几个方案,都未能达到满意效果。windows下可以使用powershell,和cmd是一样的,你以前打开cmd输入的是cmd,现在输入powershell。cmd是bat文件,ps就是ps1文件。你把以下代码粘贴过去就行了。我已经测试过了,这个就是把视频文件最底下加个gif水印然后水平匀速移动。要注意的是,如果提示的你powershell没权限,你要在ps里输入Set-ExecutionPolicy RemoteSigned ...

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

bleachko 发表于 2024-10-16 17:24
这个用cmd做,处理浮点数和复杂的字符串操作可能会比较棘手。我试了好几个方案,都未能达到满意效果。windows下可以使用powershell,和cmd是一样的,你以前打开cmd输入的是cmd,现在输入powershell。cmd是bat文件,ps就是ps1文件。你把以下代码粘贴过去就行了。我已经测试过了,这个就是把视频文件最底下加个gif水印然后水平匀速移动。要注意的是,如果提示的你powershell没权限,你要在ps里输入Set-ExecutionPolicy RemoteSigned,然后选择全是,就可以正常运行了。
[PowerShell] 纯文本查看 复制代码
# 设置输入文件
$inputFile = "input.mp4"
$gifFile = "input.gif"

# 使用ffprobe获取视频信息
$videoInfo = & ffprobe -v quiet -print_format json -show_format -show_streams $inputFile | ConvertFrom-Json

# 提取视频信息
$duration = [math]::Floor([double]$videoInfo.format.duration)
$width = $videoInfo.streams[0].width
$height = $videoInfo.streams[0].height

# 计算GIF和覆盖框的尺寸
$gifH = [math]::Floor($height / 30)
$gifW = $gifH
$boxW = $width - [math]::Floor($gifW / 2)
$boxH = $gifH

# 确保所有尺寸至少为1
$gifH = [math]::Max(1, $gifH)
$gifW = [math]::Max(1, $gifW)
$boxW = [math]::Max(1, $boxW)
$boxH = [math]::Max(1, $boxH)

# 设置覆盖位置
$overlayX = "(W-w)*t/$duration"
$overlayY = "H-h"

# 输出调试信息
Write-Host "Video dimensions: ${width}x${height}"
Write-Host "Duration: $duration seconds"
Write-Host "Box dimensions: ${boxW}x${boxH}"
Write-Host "GIF dimensions: ${gifW}x${gifH}"

# 构建ffmpeg命令
$ffmpegCmd = "ffmpeg -i `"$inputFile`" -i `"$gifFile`" -filter_complex " + `
    "`"color=#[email]EEA9B8@0.2[/email]:${boxW}x${boxH}[box];" + `
    "[1:v]loop=-1:53,setpts=N/FRAME_RATE/TB,scale=${gifW}x${gifH}[mov];" + `
    "[0:v][box]overlay=shortest=1:x='if(gte(t,$duration),0,t/$duration*(W-$gifW)-(W-$gifW/2))':y=H-h[cache];" + `
    "[cache][mov]overlay=x='if(gte(t,$duration),0,(W-w)*t/$duration)':y=$overlayY`" " + `
    "-c:v libx264 -c:a copy -shortest output.mp4"

# 执行ffmpeg命令
Invoke-Expression $ffmpegCmd

if ($LASTEXITCODE -eq 0) {
    Write-Host "Processing complete. Output file: output.mp4"
} else {
    Write-Host "An error occurred during FFmpeg processing."
}

Read-Host -Prompt "Press Enter to exit"


pxhzai 发表于 2024-10-16 17:54
阿里千问

将上述 Bash 脚本转换为 Windows 的批处理(.bat)脚本需要考虑到几个关键点:

1. Windows 的命令行工具与 Linux 工具不同,例如 `ffprobe` 在 Windows 下的使用可能略有不同。
2. Windows 批处理文件中没有 shell 的概念,因此不需要以 `#!/bin/bash` 开头。
3. 变量赋值和引用的方式也有所不同。
4. 在 Windows 中,通常使用 `set` 命令来定义变量,并且在引用变量时需要使用 `%variable%` 格式。
5. AWK 工具在 Windows 上通常不可用,需要使用其他方法来解析数据,例如 `findstr` 或 `powershell`。

下面是转换后的 .bat 脚本示例。请注意,这里假设 `ffprobe` 和 `ffmpeg` 都已经被正确安装并且可以在命令行中直接调用。

```bat
@echo off
setlocal enabledelayedexpansion

rem 获取视频信息
for /f "tokens=* delims=[" %%a in ('ffprobe -hide_banner -show_format -show_streams "%~dp0\input.mp4" 2^>nul') do (
    set data=%%a
)

rem 提取 duration, width, height
set time=
for /f "tokens=2 delims==" %%a in ('echo !data! ^| findstr /R /C:"duration="') do (
    set time=%%a
)
set time=!time: =!

set width=
for /f "tokens=2 delims==" %%a in ('echo !data! ^| findstr /R /C:"width="') do (
    set width=%%a
)
set width=!width: =!

set height=
for /f "tokens=2 delims==" %%a in ('echo !data! ^| findstr /R /C:"height="') do (
    set height=%%a
)
set height=!height: =!

rem 计算 gif 的尺寸
set gif_h=%height%/30
set gif_w=%gif_h%
set box_w=%width%-%gif_w%/2
set box_h=%gif_h%

rem 定义文件名
set input_file=%~dp0\input.mp4
set gif=%~dp0\input.gif

rem 计算 overlay 的位置
set overlay_x=(W-%gif_w%)*t/%time%-(w-%gif_w%/2)
set overlay_y=H-%height%

rem 使用 ffmpeg 创建带有 gif 的输出视频
ffmpeg -i "%input_file%" -vf "color=c=#eea9b8@0.2:%box_w%:%box_h%[box];movie=%gif%:loop=0,setpts=N/FRAME_RATE/TB,scale=%gif_w%:%gif_h%[mov];[0:v][box]overlay=shortest=1:x=t/%time%*(W-%gif_w%)-(w-%gif_w%/2):y=H-%height%[cache];[cache][mov]overlay=x=%overlay_x%:y=%overlay_y%" -c:a copy -shortest "%~dp0\output.mp4"

endlocal
```

这个脚本应该能在 Windows 环境下运行,但是请注意,`ffprobe` 和 `ffmpeg` 必须已经安装并且在系统的 PATH 中。此外,该脚本假设了 `input.mp4` 文件位于与批处理文件相同的目录中。如果你有更复杂的需求或遇到任何问题,请随时提问。
 楼主| 小情歌 发表于 2024-10-16 19:09
blfiag 发表于 2024-10-17 10:20
最有可能是两个平台的ffmpeg不同,win下是不是不完整?
ugvfpdcuwfnh 发表于 2024-10-17 14:08
llama 3.2的回复:


这里是等效的批处理脚本,它对`video`文件夹下的所有MP4文件执行相同的操作,并将结果输出到`video/output`文件夹中:
```
@echo off
setlocal enabledelayedexpansion

for %%f in (video\*.mp4) do (
  set "input_file=%%~nf"
  set "gif_file=!input_file!.gif"
  set "output_file=video\output\!input_file!.mp4"

  for /f "tokens=2 delims==" %%a in ('ffprobe -hide_banner -show_format -show_streams "%%f" 2^>^&1 ^| findstr /c:"duration="') do set "time=%%a"
  for /f "tokens=2 delims==" %%a in ('ffprobe -hide_banner -show_format -show_streams "%%f" 2^>^&1 ^| findstr /c:"width="') do set "width=%%a"
  for /f "tokens=2 delims==" %%a in ('ffprobe -hide_banner -show_format -show_streams "%%f" 2^>^&1 ^| findstr /c:"height="') do set "height=%%a"

  set /a "gif_h=!height!/30"
  set /a "gif_w=!gif_h!"
  set /a "box_w=!width!-!gif_w!/2"
  set /a "box_h=!gif_h!"
  set "overlay_x=(W-w)*t/!time!"
  set "overlay_y=H-h"

  ffmpeg -i "%%f" -c:v libx264 -filter_complex "color=#EEA9B8@0.2:!box_w!x!box_h![box];movie=!gif_file!:loop=0,setpts=N/FRAME_RATE/TB,scale=!gif_w!x!gif_h! [mov];[0:v][box]overlay=shortest=1:x=t/!time!*(W-!gif_w!)-(w-!gif_w!/2):y=H-h[cache];[cache][mov]overlay=x=!overlay_x!:y=!overlay_y!"" -c:a copy -shortest "!output_file!"
)
```
注意我使用了`for`循环来遍历`video`文件夹下的所有MP4文件,并使用`%%~nf`语法来获取文件名(不包括扩展名)。我还使用了`setlocal enabledelayedexpansion`命令来启用延迟扩展,这样就可以在循环中使用`!`字符来访问变量。

另外,我使用了`findstr`命令来从`ffprobe`的输出中提取持续时间、宽度和高度值,而不是像原始脚本那样使用`awk`。

您可以将此脚本保存为批处理文件(例如`convert_videos.bat`),然后在命令行中运行它,以处理`video`文件夹下的所有MP4文件。
Dmark 发表于 2024-10-17 15:20
[Shell] 纯文本查看 复制代码
@echo off
setlocal enabledelayedexpansion

REM 设置 ffmpeg 和 ffprobe 的路径
set ffmpeg_path="C:\path\to\ffmpeg.exe"
set ffprobe_path="C:\path\to\ffprobe.exe"

REM 创建输出目录
if not exist "video\output\" mkdir "video\output"

REM 遍历 video 文件夹下的所有 mp4 文件
for %%f in (video\*.mp4) do (
    set "input_file=%%f"
    set "output_file=video\output\%%~nf_output.mp4"

    REM 获取视频信息
    for /f "tokens=2 delims==" %%a in ('%ffprobe_path% -hide_banner -show_format -show_streams "!input_file!" ^| find "duration="') do set "time=%%a"
    for /f "tokens=2 delims==" %%a in ('%ffprobe_path% -hide_banner -show_format -show_streams "!input_file!" ^| find "width="') do set "width=%%a"
    for /f "tokens=2 delims==" %%a in ('%ffprobe_path% -hide_banner -show_format -show_streams "!input_file!" ^| find "height="') do set "height=%%a"

    REM 计算 gif 和 box 的尺寸
    set /a gif_h=!height!/30
    set /a gif_w=!gif_h!
    set /a box_w=!width!-!gif_w!/2
    set /a box_h=!gif_h!

    REM 设置 gif 文件路径
    set "gif=input.gif"

    REM 执行 ffmpeg 命令
    %ffmpeg_path% -i "!input_file!" -c:v libx264 -filter_complex "color=EEA9B8@0.2:!box_w!x!box_h![box];movie=!gif!:loop=0,setpts=N/FRAME_RATE/TB,scale=!gif_w!x!gif_h! [mov];[0:v][box]overlay=shortest=1:x=t/!time!*(W-!gif_w!)-(w-!gif_w!/2):y=H-h[cache];[cache][mov]overlay=x=(W-w)*t/!time!:y=H-h" -c:a copy -shortest "!output_file!"
)

echo 处理完成
pause



解释脚本
  • 设置环境变量:脚本首先设置了 ffmpeg 和 ffprobe 的路径。请根据您的实际安装路径进行修改。
  • 创建输出目录:如果 video\output 目录不存在,则创建它。
  • 遍历文件:使用 for 循环遍历 video 文件夹下的所有 .mp4 文件。
  • 获取视频信息:使用 ffprobe 获取视频的时长、宽度和高度。
  • 计算尺寸:根据获取的视频信息计算 gif 和 box 的尺寸。
  • 执行 ffmpeg 命令:使用 ffmpeg 处理视频文件,并将结果输出到 video\output 目录。
3. 注意事项
  • 路径问题:确保 ffmpeg 和 ffprobe 的路径正确,并且 video 文件夹和 input.gif 文件存在。
  • 权限问题:确保脚本在运行时有足够的权限访问和修改文件。
  • 性能问题:批处理脚本在处理大量文件时可能会比较慢,建议在测试时先处理少量文件。
将上述脚本保存为 .bat 文件,然后在命令提示符中运行它,即可批量处理 video 文件夹下的所有 .mp4 文件。

[Shell] 纯文本查看 复制代码
@echo off
setlocal enabledelayedexpansion

REM 设置 ffmpeg 和 ffprobe 的路径
set ffmpeg_path="C:\path\to\ffmpeg.exe"
set ffprobe_path="C:\path\to\ffprobe.exe"

REM 创建输出目录
if not exist "video\output\" mkdir "video\output"

REM 遍历 video 文件夹下的所有 mp4 文件
for %%f in (video\*.mp4) do (
    set "input_file=%%f"
    set "output_file=video\output\%%~nf_output.mp4"

    REM 获取视频信息
    for /f "tokens=2 delims==" %%a in ('%ffprobe_path% -hide_banner -show_format -show_streams "!input_file!" ^| find "duration="') do set "time=%%a"
    for /f "tokens=2 delims==" %%a in ('%ffprobe_path% -hide_banner -show_format -show_streams "!input_file!" ^| find "width="') do set "width=%%a"
    for /f "tokens=2 delims==" %%a in ('%ffprobe_path% -hide_banner -show_format -show_streams "!input_file!" ^| find "height="') do set "height=%%a"

    REM 计算 gif 和 box 的尺寸
    set /a gif_h=!height!/30
    set /a gif_w=!gif_h!
    set /a box_w=!width!-!gif_w!/2
    set /a box_h=!gif_h!

    REM 设置 gif 文件路径
    set "gif=input.gif"

    REM 执行 ffmpeg 命令
    %ffmpeg_path% -i "!input_file!" -c:v libx264 -filter_complex "color=EEA9B8@0.2:!box_w!x!box_h![box];movie=!gif!:loop=0,setpts=N/FRAME_RATE/TB,scale=!gif_w!x!gif_h! [mov];[0:v][box]overlay=shortest=1:x=t/!time!*(W-!gif_w!)-(w-!gif_w!/2):y=H-h[cache];[cache][mov]overlay=x=(W-w)*t/!time!:y=H-h" -c:a copy -shortest "!output_file!"
)

echo 处理完成
pause



注意事项和改进点
  • 数学运算:
    • 确保所有的数学运算都正确。批处理脚本中的数学运算可能会受到整数除法的影响,导致结果不准确。可以使用浮点数运算库(如 bc)来提高精度,但需要在 Windows 上找到合适的替代方案。
  • 变量处理:
    • 使用 setlocal enabledelayedexpansion 和 !variable! 来正确处理循环中的变量。
  • 路径和文件名:
    • 确保 ffmpeg 和 ffprobe 的路径正确,并且 video 文件夹和 input.gif 文件存在。
  • 错误处理:
    • 添加错误处理机制,以便在出现问题时能够捕获并报告错误。

测试和调试
  • 单个文件测试:
    • 先对单个文件进行测试,确保脚本能够正确处理该文件。
  • 日志记录:
    • 添加日志记录功能,将关键步骤的输出记录到日志文件中,以便调试和分析。
  • 逐步执行:
    • 逐步执行脚本,检查每个步骤的输出,确保每个变量和计算结果都符合预期。

示例日志记录
[Shell] 纯文本查看 复制代码
@echo off
setlocal enabledelayedexpansion

REM 设置 ffmpeg 和 ffprobe 的路径
set ffmpeg_path="C:\path\to\ffmpeg.exe"
set ffprobe_path="C:\path\to\ffprobe.exe"

REM 创建输出目录
if not exist "video\output\" mkdir "video\output"

REM 遍历 video 文件夹下的所有 mp4 文件
for %%f in (video\*.mp4) do (
    set "input_file=%%f"
    set "output_file=video\output\%%~nf_output.mp4"

    REM 获取视频信息
    for /f "tokens=2 delims==" %%a in ('%ffprobe_path% -hide_banner -show_format -show_streams "!input_file!" ^| find "duration="') do set "time=%%a"
    for /f "tokens=2 delims==" %%a in ('%ffprobe_path% -hide_banner -show_format -show_streams "!input_file!" ^| find "width="') do set "width=%%a"
    for /f "tokens=2 delims==" %%a in ('%ffprobe_path% -hide_banner -show_format -show_streams "!input_file!" ^| find "height="') do set "height=%%a"

    REM 计算 gif 和 box 的尺寸
    set /a gif_h=!height!/30
    set /a gif_w=!gif_h!
    set /a box_w=!width!-!gif_w!/2
    set /a box_h=!gif_h!

    REM 设置 gif 文件路径
    set "gif=input.gif"

    REM 记录日志
    echo Input File: !input_file! >> log.txt
    echo Time: !time! >> log.txt
    echo Width: !width! >> log.txt
    echo Height: !height! >> log.txt
    echo Gif Height: !gif_h! >> log.txt
    echo Gif Width: !gif_w! >> log.txt
    echo Box Width: !box_w! >> log.txt
    echo Box Height: !box_h! >> log.txt

    REM 执行 ffmpeg 命令
    %ffmpeg_path% -i "!input_file!" -c:v libx264 -filter_complex "color=EEA9B8@0.2:!box_w!x!box_h![box];movie=!gif!:loop=0,setpts=N/FRAME_RATE/TB,scale=!gif_w!x!gif_h! [mov];[0:v][box]overlay=shortest=1:x=t/!time!*(W-!gif_w!)-(w-!gif_w!/2):y=H-h[cache];[cache][mov]overlay=x=(W-w)*t/!time!:y=H-h" -c:a copy -shortest "!output_file!"
)

echo 处理完成
pause

RootPotence 发表于 2024-10-17 16:52
[Bash shell] 纯文本查看 复制代码
@echo off
setlocal enabledelayedexpansion

:: 设置输入和输出文件夹
set "input_folder=video"
set "output_folder=video\output"

:: 创建输出文件夹(如果不存在)
if not exist "%output_folder%" mkdir "%output_folder%"

:: 遍历视频文件夹中的所有 .mp4 文件
for %%f in ("%input_folder%\*.mp4") do (
    :: 获取文件名(不带路径)
    set "filename=%%~nxf"
    
    :: 使用 ffprobe 获取视频信息
    for /f "tokens=*" %%a in ('ffprobe -hide_banner -show_format -show_streams "%%f" 2^>^&1') do (
        set "data=%%a"
    )
    
    :: 提取视频时长、宽度和高度
    for /f "tokens=2 delims==" %%a in ('echo !data! ^| findstr /C:"duration="') do (
        set "time=%%a"
    )
    for /f "tokens=2 delims==" %%a in ('echo !data! ^| findstr /C:"width="') do (
        set "width=%%a"
    )
    for /f "tokens=2 delims==" %%a in ('echo !data! ^| findstr /C:"height="') do (
        set "height=%%a"
    )
    
    :: 计算 gif 尺寸和位置
    set /a gif_h=%height%/30
    set /a gif_w=%gif_h%
    set /a box_w=%width%-%gif_w%/2
    set /a box_h=%gif_h%
    
    :: 计算 overlay 参数
    set "overlay_x=(W-w)*t/%time%-(w-%gif_w%/2)"
    set "overlay_y=H-h"
    
    :: 处理视频
    ffmpeg -i "%%f" -c:v libx264 -filter_complex "color=#EEA9B8@0.2:%box_w%x%box_h%[box];movie=%%~nf.gif:loop=0,setpts=N/FRAME_RATE/TB,scale=%gif_w%x%gif_h% [mov];[0:v][box]overlay=shortest=1:x=t/%time%*(W-%gif_w%)-(w-%gif_w%/2):y=H-h[cache];[cache][mov]overlay=x='%overlay_x%':y='%overlay_y%'" -c:a copy -shortest "%output_folder%\!filename!"
)

endlocal
pause
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-12-14 04:56

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表