LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   FFMPEG reduce a video to specific file size and keep best quality (https://www.linuxquestions.org/questions/programming-9/ffmpeg-reduce-a-video-to-specific-file-size-and-keep-best-quality-4175734915/)

blumenwesen 03-14-2024 07:30 PM

FFMPEG reduce a video to specific file size and keep best quality
 
The videos have 1.5gb to 10gb, length 0.20h to 10h, and the target size should not exceed about 1gb.
Similar to the example but with the best possible quality, can libx265 be used or better option than in the example?

teckk 03-14-2024 08:14 PM

Quote:

FFMPEG reduce a video to specific file size and keep best quality
Those 2 things don't go together.

I haven't done that with ffmpeg for a while. The formula to calculate filesize for a bitrate is:
Code:

(Desired_size_MB * 8350) / seconds_of_video.0) - Sound_kbps = video_bitrate
1 hour video, 1GB file size, 192k audio:
Code:

((1000*8350)/3600.0) - 192 = 2127.44
I would use x264, x265 presets instead.
Code:

ffmpeg -i file.mp4 -c:a copy -c:v libx264 -crf 18 -preset slow -r 24 -s 300x168 out.mp4
-preset slower veryslow placebo will give smaller file size, but will take longer to encode.

blumenwesen 03-15-2024 11:20 AM

How can I use "-crf" for the best quality without first manually testing and calculating to get the average size from about 1gb to a maximum of 1.5gb?

The videos have very different values 1="size:3889957442, bit_rate:2108103 duration:14762", 2="size:1856409823, bit_rate:6785433 duration:2189", 3="size:1752405186, bit_rate:1841002 duration:7779".
I think video1 would have to be strongly compressed by size with regard to quality because of medium bitrate and long duration, video2 would have to be compressed a little more because duration is short and bitrate is high, video3 would have to be compressed with regard to quality because of longer duration and low bitrate.

There are a lot of videos to be edited, so I would have to calculate a suitable crf value in my opinion.
Is there a better way or can my example still be optimized?

Code:

ar0=(1079775913 1371610925 1752405186 1856409823 1857346492 2035982939 3889957442); ar1=(4338506 3460210 1841002 6785433 5915325 1324780 2108103); ar2=(1991 3271 7779 2189 2512 12295 14762);
for ((z=0; z<${#ar0[@]}; z++)); do y="${ar0[$z]}"; x="${ar1[$z]}"; w="${ar2[$z]}";
echo -e "$y\t$x\t$w\t" $[ (47+((($y/(9**8))/(7*6))-(5+(($y/($[${#y}+4]#$[$y/32]))+10)))) ] $[ ((($x^(${#x}^9))>>18)-(20-${#x})) ] $[ ((((5*4)-($w/(32#10${#w})))/6)+((((7**8)/$w)-${#w})>>9)) ];
done

Quote:

sGB size bytes bitrate durat results > > < 0-51
1,1 1079775913 4338506 1991 29 3 8 . - . 15
1,2 1371610925 3460210 3271 29 0 5 . . - 20
1,8 1752405186 1841002 7779 29 -6 3 . . - 25
1,9 1856409823 6785433 2189 30 12 8 - ÷ . 28
1,9 1857346492 5915325 2512 30 9 7 - ÷ . 28
2,0 2035982939 1324780 12295 30 -8 1 - . ÷ 30
3,9 3889957442 2108103 14762 32 -5 1 ÷ - ÷ 37
prognosis "."=2±, "-"=5±, "÷"=7± crf

blumenwesen 03-16-2024 09:53 AM

I simplified the crasy calculation. :D

Code:

ar0=(832655422 927902511 1079775913 1371610925 1752405186 1856409823 1857346492 2035982939 3889957442); ar1=(1853011 5084258 4338506 3460210 1841002 6785433 5915325 1324780 2108103); ar2=(3595 1460 1991 3271 7779 2189 2512 12295 14762); for ((z=0; z<${#ar0[@]}; z++)); do y="${ar0[$z]}"; x="${ar1[$z]}"; w="${ar2[$z]}";
echo -e "$y\t$x\t$w\t" $[ ((($y/707788800)+22)+((($x/691200)+($w/1500))/3)) ]
done

Results
size bitrate duration = possible CRF
Quote:

832655422 1853011 3595 = 24
927902511 5084258 1460 = 25
1079775913 4338506 1991 = 25
1371610925 3460210 3271 = 25
1752405186 1841002 7779 = 26
1856409823 6785433 2189 = 27
1857346492 5915325 2512 = 27
2035982939 1324780 12295 = 27
3889957442 2108103 14762 = 31
I can't test the compression on my slow pc, a single video would be converted for days.
How can I optimize the result for CRF, and could the results be approximately suitable for the respective video size?

teckk 03-16-2024 01:55 PM

Why don't you look and see how youtube does it.

Code:

yt-dlp -f 22 https://m.youtube.com/watch?v=UIYEuDs7wBA -o NovemberMan.mp4

ffprobe NovemberMan.mp4
...
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'NovemberMan.mp4':
  Metadata:
    major_brand    : mp42
    minor_version  : 0
    compatible_brands: isommp42
    creation_time  : 2023-10-22T20:43:07.000000Z
  Duration: 01:44:34.10, start: 0.000000, bitrate: 491 kb/s
  Stream #0:0[0x1](und): Video: h264 (Main) (avc1 / 0x31637661), yuv420p(tv, bt709, progressive), 1280x536 [SAR 1:1 DAR 160:67], 359 kb/s, 23.98 fps, 23.98 tbr, 24k tbn (default)
    Metadata:
      creation_time  : 2023-10-22T20:43:07.000000Z
      handler_name    : ISO Media file produced by Google Inc. Created on: 10/22/2023.
      vendor_id      : [0][0][0][0]
  Stream #0:1[0x2](eng): Audio: aac (LC) (mp4a / 0x6134706D), 44100 Hz, stereo, fltp, 127 kb/s (default)
    Metadata:
      creation_time  : 2023-10-22T20:43:07.000000Z
      handler_name    : ISO Media file produced by Google Inc. Created on: 10/22/2023.
      vendor_id      : [0][0][0][0]
     
stat NovemberMan.mp4
  File: NovemberMan.mp4
  Size: 385313532      Blocks: 752568    IO Block: 4096  regular file
...

The video is 1hr 44 min, 385MB, 1280x536, The audio is fine. The video could be a little better.

Why don't you experiment with small segments of video.

Get 3 minutes of your video.
Code:

ffmpeg -ss 00:01:00 -t 00:04:00 -i Myvid.mp4 -c:a copy -c:v copy Test1.mp4
Then experiment
Code:

ffmpeg -i Test1.mp4 -c:a copy -c:v libx264 -crf 18 -preset slow -r 24 Out1.mp4
ffmpeg -i Test1.mp4 -c:a copy -c:v libx264 -crf 18 -preset slower -r 24 Out2.mp4
ffmpeg -i Test1.mp4 -c:a copy -c:v libx264 -b:v 2000k -r 24 Out3.mp4
ffmpeg -i Test1.mp4 -c:a copy -c:v libx264 -maxrate 2000k -bufsize 1M -r 24 Out4.mp4

Resizing a video smaller with good bitrate will also make the file size smaller. Keep the same aspect ratio.

Docs:
https://trac.ffmpeg.org/wiki/TitleIndex
https://ffmpeg.org/ffmpeg.html
https://linux.die.net/man/1/ffmpeg

Edit:
2 pass was good for Xvid. I don't that it does much in file size for x264.

blumenwesen 03-16-2024 09:10 PM

Ok, I'll try that, hope it's comparable to compressing 3.5gb > 1gb alternatively 3.5mb > 1mb.
Thanks for the help.


All times are GMT -5. The time now is 07:18 PM.