0

I'm trying to develop a simple video transcoding system. When you upload a video, After extracting the video and audio separately, I want to encode them at 360, 720, and 1080p resolutions respectively and then merge them to create three final mp4 files. At this time, I have two questions.

  1. Is there a big difference between encoding the video and audio separately in the original video file and encoding the original video file as is? In a related book, it is said that a system is created by separating video and audio, and I am curious as to why.

  2. I want to change the resolution without compromising the original image quality. At this time, the resolution of the uploaded file can be known at the time of upload. As a test, I created files according to each resolution, and found that the image quality was damaged. If I want to change only the resolution while keeping the original image quality, I would like to know how to adjust each ffmpeg option. We plan to change it to 360, 720, and 1080p.

  3. Lastly, are there appropriate settings for the three resolutions (360, 720, 1080) that I am trying to convert to ffmpeg?

1 Answer 1

0

Is there a big difference between encoding the video and audio separately in the original video file and encoding the original video file as is?

If you're only downscaling the video, then you can save a small amount of time by separating the audio and converting it once, so for each uploaded video, there is 3 video encoding steps + 1 audio encoding step instead of 3 video encoding steps + 3 (redundant) audio encoding steps.

Here's an example of how to do this, taking $input and compressing it into three videos of 360p, 720p, and 1080p resolutions. It encodes the audio as 64kbps Opus. The video is encoded to AV1 with the default CRF:

ffmpeg -sn -dn -vn -i $input -c:a libopus -b:a 64k temp.opus
ffmpeg -sn -dn -an -i $input -i temp.opus -c:a copy -c:v libsvtav1 -vf "scale=-2:360:flags=lanczos+accurate_rnd" -c:a copy 360p.webm
ffmpeg -sn -dn -an -i $input -i temp.opus -c:a copy -c:v libsvtav1 -vf "scale=-2:720:flags=lanczos+accurate_rnd" -c:a copy 720p.webm
ffmpeg -sn -dn -an -i $input -i temp.opus -c:a copy -c:v libsvtav1 -vf "scale=-2:1080:flags=lanczos+accurate_rnd" -c:a copy 1080p.webm
rm temp.opus

There would be a way to do this all in a single command with no temporary files using filter_complex and the tee pseudo-muxer, but it would be more complex to read and isn't necessary to illustrate the point.

I want to change the resolution without compromising the original image quality.

That isn't possible. Whenever you transcode you damage quality. This is called generation loss and you should always minimize the number of generations of transcoding that a video goes through. When you downscale, you also remove information. You can optimize bitrate and resolution trade offs for best quality by using something called a "convex-hull approach".

Lastly, are there appropriate settings for the three resolutions (360, 720, 1080) that I am trying to convert to ffmpeg?

You should pick a CRF for each resolution that gives you acceptable quality at acceptable bitrate. Lower CRF means better quality but higher bitrate. You can also improve quality by using a slower preset. This will give better quality for any given bitrate (put another way, you can get the same quality at a lower bitrate) but at the expense of more encoding time. There are diminishing returns at the really slow presets though.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.