剪切多个视频的结尾

Cut end of multiple videos

我需要一个脚本来截断多个视频的最后 6 秒。这些视频确实都有不同的长度。

我在网上找不到任何有用的东西。

有人知道怎么做吗? 谢谢

你必须使用迂回的方式来实现这个,

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

一种方法,使用ffprobe获取输入时长,bc计算所需输出时长,ffmpeg执行切割。此方法不要求输入包含音频流,但它需要两个额外的工具(ffprobebc),而不仅仅是 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

windows 批处理文件几乎不可能做到这一点。这是 Powershell 的脚本:

$ListsFiles = Get-ChildItem "D:\VIDEOS\" -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\output\{2}"' -f $file.Fullname, $output_duration, $file;
    Write-Host -ForegroundColor Green -Object $ArgumentList;   
    Start-Process -FilePath ffmpeg -ArgumentList $ArgumentList -Wait -NoNewWindow;    
}