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

Local API: Improve audio quality by sorting streams, highest bitrate first #6807

Merged
merged 5 commits into from
Feb 17, 2025

Conversation

AlyoshaVasilieva
Copy link
Contributor

@AlyoshaVasilieva AlyoshaVasilieva commented Feb 15, 2025

Local API: Improve audio quality by sorting streams, highest bitrate first

Pull Request Type

  • Bugfix

Related issue

closes #6138

Description

The player seems to select the first audio stream it sees (I do not know its precise behavior). YouTube often puts a 40-50kbps audio stream first in the format list, which means FreeTube selects it and gives low quality audio.

Higher bitrate streams consistently coming first due to sorting means the player selects a high-quality audio stream, rather than potentially a very low-quality one. See #6138 for more info.

Testing

Try watching videos with/without this patch, e.g. https://youtu.be/G4qVG_FL4_s

Desktop

  • OS: Windows
  • OS Version: 10
  • FreeTube version: 0.23.1

Additional context

This doesn't break the quality selector.

I didn't touch the Invidious API because there were no working instances, can't test.

Higher bitrate audio streams consistently coming first mean the player selects a high-quality audio stream, rather than potentially a very low-quality one.
@github-actions github-actions bot added the PR: waiting for review For PRs that are complete, tested, and ready for review label Feb 15, 2025
@FreeTubeBot FreeTubeBot enabled auto-merge (squash) February 15, 2025 07:46
Copy link
Member

@absidue absidue left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is already a much better approach that the previous pull request, but it won't work for live streams as we use the DASH manifest from YouTube for those and as you mentioned yourself it doesn't cover the Invidious API.

A better implementation would do the sorting inside of manifestPreprocessorTXml in the src/renderer/components/ft-shaka-player/ft-shaka-video-player.js file. Additionally this time please edit this PR instead of opening a new one again.

@absidue absidue added PR: changes requested and removed PR: waiting for review For PRs that are complete, tested, and ready for review labels Feb 15, 2025
@AlyoshaVasilieva
Copy link
Contributor Author

I'll look at manifestPreprocessorTXml but I might not be able to implement it; I don't really know JavaScript/Electron/Vue/shaka-player so I'm basically just poking things to see if it works.

Additionally this time please edit this PR instead of opening a new one again.

I opened a new PR because I considered it a different approach, I didn't consider it an improvement of the old PR. Though I guess they are both sorting things.

@absidue
Copy link
Member

absidue commented Feb 15, 2025

That function is passed to shaka-player and runs after shaka-player has parsed the XML into objects but before it starts processing it. The function already has some code to sort the adaptation sets based on their codec. You will want to add some code that will sort the representations inside of the adaptation sets, for performance reasons you only need to sort them in the audio adaptation sets (the video, text (subtitles) and image (thumbnail previews)) don't need sorting.

The player currently selects the first audio stream. So, sort to ensure that, for a specific codec, the first stream has the highest bitrate.
auto-merge was automatically disabled February 15, 2025 10:42

Head branch was pushed to by a user without write access

@FreeTubeBot FreeTubeBot enabled auto-merge (squash) February 15, 2025 10:42
@AlyoshaVasilieva
Copy link
Contributor Author

AlyoshaVasilieva commented Feb 15, 2025

I think this works. Tested it (local API) on various videos/livestreams until I got temp-banned by YouTube and it was selecting the highest bitrate audio stream on each (and not crashing or anything).

@absidue absidue added PR: waiting for review For PRs that are complete, tested, and ready for review and removed PR: changes requested labels Feb 15, 2025
Copy link
Member

@absidue absidue left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Small code nit, other than that LGTM.

Co-authored-by: absidue <48293849+absidue@users.noreply.github.com>
auto-merge was automatically disabled February 16, 2025 00:52

Head branch was pushed to by a user without write access

@FreeTubeBot FreeTubeBot enabled auto-merge (squash) February 16, 2025 00:52
auto-merge was automatically disabled February 16, 2025 03:09

Head branch was pushed to by a user without write access

@FreeTubeBot FreeTubeBot enabled auto-merge (squash) February 16, 2025 03:09
@PikachuEXE
Copy link
Collaborator

I can play the video but how do I know if I get highest/lowest/random quality audio stream with this PR?
Don't know where to look

@AlyoshaVasilieva
Copy link
Contributor Author

Easier way but less exhaustive: Right-click the video and click "Show Stats", then look for the itag number next to the audio codec and compare it to a list of itags, e.g. yt-dlp's: https://github.com/yt-dlp/yt-dlp/blob/421bc72103d1faed473a451299cd17d6abb433bb/yt_dlp/extractor/youtube.py#L1333 (bitrates are not exact)

Opus 251 is good, it's something like 130kbps. Opus 249 is bad, it's 40-50kbps. mp4a 140 is good too. Need to check multiple videos because some (recently-posted?) videos only have high-quality audio.

More exhaustive way: Open devtools with F12 before viewing video, look for the request to player?prettyPrint=false&alt=json. Look in streamingData object for all the streams available. FreeTube's audio codec priority is opus > mp4a > ec-3 > ac-3, so check as above for what codec it is using, and then look at all the audio streams YouTube listed to make sure FreeTube is using the highest quality stream according to priority and bitrate. (So, even if the AAC 140 stream has a higher bitrate, it'll select Opus if it's present since it's a newer codec, but for a given codec it should select highest bitrate with this PR.)

At least, this is how best I know.

@FreeTubeBot FreeTubeBot merged commit 2dcc1f9 into FreeTubeApp:development Feb 17, 2025
6 checks passed
@github-actions github-actions bot removed the PR: waiting for review For PRs that are complete, tested, and ready for review label Feb 17, 2025
OothecaPickle pushed a commit to OothecaPickle/FreeTube that referenced this pull request Feb 17, 2025
…first (FreeTubeApp#6807)

* Sort streams, highest bitrate first

Higher bitrate audio streams consistently coming first mean the player selects a high-quality audio stream, rather than potentially a very low-quality one.

* Revert "Sort streams, highest bitrate first"

This reverts commit aba6803.

* Sort audio adaptation sets by bitrate

The player currently selects the first audio stream. So, sort to ensure that, for a specific codec, the first stream has the highest bitrate.

* startsWith instead of split

Co-authored-by: absidue <48293849+absidue@users.noreply.github.com>

* Fix missing paren

---------

Co-authored-by: absidue <48293849+absidue@users.noreply.github.com>
PikachuEXE added a commit to PikachuEXE/FreeTube that referenced this pull request Feb 20, 2025
* development: (58 commits)
  Convert FtSubscribeButton and watch-video-info SCSS to CSS (FreeTubeApp#6814)
  Use numbers instead of strings for the DBActions and SyncEvents constants (FreeTubeApp#6815)
  Translated using Weblate (English (United Kingdom))
  Fix: search history text overflows if search term is long (FreeTubeApp#6728)
  Check if a keyboard composition session is active when pressing 'Enter' on ft-input (FreeTubeApp#6799)
  use hq img (FreeTubeApp#6826)
  Move the choose default folder logic to the main process (FreeTubeApp#6811)
  Translated using Weblate (French)
  Translated using Weblate (Turkish)
  Set process.platform at build time (FreeTubeApp#6784)
  Use logical spec for float (FreeTubeApp#6783)
  Migrate DataSettings to the composition API (FreeTubeApp#6785)
  Local API: Improve audio quality by sorting streams, highest bitrate first (FreeTubeApp#6807)
  Bump sass from 1.84.0 to 1.85.0 (FreeTubeApp#6825)
  Bump webpack from 5.97.1 to 5.98.0 (FreeTubeApp#6820)
  Bump postcss from 8.5.1 to 8.5.2 in the stylelint group (FreeTubeApp#6819)
  Bump the babel group with 2 updates (FreeTubeApp#6817)
  Bump globals from 15.14.0 to 15.15.0 (FreeTubeApp#6823)
  Bump sass-loader from 16.0.4 to 16.0.5 (FreeTubeApp#6822)
  Bump eslint from 9.20.0 to 9.20.1 in the eslint group (FreeTubeApp#6818)
  ...

# Conflicts:
#	src/renderer/components/watch-video-info/watch-video-info.scss
#	src/renderer/components/watch-video-info/watch-video-info.vue
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

Successfully merging this pull request may close these issues.

[Bug]: Strong audio compression artifacts audible since version 0.22.0
6 participants