削减多个视频的结尾

时间:2018-04-22 09:03:40

标签: video ffmpeg trim cut

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

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

有谁知道怎么做? THX

3 个答案:

答案 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执行切割。此方法不需要输入包含音频流,但它需要两个额外的工具(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

答案 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;    
}