我需要一个脚本来切断多个视频的最后6秒。这些视频都有不同的长度。
我在网上找不到任何有用的东西。
有谁知道怎么做? THX
答案 0 :(得分:0)
你必须使用迂回的方式来实现这一目标,
ffmpeg -i file.mp4 -itsoffset 6 -i file.mp4 -c copy -map 0:a:0 -map 1 -shortest -f nut - | ffmpeg -y -i - -c copy -map 0 -map -0:0 -ss 6 trimmed.mp4
这会运行两个通过管道连接的ffmpeg进程,尽管你可以使用两个ffmpeg命令一个接一个地运行它。
第一个命令两次摄取文件,并将第二个输入的时间戳偏移6秒。它映射来自第一个输入的音频流和来自第二个输入的所有流。第一个命令的输出设置为以最短流终止,该最短流是来自第一个输入的音频流。副作用是第二个输入的最后6秒被切断。在第二个过程中,除第一个音频流之外的所有流都将被复制到一个新容器中。
如果您不确定文件是否包含音频,可以将-map 0:a:0
替换为-map 0:0
答案 1 :(得分:0)
使用ffprobe
获取输入持续时间的方法,bc
计算所需的输出持续时间,ffmpeg
执行切割。此方法不需要输入包含音频流,但它需要两个额外的工具(ffprobe
和bc
),而不仅仅是ffmpeg
。
您没有提及您首选的脚本语言,所以我假设bash会这样做。在请求的脚本表单中:
#!/bin/bash
for f in *.mp4; do
cut_duration=6
input_duration=$(ffprobe -v error -select_streams v:0 -show_entries stream=duration -of default=noprint_wrappers=1:nokey=1 "$f")
output_duration=$(bc <<< "$input_duration"-"$cut_duration")
ffmpeg -i "$f" -map 0 -c copy -t "$output_duration" output/"$f"
done
或者作为一行:
for f in *.mp4; do ffmpeg -i "$f" -map 0 -c copy -t "$(bc <<< "$(ffprobe -v error -select_streams v:0 -show_entries stream=duration -of default=noprint_wrappers=1:nokey=1 "$f")"-6)" output/"$f"; done
答案 2 :(得分:0)
对于Windows批处理文件几乎不可能做到这一点。这是Powershell的脚本:
$ListsFiles = Get-ChildItem "D:\VIDEOS\1\" -Filter *.avi;
Foreach ($file in $ListsFiles){
$input_d = [math]::round((ffprobe -v error -show_entries format=duration -of default=noprint_wrappers=1:nokey=1 $file.Fullname));
$output_duration=$input_d-5;
$ArgumentList = '-i "{0}" -map 0 -c copy -t {1} "D:\VIDEOS\1\output\{2}"' -f $file.Fullname, $output_duration, $file;
Write-Host -ForegroundColor Green -Object $ArgumentList;
Start-Process -FilePath ffmpeg -ArgumentList $ArgumentList -Wait -NoNewWindow;
}