Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ffmpeg video compression / specific file size

Tags:

Currently I have 80mb movies that I want to use ffmpeg to convert down to say about 10mb or 15mb. I know there will be a quality loss but they will need to have sound. Is there a way to either specify a file size or higher compression than what I have done previously

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

They are currently about 25mb a piece

like image 985
justin.esders Avatar asked Mar 16 '15 16:03

justin.esders


People also ask

How do I compress a video size in FFmpeg?

Download and set up FFmpeg on your computer, use command line to compress video with FFmpeg by changing video codec format, lowering down bitrate, cutting video length, etc. For example, set CRF in FFmpeg to reduce video file size (ffmpeg -i input. mp4 -vcodec libx264 -crf 24 output.

How do I set bitrate in FFmpeg?

To set the bitrate target in FFmpeg, use the -b:v code (bitrate:video) below : ffmpeg -i Test_1080p. MP4 -c:v libx264 -b:v 5000k Test_DR_5M.

How do I use FFmpeg without losing quality?

Instead of -sameq (removed by FFMpeg), use -qscale 0 : the file size will increase but it will preserve the quality.


2 Answers

if you are targeting a certain output file size the best way is to use H.264 and Two-Pass encoding.

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

You calculate your target bitrate using bitrate = target size / duration and you launch ffmpeg two times: one pass analyzes the media and the second does the actual encoding:

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) is even better at compression (50% of H.264 size in some cases) but support is not yet widespread so stick with H.264 for now.

like image 60
aergistal Avatar answered Sep 20 '22 13:09

aergistal


Inspired by Hashbrown's answer. This version keeps the original audio quality, and resizes to the target size.

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 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\n" "Target size ${T_SIZE}MB is too small!" >&2     printf "%s %s\n" "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

Hashbrown's answer (in this thread)

Two Pass method

like image 26
Marian Minar Avatar answered Sep 18 '22 13:09

Marian Minar