How to compress video - ffmpeg

Primer

Compressed video mostly uses ffmpeg, we need to think clearly why we need to compress video. Is it because of user experience (seconds to open, smooth) problems? Or is it because of cost (bandwidth, storage)? Or is it because of operational (advertising, interaction) needs? We need to anchor the key goals before compression, and then balance the trade-offs.

background

The initial demand I got was that the user's playback was stuck, which needed to be resolved. Use ffmpeg to simply analyze the video source. Basic information includes key data such as resolution, frame rate, and bit rate. Reference information includes file format, encoding format, pixel format, etc.; (audio takes up a small file, lower the priority first)

It can be seen that the resolution is 1080x1928, the frame rate is 30fps, the code rate is 13095kbps, the file is mp4, the encoding format is h264 (main), and the pixel format is yuv420p; the file length is 00:01:10.1, 1 minute and 10 seconds; press this code Rate, the size of the video part is 13095x70=916650kb, here is the bit, the converted KB is 114581.25, and the converted MB is about 111.90MB.

Let's briefly evaluate the requirements for the user's network. If the buffer is 500ms, then the download speed of 13095x0.5=6547.5kb=818.4375KB=about 0.8MB is still relatively demanding, because the network operator reports to everyone that kbps is small b, the conversion is equivalent to requiring 6.4Mb.

solve

In view of the above problems, my solution ideas are as follows:
1. The mobile phone player generally does not need such a high resolution, so reduce the 720p;
2. The frame rate of 30fps can also be reduced appropriately, and can be reduced to 22-25;
3. Bit rate compression, You can choose -crf fixed bit rate ratio compression or -b:v highest bit rate compression method;
4. Video encoding h264 (main) can be adjusted to h264 (high);
the above 4 parameter configuration compression commands are as follows:
ffmpeg -y -i xx.mp4 -c:a copy -c:v libx264 -profile:v high -r 30 -crf 30 -s 720x1080 xx-out.mp4
Briefly introduce the parameters:
-y: Indicates that the output file is overwritten
-i: Indicates the input file
-c:a: Indicates that the audio part is encoded, and copy indicates that it is directly copied to a new file
-c:v: Indicates that the video part is encoded, libx264 indicates that h264 is used for
encoding -profile:v: h264 encoding parameters, using a more compact compression algorithm
-r: indicates the video frame rate, 30fps
-crf: indicates that the code rate applies a fixed code rate ratio, from 0 to 500, the larger the code rate, the lower the code rate, generally 18 to 32 is better
-s: Video resolution cropping, 720x1080 means cropping to 720p

Effect

After the above command is executed, the effect is as follows:

The most obvious bit rate is reduced to 926kbps, and others are changed according to the parameters. The new file size is optimized to 926x70=64820kb, about 7.91MB. From 111.90MB to 7.91MB, the optimization effect is very good. The requirement for user network bandwidth is reduced to about 463kb, which is only a fraction compared to 6.4Mb.

Can it be achieved in seconds? Let's go back and look at the moov header:

You can see that ftyp and free are file identifiers, so don’t worry about them; mdat is video + audio data storage, occupying 8030053 bytes, and the next is the moov header. We know that the video playback will first obtain the moov header before knowing the specific metadata information. How to encode, resolution geometry and such. Generally, video players will also be optimized, which is to read a certain number of bytes in front of the video header first. If the moov header has not been parsed, a new request will be made to read a certain number of bytes from the end of the file to supplement the parsing of moov. The ideal state must be that the moov header can be parsed for the first time buffering data, and continue to buffer data, instead of disconnecting and re-requesting, parsing the moov header, and then requesting buffered data. So it is necessary to move forward for the moov head.
The specific ffmpeg command is as follows:
-movflags +faststart
just add the above parameters to the above command. The final command is as follows:
ffmpeg -y -i xx.mp4 -c:a copy -c:v libx264 -profile:v high -r 30 -crf 30 -s 720x1080 -movflags +faststart xx-out.mp4

expand

We will introduce the basic video optimization here first, the above is the most basic optimization, and we will continue to advance other optimizations based on the above.
1. Change the encoding format, try h265 (compatible with Apple qt), try vp9, try av1;
2. Video slice, use the m3u8 file format of hls+ts;
3. Apply 2-pass to optimize the bit rate;
4. The most important introduction Video quality evaluation system, ssim, psnr, vmaf;
5. Try multi-resolution distribution, 480p, 720p, 1080p;
6. Network optimization, CDN acceleration;
7. Other small optimizations;
in the actual practice process, it is still necessary to constantly adjust the application , encounter problems and solve problems; select the optimization target, select the quality comparison parameters, and then continuously tune the above parameters to achieve the final optimization balance.

The benefits of this article, free C++ audio and video learning materials package, technical video/code, including (audio and video development, interview questions, FFmpeg, webRTC, rtmp, hls, rtsp, ffplay, codec, push-pull stream, srs)↓↓↓ ↓↓↓See below↓↓Click at the bottom of the article to get it for free↓↓

Guess you like

Origin blog.csdn.net/m0_60259116/article/details/131014408