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

ffmpeg视频压缩/特定文件大小,ffmpeg,Ffmpeg,目前我有80mb的电影,我想用ffmpeg将其转换为10mb或15mb左右。我知道会有质量损失,但他们需要声音。有没有一种方法可以指定文件大小或比我之前所做的更高的压缩 ffmpeg -i movie.mp4 -b 2255k -s 1280x720 movie.hd.ogv 它们目前约为25mb/块如果您针对特定的输出文件大小,最好的方法是使用H.264和两次编码 这里有一个很好的示例,但它太大,无法复制粘贴: 您使用bitrate=文件大小/持续时间计算目标比特率,并启动ffmpeg两次

目前我有80mb的电影,我想用ffmpeg将其转换为10mb或15mb左右。我知道会有质量损失,但他们需要声音。有没有一种方法可以指定文件大小或比我之前所做的更高的压缩

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

它们目前约为25mb/块

如果您针对特定的输出文件大小,最好的方法是使用H.264两次编码

这里有一个很好的示例,但它太大,无法复制粘贴:

您使用
bitrate=文件大小/持续时间
计算目标比特率,并启动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吧。

这里有一种方法可以通过bash脚本自动完成这项工作
只要像
/script.sh file.mp4 15
那样调用
15mB

bitrate=“$(awk)开始{print int($2*1024*1024*8/$(ffprobe)\
-v误差\
-显示项目格式=持续时间\
-默认值=noprint_wrappers=1:nokey=1\
"$1" \
)/1000)}“k”
ffmpeg\
-y\
-i“$1”\
-c:v libx264\
-预设媒体\
-b:v$比特率\
-通过1\
-一个\
-强积金4\
/dev/null\
&& \
ffmpeg\
-i“$1”\
-c:v libx264\
-预设媒体\
-b:v$比特率\
-通过2\
-一个\
“${1%.*}-$2mB.mp4”

注意:受哈什布朗答案的启发,我正在删掉音频。此版本保持原始音频质量,并根据目标大小调整大小

用法
/script original\u video.mp4大小

大小=以MB为单位的整数

剧本
#/bin/bash
target_video_size_MB=“$2”

origin_duration_s=$(ffprobe-v error-show_streams-选择_streams a“$1”| grep-Po”(?仅降低帧速率-如果您不需要像在教程中那样具有高帧速率-您将显著减小视频文件的大小,并且使用此过滤器您希望丢失音频同步


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

在您的计算中,文件大小和持续时间的单位是多少?@DrewChapin千位/秒H.265在速度较慢的PC或移动设备上也可能有害,因为它占用大量CPU。如何不剪切音频?好的。解决方案是用
-an
Mm删除行,我刚才没有不要尝试,因为它将不再匹配您想要的大小。要包含音频并有一个文件大小上限,您需要确定比特率,从而降低音频质量,而不仅仅是
-b:v
,还要确保这两个加起来正确。如果您想保持音频“原样”(我通常希望这样),然后您当然可以使用ffprobe之类的工具来确定音频曲目的大小。从目标大小中减去该大小,即可获得可用于视频曲目的剩余大小。我发现您需要从MP4容器的大小中减去2Mb。最近的一个示例是,将200Mb、720p视频缩小为640x360版本,目标是64Mb(获得63.9Mb):
ffmpeg-i in.mp4-filter:v scale=640:-1-c:a copy-b:v 630k out.mp4
;在输出视频中,
-c:a copy
为我提供原始音频。
如果文件路径包含空格,则第4行和第5行应引用$1
。在相关注释中,“编辑内容必须至少包含6个字符。”“对于编程网站来说,这是一条愚蠢的规则。
$1
s现在被引用,谢谢9072997。还是简称907?如果您的输入包含多个音频流,您可能需要更改
-选择\u streams a
-在两个ffprobe行上选择\u streams a:0
。它不应该是整数,我没有运行您的,但我的原始设置为“7.5”所以我认为你的可能/可能。这很方便,因为算法似乎过了调(8生成了一个8.5mB的文件,discord不喜欢,但7.8非常死板,没有降到7-flat),
1.048576
从何而来?
#!/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"