Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[youtube] Video codec selected by yt-dlp doesn't provide the highest quality #458

Closed
5 of 6 tasks
Pyxia-Code opened this issue Jun 29, 2021 · 10 comments
Closed
5 of 6 tasks

Comments

@Pyxia-Code
Copy link

Checklist

  • I'm reporting a broken site support issue
  • I've verified that I'm running yt-dlp version 2021.06.23
  • I've checked that all provided URLs are alive and playable in a browser
  • I've checked that all URLs and arguments with special characters are properly quoted or escaped
  • I've searched the bugtracker for similar bug reports including closed ones
  • I've read bugs section in FAQ

Verbose log

[debug] Command-line config: ['--skip-download', 'https://www.youtube.com/watch?v=Dnw6-ntk3SY', '-v']
[debug] Encodings: locale UTF-8, fs utf-8, out utf-8, pref UTF-8
[debug] yt-dlp version 2021.06.23 
[debug] Python version 3.9.5 (CPython 64bit) - Linux-5.12.7-gnu-hardened1-1-hardened-x86_64-with-glibc2.33
[debug] exe versions: ffmpeg 4.4, ffprobe 4.4, rtmpdump 2.4
[debug] Proxy map: {}
[debug] [youtube] Extracting URL: https://www.youtube.com/watch?v=Dnw6-ntk3SY
[youtube] Dnw6-ntk3SY: Downloading webpage
[youtube] Dnw6-ntk3SY: Downloading MPD manifest
[debug] Formats sorted by: hasvid, ie_pref, lang, quality, res, fps, vcodec:vp9.2(10), acodec, filesize, fs_approx, tbr, vbr, abr, asr, proto, vext, aext, hasaud, source, id
[debug] Default format spec: bestvideo*+bestaudio/best
[info] Dnw6-ntk3SY: Downloading 1 format(s): 303+251

Description

By default yt-dlp seems to download videos encoded with the VP9 codec first which from my tests doesn't seem to offer the best possible quality when downloading from youtube.
When youtube only offers a video in VP9 and H.264 then H.264 has the highest quality:
comparison-redone
https://www.youtube.com/watch?v=Dnw6-ntk3SY

comparison
https://www.youtube.com/watch?v=fy16LjNLWjk

And in the case when youtube also offers the video in AV1, then it seems that AV1 > VP9 > H.264 in terms of quality:
comparison
https://www.youtube.com/watch?v=spcauG9AnGI

comparison
https://www.youtube.com/watch?v=RAhqxvgQYn0

My guess is that the quality depends on which codec was used by the original video. I think that most people use H.264 so the version reencoded to VP9 has lower quality and when a video is available in AV1 then it was the original codec used to encode the video so it has the highest quality.
VBR reported by youtube doesn't seem to play a role here, because when comparing the quality of these videos:
https://www.youtube.com/watch?v=spcauG9AnGI (Highest VBR - H.264)
https://www.youtube.com/watch?v=rXHpFOG-fcY (Highest VBR - VP9)
https://www.youtube.com/watch?v=RAhqxvgQYn0 (Highest VBR - AV1)
all of them seem to have the highest quality in AV1 even though the codec with the highest VBR seem to be different for every video.

It should be possible to solve this by changing the format sort used by the youtube extractor to first check for AV1 then for H.264 and only then for VP9.

Command I've used to download videos for comparison:

yt-dlp VIDEO_URL -f FORMAT

All of the screenshots were taken using mpv with screenshot-format=png

@Jules-A
Copy link
Contributor

Jules-A commented Jun 30, 2021

AV1 isn't really widely supported yet but users can just use something like -S res,codec:av1 if they prefer AV1. As for VP9/H.264, in my experience VP9 produces slight better results on average with decently lower bitrates but can slip up on some videos. If you want to prefer AV1>H.264>VP9 then I think you can just use `-S res,codec:av1,codec:avc' (not sure what yt-dlp uses to identify h.264).

@Pyxia-Code
Copy link
Author

AV1 isn't really widely supported yet but users can just use something like -S res,codec:av1 if they prefer AV1. As for VP9/H.264, in my experience VP9 produces slight better results on average with decently lower bitrates but can slip up on some videos. If you want to prefer AV1>H.264>VP9 then I think you can just use `-S res,codec:av1,codec:avc' (not sure what yt-dlp uses to identify h.264).

-S res,codec:av1,codec:h264,codec:vp9 does what I want.
In my case in 2 videos I've tested where only these 2 codecs were available H.264 performed better than VP9 but it might depend on the content of the video and the strengths and weaknesses of codecs so as you said it might sometimes perform better and sometimes worse. I guess I'll wait for the opinion of the devs on this.

@pukkandan
Copy link
Member

When youtube only offers a video in VP9 and H.264 then H.264 has the highest quality:
And in the case when youtube also offers the video in AV1, then it seems that AV1 > VP9 > H.264 in terms of quality:

This is not a general rule. The relative quality of different encodings depends on a lot of factors including the actual content of the video itself. There is no objective way of testing the actual "quality" of the video formats without downloading them first. Generally, av01>vp9>h264 in terms of quality. But av01 is not yet playable by most devices. So yt-dlp choses vp9>h264>av1 (this is an over-simplification based on youtube only). You can make it prefer av1 with vcodec:av1 in -S if you want

-S res,codec:av1,codec:h264,codec:vp9 does what I want.

No. This is equivalent to just using -S res,codec:av1 (gives av1>vp9>h264). -S is a format sorting option. The command you gave is like asking to sort the alphabets starting at N, then sort again starting at D - Only the last sort will have any effect. There is an (untracked) request to allow multiple entries for the sort-preference, but no such feature is yet implemented.

Currently, the only way to do av1>h264>vp9 is to use -f

@hronro
Copy link

hronro commented Sep 5, 2021

@pukkandan

This is really confusing for me.

When I saw this in README.md:

The default format sorting options have been changed so that higher resolution and better codecs will be now preferred instead of simply using larger bitrate.

Until I saw this issue, I thought it would prefer av1 codec by default since av1 is the best codec before h266(VVC) is coming out.

But av01 is not yet playable by most devices.

This is not true. There are some free and open-source decoders like dav1d, which uses CPU to decode instead of some specific hardware. With proper player apps, most of my devices can play av1 videos (including my 3-years-old iPhone, my 4-years-old Google Pixel, my MacBook Pro, and my Windows PC).

@hronro
Copy link

hronro commented Sep 5, 2021

@Pyxia-Code

My guess is that the quality depends on which codec was used by the original video. I think that most people use H.264 so the version reencoded to VP9 has lower quality and when a video is available in AV1 then it was the original codec used to encode the video so it has the highest quality.

This is not true. YouTube re-encodes every video no matter that the original codec of the video is. After re-encodes, every format YouTube offers would be lossy. From my experience, av01 is always the best choice for best quality.

@pukkandan
Copy link
Member

The readme was recently edited to clarify this.

the default order used is: lang,quality,res,fps,codec:vp9.2,...

Note that the default has codec:vp9.2; i.e. av1 is not prefered

I will make AV1 default only after atleast all major OSes start supporting it See this list. Hopefully, most new devices will also have hardware support for it by then

I don't understand why people complain about this. You have the option to just put something like -S res,vcodec:av1 in a config file and forget about it.

The default option should work for the most non-techie users and a codec that is still not natively supported on popular OSes is not a good default

@hronro
Copy link

hronro commented Sep 5, 2021

@pukkandan

I respect the decision you made, I just want to point out the container formats that yt-dlp currently used for vp9 (mkv/webm), are not supported by most OSes neither.

@chrizilla
Copy link

@pukkandan said:
Currently, the only way to do av1>h264>vp9 is to use -f

like -f "(bv*+ba/b)[vcodec=av01] / (bv*+ba/b)[vcodec=h264] / (bv*+ba/b)[vcodec=vp9] / (bv*+ba/b)" ?

@milahu
Copy link

milahu commented Oct 17, 2023

#458 (comment) did not work for me

currently im using multiple calls to yt-dlp

H=720
f="bestvideo[height<=$H][ext=mp4]+bestaudio[ext=m4a]/0/iphone-$Hp/best[height<=$H]"

# h264 > av1 > vp9
yt-dlp -f "$f" -S vcodec:h264 "$@" ||
yt-dlp -f "$f" -S vcodec:av1 "$@" ||
yt-dlp -f "$f" "$@"

@r3a1d3a1
Copy link

r3a1d3a1 commented Feb 10, 2024

I don't understand why people complain about this. You have the option to just put something like -S res,vcodec:av1 in a config file and forget about it.

@pukkandan Doesn't work when also using something like: -f "[height=720]"

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants