Giter Site home page Giter Site logo

sv443 / betterytm Goto Github PK

View Code? Open in Web Editor NEW
33.0 33.0 0.0 19.04 MB

Userscript that improves YT Music with tons of quality of life improvements such as better lyrics lookup, finer volume control and lots more general layout and usability improvements

License: GNU Affero General Public License v3.0

JavaScript 1.87% TypeScript 88.22% CSS 9.92%
browser-extension extension qol userscript userscripts youtube youtube-music

betterytm's Introduction

Hi there, I'm Sven

I am a 22 year old full stack developer from Germany.
My interests are in open source software, server and web development, as well as PC and server hardware and IT infrastructure.
Most of my projects are made with or for Javascript, Linux and Arduino.
Although I love working in a familiar environment, I'm always open to try out new technologies and want to continue learning and improving my skills.

What I'm currently working on:

  • JokeAPI is an API that serves a good variety of uniformly formatted jokes and offers lots of filtering methods.
  • BetterYTM, a userscript that brings tons of features and UX improvements to YouTube Music.
  • geniURL, an API for looking up and filtering song metadata from genius.com
  • Userscript.ts, a Template for making Userscripts in TypeScript with tons of modern utilities and comfort features.
  • SvCoreLib, which is a Node.js package that is used in basically all of my Node.js projects. It has many commonly used features.

My projects are free and open source so I rely on donations to keep my servers and domains running.
So if you like what I do, please consider supporting my development.

If you want to reach out to me, you can join my Discord server or send me an E-Mail.
Please don't contact me with any job offers or shady business requests, you will be ignored.



Links: Homepagenpm

betterytm's People

Contributors

imgbot[bot] avatar imgbotapp avatar sv443 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar

betterytm's Issues

Add iframe to page to look up lyrics on genius.com

LyricFind absolutely sucks ass, the lyrics always have mistakes, wrong spelling or are for entirely different songs. Genius is just much better.

Add an <iframe> that can be toggled on and off (maybe like an icon next to the Lyrics tab).

Genius URL format: https://genius.com/search?q=artist%20name%20song%20name
Extract the search query from .content-info-wrapper > yt-formatted-string:nth-child(1) and span.subtitle > yt-formatted-string:first-child

Site switch doesn't keep the video time

Fixing this when coming from YT to YTM will be difficult, since the video time is only updated while the media control bar is visible, which on YT only occurs after user interaction, while on YTM it is visible all the time.

Edit: dispatching mouse events shows the video time so it can be parsed, see src/dev/ytForceShowVideoTime.js

Fail to load when cookies are blocked

Checklist:

  • I checked here if there is already an issue for this bug
  • I am using the latest version of BetterYTM
  • I am using the latest version of my browser
  • I was able to reproduce the bug while all my other userscripts or extensions were disabled

Description of the bug and steps to reproduce:

The current version of the script doesn't work whenever cookies are blocked on the site.
It does run according to the console, but it errors on some parts and ultimately doesn't load.
In the console, you can see the message Uncaught DOMException: The operation is insecure..
This happens on Firefox (and derivatives), but I'm unsure if it's the same case for Chromium-based browsers.

Environment:

  • Browser name & version: LibreWolf 122.0.1-2
  • Userscript version & build number: v1.1.0 (520689c)

Other info / screenshots:

It runs.
image
Fails to load.
image

Arrow keys don't work on FF macOS

On Firefox in macOS, pressing arrow keys to skip forwards & backwards doesn't work and comes up with this error:

grafik

Update:

The problem comes from the window object being only limitedly available in userscripts. YTM needs certain properties that are unavailable regularly, thus unsafeWindow is required to dispatch the arrow key events correctly.

But in the current constellation I don't see a way for it to be a potential vulnerability, so this is just how it's gonna have to be.
You may remove the @grant unsafeWindow line in the userscript header but note that all features that dispatch keyboard events might break.

Feature to automatically close toasts

Toasts (like when liking a song or adding it to a playlist) don't automatically close.
A simple MutationObserver and .click() after a configurable timeout should do the trick.

More powerful translation system

Create a library with an extended syntax for declaring translations.
The goal is not to be as flexible as the other translation libs currently in existence, it's to be as lightweight as possible for userscript usage, while being a step above UserUtils' current, VERY simple translation system.

Requirements:

  • Interpret certain translations as raw HTML, others as a string (XSS prevention)
  • Support for named variables (numbered ones are kinda wack for context)
  • Support for calling predefined actions that result in a string, using passed parameters
  • Support for nested translations using dot syntax (i.e. generic.buttons.submit)
Example - click to expand
{
  // regular translation with indexed parameters - like it is right now
  "example0": "My translation blabla, %0",

  // translation treated as raw HTML, with a localized URL
  "example1.0": "[/];My translation blabla <a href=\"local url\">%0</a>",
  // translation treated as raw HTML, with a variable URL provided by the implementer
  "example1.1": "[/];My translation blabla <a href=\"%0\">text</a>",
  // translation with named variables and indexed parameters at the same time
  "example2": "[$];My translation blabla ${namedVar}, %0",
  // translation with an action call that results in an arbitrary string
  "example3": "[@];My translation blabla @{actionName,%0,param2}",

  // combination of all the above
  "example4": "[/$@];My translation blabla <a href=\"%0\">${namedVar}</a> @{actionName,%1,param2}"
};

Example usage:

tr("example0", ["param1"]);

tr("example1.0", ["anchor text"]);

tr("example1.1", ["https://example.com"]);

tr("example2", { namedVar: "namedVar", 0: "param1" });

tr.defineAction("actionName", (locale, ...params) => {
  return "action result";
});
tr("example3", ["param1"]);

tr("example4", { namedVar: "namedVar", 0: "https://example.com", "1": "param2" });
// ^ should support stringified number keys too, because of object & array merging

Lyrics search is inconsistent, especially with short song / artist names

For example take the song Flume - v (geniURL search query: Flume%20v)
The geniURL API now responds with Flume - Voices, then Flume - v in second place, see API response.

Instead of blindly using the top result, BYTM should use the /search endpoint (instead of /search/top), and then do some simple string matching to determine whether there's a perfect match that didn't get top place.
This could (if needed) again be done with the Fuse library.

Allow caching lyrics URLs in GM storage

Should store the sanitized song and artist strings, lyrics URL and the last time the URL was grabbed.
Every time an entry is read, its datetime should be set to Date.now(), this is to keep the more often listened to songs alive in the cache.

This cache should be exposed on the interface, just like the current lyrics URL related functions.

It should have one menu option to enable it and one to specify how many entries should be stored.

Performance: After a quick test with 100,000,000 characters stored, GM read time stayed under 1ms on Firefox. Of course parsing JSON that humongous is gonna take a LONG time.

Constraints of number inputs can be overwritten

Number inputs in the config menu that have a min and max property don't allow to set an out-of-bounds value when clicking the arrows or using the arrow keys, but typing the number manually can bypass the constraint.
To fix this, the menu should constrain all input fields after the config has been changed.

Make a better menu

The current menu is not very well structured and expandable

Requirements:

  • Different tabs for different categories
  • Sections with headers per feature group
  • Support for "custom widgets"
  • Explicit save on button press to store new configuration
  • Optional cleanup function per feature so a page reload is not always needed
  • Repeatable menu content generation so locales can be switched without reloading

Nice to have:

  • Use the <dialog> element for better accessibility
  • Toggle switches instead of checkboxes

Improve genius.com autoclick

The current autoclick does an exact match (case insensitive) to check for a search result to autoclick. Instead, since artist names and even song names can vary greatly between YTM and genius, a fuzzy search library like Fuse.js should be used to find the best match way more reliably:

// ==UserScript==
// @require https://cdn.jsdelivr.net/npm/fuse.js/dist/fuse.min.js
// ==/UserScript==

const f = new Fuse([ "apple", "banana", "orange", "lemon" ]);

f.search("apel"); // [ { item: "apple" } ]

Volume slider sensitivity should impact scroll wheel

Description of the feature:

Scroll wheel should change volume only by the same amount as "Volume slider sensitivity". I think that when the sensitivity is set to a number below 10, it should also affect the scroll wheel.
Currently how I believe it works is that the scroll wheel always changes volume by a minimum of 10. So if I set the volume slider sensitivity to 15, the scroll wheel will increment volume by 15. However if I set the volume slider sensitivity to 5, the scroll wheel will still increment volume by 10. I think that when the sensitivity is set to a number below 10, it should also affect the scroll wheel. My apologies if this is formatted incorrectly; I am not a computer person.

Remember song time for a short while

Sometimes when reloading the page or accidentally closing the tab and reopening it, it would be cool if the previous video time was restored.
It would be invalidated after a couple minutes, would be overwritten by the next song that plays and it would only ever be restored once on page load as to not be disruptive.

Add details to menu options

Since the menu option descriptions have to be under a certain length, it's sometimes hard to explain the feature correctly.
A (?) element that explains it in more detail on hover or click would be good.

Use currentTime on the video element to skip to a certain time

Code:

// read:
document.querySelector("ytmusic-player video").currentTime;
// skip to seconds:
document.querySelector("ytmusic-player video").currentTime = 69;
// skip by x seconds:
document.querySelector("ytmusic-player video").currentTime += x;

Affected features:

  • Remember song time
  • Arrow keys skip
  • Number keys skip

Show welcome page after first install

This could allow users to

  • directly select their language and not have to navigate a menu in a foreign language first
  • click some links to the project (readme, funding, contributing, etc.)
  • be asked to rate the userscript on GF and OUJS

and could be expanded to open after each update to show

  • the latest changes from the changelog
  • the latest dev news

Use `input` event over `change`

The change event on an <input> only fires after the element has lost focus if it's a text input, or after the input was let go if it's something like a slider.
input is supported in all browsers and actually fires every time the value changes.

Genius URL autoclick should prefer the top result

This example song gives the genius URL https://genius.com/search?q=Phone%20Numbers%20Dominic%20Fike
The autoclick fuzzy search now chooses the wrong search result:

The "top result" should gain a score bonus, so that it will jump to 1st place if it's on like 2nd or 3rd place in the list of fuzzy search matches.
Additionally, the top result of the "songs" section could gain a similar score boost (but smaller than "top result").

Also, to remove false positives like for this song there could be a score threshold, below which no autoclick will be done.

Make features hot-reloadable

Each feature in features/index.ts should come with an initialization function and a cleanup function, unless explicitly stated by a property that the feature requires a page reload (ex. beforeunload listener).
The cleanup function should remove all elements and MutationObservers created by the initialization function, reset all in-memory variables and remove all onSelector listeners.

Feature to fix song metadata in Windows

For some reason the album takes precedence over the artist name and since YTM auto-fills the album name with the song's name if there's no album, the metadata Windows displays is just the song name twice in like 80% of the cases.
Using the MediaMetadata API, I could modify the metadata so it only displays song and artist:

if ('mediaSession' in navigator) {
  navigator.mediaSession.metadata = new MediaMetadata({
    title: "Song",
    artist: "Artist",
    artwork: [
      { src: "https://dummyimage.com/96x96", sizes: "96x96", type: "image/png" },
      { src: "https://dummyimage.com/512x512", sizes: "512x512", type: "image/png" },
    ],
  });

Add translations

Since i18n libs are usually on the bigger side, a custom solution based on simple JSON files would be most adequate I think

Improve geniURL query

At the moment, artist and song are separated and everything in parentheses like (Someone Remix) is removed.
Now that geniURL has proper fuzzy filtering for full queries (using ?q) including remixes, not much sanitisation is needed.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.