ffmpeg视频压缩/特定文件大小

时间:2015-03-16 16:47:39

标签: ffmpeg

目前我有80mb电影我想用ffmpeg转换成大约10mb或15mb。我知道会有质量损失,但他们需要有声音。有没有办法指定文件大小或更高的压缩比我以前做的

ffmpeg -i movie.mp4 -b 2255k -s 1280x720 movie.hd.ogv

他们目前约有25mb一件

4 个答案:

答案 0 :(得分:17)

如果您要定位某个输出文件大小,最好的方法是使用 H.264 双通道编码

这里有一个很好的例子,但复制粘贴太大了: https://trac.ffmpeg.org/wiki/Encode/H.264

您使用bitrate = file size / duration计算目标比特率,然后启动 ffmpeg 两次:一次分析媒体,第二次执行实际编码:

ffmpeg -y -i input -c:v libx264 -preset medium -b:v 555k -pass 1 -c:a libfdk_aac -b:a 128k -f mp4 /dev/null && \
ffmpeg -i input -c:v libx264 -preset medium -b:v 555k -pass 2 -c:a libfdk_aac -b:a 128k output.mp4

编辑:H.265(HEVC)在压缩方面甚至更好(在某些情况下为H.264大小的50%),但支持尚未普及,因此现在坚持使用H.264。

答案 1 :(得分:8)

受Hashbrown的回答启发。此版本保持原始音频质量,并调整为目标大小。

用法

./script original_video.mp4 size

size =以MB为单位的整数

脚本

#!/bin/bash

target_video_size_MB="$2"
origin_duration_s=$(ffprobe -v error -show_streams -select_streams a "$1" | grep -Po "(?<=^duration\=)\d*\.\d*")
origin_audio_bitrate_kbit_s=$(ffprobe -v error -pretty -show_streams -select_streams a "$1" | grep -Po "(?<=^bit_rate\=)\d*\.\d*")
target_audio_bitrate_kbit_s=$origin_audio_bitrate_kbit_s # TODO for now, make audio bitrate the same
target_video_bitrate_kbit_s=$(\
    awk \
    -v size="$target_video_size_MB" \
    -v duration="$origin_duration_s" \
    -v audio_rate="$target_audio_bitrate_kbit_s" \
    'BEGIN { print  ( ( size * 8192.0 ) / ( 1.048576 * duration ) - audio_rate ) }')

ffmpeg \
    -y \
    -i "$1" \
    -c:v libx264 \
    -b:v "$target_video_bitrate_kbit_s"k \
    -pass 1 \
    -an \
    -f mp4 \
    /dev/null \
&& \
ffmpeg \
    -i "$1" \
    -c:v libx264 \
    -b:v "$target_video_bitrate_kbit_s"k \
    -pass 2 \
    -c:a aac \
    -b:a "$target_audio_bitrate_kbit_s"k \
    "${1%.*}-$2mB.mp4"

待办事项/愿望清单

  1. 中止目标大小是否小于可能的大小(假设用户要求的大小小于音频流大小等)
  2. 警告目标尺寸是否会导致视频比特率严重降低

注释

  • 我尝试避免将bc用作计算器,而是选择了awk(不确定是否很酷,但是可以)
  • 我的视频上收到“输出中非单调DTS”警告-如何解决?
  • 如果尝试将其移植到Windows脚本:用户应使用NUL而不是/dev/null^而不是\

来源

哈希布朗的答案(在这里)https://stackoverflow.com/a/58122773/10059841

两次通过方法https://trac.ffmpeg.org/wiki/Encode/H.264#twopass

答案 2 :(得分:1)

这是一种使用bash脚本自动执行操作的方法
./script.sh file.mp4 15一样为15mB

打电话
bitrate="$(awk "BEGIN {print int($2 * 1024 * 1024 * 8 / $(ffprobe \
    -v error \
    -show_entries format=duration \
    -of default=noprint_wrappers=1:nokey=1 \
    "$1" \
) / 1000)}")k"
ffmpeg \
    -y \
    -i "$1" \
    -c:v libx264 \
    -preset medium \
    -b:v $bitrate \
    -pass 1 \
    -an \
    -f mp4 \
    /dev/null \
&& \
ffmpeg \
    -i "$1" \
    -c:v libx264 \
    -preset medium \
    -b:v $bitrate \
    -pass 2 \
    -an \
    "${1%.*}-$2mB.mp4"

NB我要剪掉音频

答案 3 :(得分:-3)

只需降低帧速率-如果不需要像教程中那样高的帧速率-您将大大减小视频文件的大小,并且使用此过滤器您将失去音频同步

ffmpeg -i input.mp4 -filter:v fps = fps = 10 output.mp4