English 中文(简体)
ffmpeg视频压缩/特定文档尺寸
原标题:ffmpeg video compression / specific file size
  • 时间:2015-03-16 16:47:38
  •  标签:
  • ffmpeg

目前,我有80米布的电影,我要使用ff子,改用10米布或15米布。 我知道,将出现质量损失,但需要健康。 是否有办法比我以前做过什么来说明档案的份量或高压。

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

目前约有25mb

问题回答

如果你以某种产出文档规模为目标,最好使用H.264。 2-Pas encoding

There is a great example here but it s too large to copy-paste: https://trac.ffmpeg.org/wiki/Encode/H.264#twopass

您使用<条码>比值=目标大小/期限计算其目标比值,并两次发射mpeg:一次通过分析分析媒体,第二次实际编码:

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

Edit:H.265(HEVC)的压缩率更高(有时是H.264的50%),但现在的支助还没有像H.264那样广泛。

Hashbrown的回答启发了这一看法。 该版本保持原有的音频质量,并转而达到目标规模。

<>strong>NEW

  1. Renamed variables for readability and consistency.
  2. Removed dependency on grep (-P switch not implemented in OSX grep)
  3. The script now exits with a helpful message if the target size would be too small.

Script

#!/bin/bash
#
# Re-encode a video to a target size in MB.
# Example:
#    ./this_script.sh video.mp4 15

T_SIZE="$2" # target size in MB
T_FILE="${1%.*}-$2MB.mp4" # filename out

# Original duration in seconds
O_DUR=$(
    ffprobe 
    -v error 
    -show_entries format=duration 
    -of csv=p=0 "$1")

# Original audio rate
O_ARATE=$(
    ffprobe 
    -v error 
    -select_streams a:0 
    -show_entries stream=bit_rate 
    -of csv=p=0 "$1")

# Original audio rate in KiB/s
O_ARATE=$(
    awk 
    -v arate="$O_ARATE" 
     BEGIN { printf "%.0f", (arate / 1024) } )

# Target size is required to be less than the size of the original audio stream
T_MINSIZE=$(
    awk 
    -v arate="$O_ARATE" 
    -v duration="$O_DUR" 
     BEGIN { printf "%.2f", ( (arate * duration) / 8192 ) } )

# Equals 1 if target size is ok, 0 otherwise
IS_MINSIZE=$(
    awk 
    -v size="$T_SIZE" 
    -v minsize="$T_MINSIZE" 
     BEGIN { print (minsize < size) } )

# Give useful information if size is too small
if [[ $IS_MINSIZE -eq 0 ]]; then
    printf "%s
" "Target size ${T_SIZE}MB is too small!" >&2
    printf "%s %s
" "Try values larger than" "${T_MINSIZE}MB" >&2
    exit 1
fi

# Set target audio bitrate
T_ARATE=$O_ARATE


# Calculate target video rate - MB -> KiB/s
T_VRATE=$(
    awk 
    -v size="$T_SIZE" 
    -v duration="$O_DUR" 
    -v audio_rate="$O_ARATE" 
     BEGIN { print  ( ( size * 8192.0 ) / ( 1.048576 * duration ) - audio_rate) } )

# Perform the conversion
ffmpeg 
    -y 
    -i "$1" 
    -c:v libx264 
    -b:v "$T_VRATE"k 
    -pass 1 
    -an 
    -f mp4 
    /dev/null 
&& 
ffmpeg 
    -i "$1" 
    -c:v libx264 
    -b:v "$T_VRATE"k 
    -pass 2 
    -c:a aac 
    -b:a "$T_ARATE"k 
    "$T_FILE"

NOTES

  • See comments for a possible Windows version.

SOURCES

https://stackoverflow.com/a/58122773/10059841”>Hashbrown s(在本校)

两种通行证方法

www.un.org/Depts/DGACM/index_spanish.htm 视窗版,因为链接不再在评论中发挥作用:

@echo off
REM Windows implementation of Marian Minar s answer to "ffmpeg video compression / specific file size" https://stackoverflow.com/a/61146975/2902367
SET "video=%~1"
SET "target_video_size_MB=%~2"
SET "output_file=%~dpn1 %~2MB.mp4"
REM I usually don t see a big difference between two-pass and single-pass... set to anything but "true" to turn off two-pass encoding
SET "twopass=true"
REM We need a way to do floating point arithmetic in CMD, here is a quick one. Change the path to a location that s convenient for you
set "mathPath=c:inMath.vbs"
REM Creating the Math VBS file
if not exist "%mathPath%" echo Wscript.echo replace(eval(WScript.Arguments(0)),",",".")>%mathPath%

echo Converting to %target_video_size_MB% MB: "%video%"
echo -^> "%output_file%"
pause
SETLOCAL EnableDelayedExpansion
REM Getting the (audio) duration. TODO: watch out for differing audio/video durations?
FOR /F "delims=" %%i IN ( ffprobe -v error -show_streams -select_streams a "%~1" ) DO (
    SET "line=%%i"
    if "!line:~0,9!" == "duration=" (
        SET "duration=!line:~9!"
    )
)
REM Getting the audio bitrate
FOR /F "delims=" %%i IN ( ffprobe -v error -pretty -show_streams -select_streams a "%~1" ) DO (
    SET "line=%%i"
    SET /A "c=0"
    if "!line:~0,9!" == "bit_rate=" (
        FOR %%a IN (!line:~9!) DO (
            if "!c!" == "0" (
                SET "audio_rate=%%a"
            )
            SET /A "c+=1"
        )
    )
)
REM TODO: Adjust target audio bitrate. Use source bitrate for now.
SET "target_audio_bitrate=%audio_rate%"

call:Math %target_video_size_MB% * 8192 / (1.048576 * %duration%) - %target_audio_bitrate%
SET "target_video_bitrate=%result%"

echo %target_audio_bitrate% audio, %target_video_bitrate% video

SET "passString="
if "%twopass%" == "true" (
    echo Two-Pass Encoding
    ffmpeg ^
        -y ^
        -i "%~1" ^
        -c:v libx264 ^
        -b:v %target_video_bitrate%k ^
        -pass 1 ^
        -an ^
        -f mp4 ^
        nul
    SET "passString=-pass 2"
) else ( echo Single-Pass Encoding )
ffmpeg ^
    -i "%~1" ^
    -c:v libx264 ^
    -b:v %target_video_bitrate%k ^
    %passString% ^
    -c:a aac ^
    -b:a %target_audio_bitrate%k ^
    "%output_file%"
    
pause
GOTO :EOF

:Math
REM echo Working : "%*"
for /f %%a in ( cscript /nologo %mathPath% "%*" ) do set "Result=%%a"
GOTO :EOF

Here s a way to do it automatically with a bash script
Just call like ./script.sh file.mp4 15 for 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 I m 剪辑

如果通过减少分辨率,将录音排出优先位置,那么,将录像尺寸(至<>)。

-filter:v "scale=-1:ih*1/2:force_original_aspect_ratio=decrease" -max_muxing_queue_size 1024





相关问题
Encode an Array of Images into a movie file? (iPhone)

My app takes time-lapse photos, and also records audio to go with it. The problem is, I have absolutely no idea how to go about turning it into a .mov/.mpeg file (I am new to this type of iPhone ...

How to use FFmpeg

I m trying to extract frames from a video and I ve picked ffmpeg ( tell me if you know something better ) for this task. I ve downloaded its source and don t know how to use it ?? how can I compile it?...

stitching videos together using ffmpeg on the command line

Does anybody know how to stitch two (or more) videos together using ffmpeg (or another cli)? This is assuming that all the videos are in the same format and the video format being used allows for ...

Using FFmpeg or wrapper to get mp3 from mp4 in C#

I m trying to extract an mp3 from a flash compatible mp4 file and have so far found FFMpeg and a bunch of different wrappers that all claim to be able to do the job. Ideally, I d like to not have to ...

Convert a video to MP4 (H.264/AAC) with ffmpeg

If I don t make a mistake, Safari currently need MP4 (H.264/AAC) video encoded for the HTML5 <video> element. So I tried to convert a video to this format with ffmpeg. However when I enter the ...

calculating filesize of a response?

im tryingto code a script to do dynamic transcoding of video and audio (likely just audio for now) and streaming to mobile devices, currently im using the script posted elsewhere on here (How do you ...

C# and FFmpeg preferably without shell commands?

I d like to be able to use FFmpeg to convert a video file from within my C# program. I know I can just call a shell command, but is there a better way? The issue with invoking a command via the ...

convert movie file to bitmap files with DirectShow

I want to convert movie files like AVI, MOV etc. to Bitmap-Files, like JPEG, JPEG2000, TIFF etc. Is it possible to realize that with DirectX / DirectShow? Is AVCodec from ffmpeg the much more better ...