FFMPEG 命令可将视频加速/减速至特定时间

FFMPEG 命令可将视频加速/减速至特定时间

我一直在尝试弄清楚如何为 ffmpeg 编写一个过滤器来拍摄一组视频并使它们具有相同的时间长度。

例如,我有一个 35 秒的视频和一个 15 秒的视频,但我希望这两个视频都长 30 秒。

我知道我可以使用 setpts 过滤器来加快或减慢视频速度,但说实话我不懂过滤器。我知道 setpts 是“更改输入帧的 PTS(显示时间戳)”。但我不认为这是正确的过滤器,因为我认为它适用于帧的时间长度,与视频的时间长度无关。

答案1

假设你的输入文件是input.mp4,输出是output.mp4。你希望output.mp4输出长度大约为 30 秒。

您可以运行以下命令:

INPUT_FILE=input.mp4 && \
OUTPUT_FILE=output.mp4 && \
OUTPUT_DURATION=30 && \
CURRENT_DURATION=$(ffprobe -v error -show_format -show_streams -i "${INPUT_FILE}" | grep 'duration=' | head -n 1 | sed 's/duration=//') && \
echo "Found current duration ${CURRENT_DURATION} seconds" && \
SPEEDUP=$(( $CURRENT_DURATION / $OUTPUT_DURATION )) && \
echo "Processing conversion with speedup ${SPEEDUP}x" && \
ffmpeg \
    -hide_banner \
    -v warning \
    -i "${INPUT_FILE}" \
    -filter:v "setpts=PTS/${SPEEDUP}" \
    -filter:a "atempo=${SPEEDUP}" \
    "${OUTPUT_FILE}" && \
echo "Done! File written to ${OUTPUT_FILE}"

让我们分解一下。首先,我们使用以下命令查找文件时长:

ffprobe -v error -show_format -show_streams -i "${INPUT_FILE}" | grep 'duration=' | head -n 1 | sed 's/duration=//'

我们使用 获取持续时间,然后使用、和ffprobe的组合从输出中提取正确的数字。grepheadsed

接下来,我们将这个数量除以 30:

$(( $CURRENT_DURATION / $OUTPUT_DURATION ))

我们将其插入到 中,-filter:v "setpts=PTS/..."以获得正确的视频时间缩放,以实现加速或减速。最后,我们使用它-filter:a "atempo=..."来获得等效的音频缩放。

还请注意,这-hide_banner -v warning只是为了减少日志信息,但如果您愿意,可以将其删除。


atempo编辑 1:使用过滤器添加音频时间拉伸

答案2

我在 SPEEDUP 和 macos zsh 上遇到了一些问题,不允许浮点数,所以我改用

SPEEDUP=$(printf "%.2f" $(echo "scale=3; $CURRENT_DURATION / $OUTPUT_DURATION" | bc)) && \

这允许 2 位浮点数根据需要向上或向下舍入。

相关内容