elliotwaite / thumbnail-rating-bar-for-youtube

A Chrome and Firefox extension for YouTube that adds a rating bar (likes/dislikes ratio) to the bottom of every thumbnail.
https://chrome.google.com/webstore/detail/youtube-thumbnail-rating/cmlddjbnoehmihdmfhaacemlpgfbpoeb
MIT License
249 stars 17 forks source link

Google has dropped the dislike count, thanks for the great extension! It was very helpful over all of these years :1st_place_medal: #50

Open NeveHanter opened 2 years ago

NeveHanter commented 2 years ago

More info: https://support.google.com/youtube/thread/134791097/update-to-youtube-dislike-counts Relevant HN discussion: https://news.ycombinator.com/item?id=29177091

Nornec commented 2 years ago

Also according to the post, devs can apply for an exemption. This is overall a bad move for the platform in my opinion, all things considered.

braham-snyder commented 2 years ago

Could this extension switch to the likes-to-views ratio?

(As "gpt5" mentions in those HN comments.)

MmyGgithubAaccount commented 2 years ago

You can apply for an exemption (to have dislike data on non-authenticated calls) as long as you don’t display or share dislike data with end your users.

Since this extension does do both of those things, I doubt it'll quality for an exemption

Nornec commented 2 years ago

I just attempted the exemption form and it seems the only way to get an exemption is to be an organization with a specific internal app that does not expose the data to anyone but a sole user or set of internal users. It also requires that a data compliance audit be done on every applicable project, but this compliance seems to, again, only apply to organizations and not sole developers. This stinks..

ryanbuening commented 2 years ago

I think a likes-to-views ratio indicator would be the next best thing here if dislike counts are being removed.

mat926 commented 2 years ago

Youtube/Google themselves are a joke.

elliotwaite commented 2 years ago

@NeveHanter, thanks for letting me know about this, and thanks for the kind words.

@Nornec, yep, looks like exemptions are only supposed to be for projects that don't share dislike counts publicly.

Could this extension switch to the likes-to-views ratio?

(As "gpt5" mentions in those HN comments.)

@braham-snyder and @ryanbuening, yes. I'll start implementing this as an optional alternative for now so we can try A/B testing it to see if we can tune it to be useful since it might need some kind of exponential/log scaling factor to work well. I'll comment here when that update has been released.

Greedquest commented 2 years ago

@elliotwaite I just wonder whether there's a bit of a loophole; given we each use our own API key, it's perfectly possible we all just happened to clone this project and are working on it independently - and so there aren't really end users per-se because each one of our API calls will not be viewed by any other App user. Basically could devs still use it for WIP projects, if they are the sole user of that particular API key.

elliotwaite commented 2 years ago

@Greedquest, interesting idea. I wonder if personal use would qualify as a valid use case. If anyone wants to try this, here's a link to the application form: Developer Exemption Application Form.

The form also mentions:

An exemption will not be granted until your API Project passes a compliance audit, so if you have not passed a compliance audit, please start this process immediately.

I tried to pass a compliance audit for this extension in the past and they would take months in between replies and ask me to submit redundant data, but maybe their communication has improved since then. I'm going to pass on trying this option since my probability estimate for success is so low that it seems like a waste of time, but if anyone else wants to try this, I'd be interested in hearing what YouTube's response is.

elliotwaite commented 2 years ago

I just released an update (version 1.5.0) which adds the option to try the "Likes-to-Views" option, as well as a "Both" option for A/B testing:

Screen Shot 2021-11-11 at 2 00 26 AM

This is the current formula (it was the best I found so far), but the a and b values may need to be tuned:

likesToViews = likes / views
a = 30
b = .2
score = 1 / (1 + Math.exp(-a * (Math.pow(likesToViews, b) - 0.5)))
percentage = 100 * score

The likesToViews get exponentiated (b), shifted (- 0.5), scaled (a), and then fed through a sigmoid. You can see what this formula does and how tuning a and b would affect the output with this Desmos graph (the x-axis is the likesToViews, and y-axis is the output score between 0 and 1).

There does seem to be some correlation between the likes-to-views and likes-to-dislikes (especially with the "Exponentially scale the rating bar" option turned on, which currently only affects the likes-to-dislikes rating), but they can also differ a lot sometimes. It's definitely a different metric, but interesting in its own unique way.

Also, this update didn't change any of the tooltip text, which still only shows likes-to-dislikes info.

Let me know what you guys think.

ShadowTheAge commented 2 years ago

Exemption is pointless because without public dislikes people wouldn't use dislikes like they use now. Why make an action if it isn't going to change anything?

ryanbuening commented 2 years ago

I compared Likes-to-Dislikes vs the Likes-to-Views formula and it seems very hit or miss so far. Bottom bar is Likes-to-Views.

image

image

image

elliotwaite commented 2 years ago

I compared Likes-to-Dislikes vs the Likes-to-Views formula and it seems very hit or miss so far. Bottom bar is Likes-to-Views.

@ryanbuening, yeah, it might be more of an engagement rating rather than the normal likes rating.

Also, videos that are run as ads will probably have low engagement. I saw this one in the trending section and it has very few likes (2,688) given its total views (1.2M), so I'm guessing Amazon ran it as a YouTube ad.

Screen Shot 2021-11-11 at 6 48 44 AM
ShadowTheAge commented 2 years ago

Train some machine learning construct that guesses the amount of dislikes based on the amount of likes, views and comments and video length? While we still have access to the data

Greedquest commented 2 years ago

@ShadowTheAge So reimplement YouTube's video suggestion algorithm! I mean that's basically what this extension is for, to allow you to pick the videos you want to watch based on community approval.

@ryanbuening Yeah, it is more of an engagement metric. Music videos for example will have most people just playing it in the background or autosuggested, less likely to interact with it. Or a 3 hour tutorial probably is watched once and never again so people won't remember to go back and like that video they watched over and over again.

Greedquest commented 2 years ago

@elliotwaite Another interesting thing to see would be Likes : Comment count (likes on video per comment) - since both of these are positively correlated with "engagement" dividing one by the other could cancel that factor out. They are also both proportional to views, so dividing one by the other gives a dimensionless metric independent of view count (just like likes/dislikes).

Tl;Dr:

Comments  ∝ TotViews * Engagement  (i.e. Comments increase with both "engagement" and number of views)
Likes     ∝ +veViews * Engagement
Dislikes  ∝ -veViews * Engagement
(TotViews = +veViews + -veViews)

∴

Likes / Dislikes ∝ +veViews / -veViews                (what we had before)
Likes / Views    ∝ +veViews * Engagement / TotViews   (what we have now - meaning it varies with video engagement as well as positive reception)
Likes / Comments ∝ +veViews / TotViews                (proposal)
Leopold702 commented 2 years ago

Someone should create an independent dislike database + browser extension that will work on the same principle as SponsorBlock. It might be even possible to fetch and archive the current dislike counts, since API should remain working till December 13th.

elliotwaite commented 2 years ago

Train some machine learning construct that guesses the amount of dislikes based on the amount of likes, views and comments and video length? While we still have access to the data

@ShadowTheAge, interesting idea. Perhaps just a standard sentiment analysis model would work, even if it's not trained to predict the likes-to-dislikes rating. It could show the average of some number of the top comments. I may try that at some point, but it would take a bit of work to implement.

Someone should create an independent dislike database + browser extension that will work on the same principle as SponsorBlock. It might be even possible to fetch and archive the current dislike counts, since API should remain working till December 13th.

@Leopold702, that could potentially work too. If the extension gained enough users (reached the critical mass point in network effect terms), maybe even just showing the likes/dislikes of only the people who use the extension would be useful. But that might require a lot more users. I might try that too, but this would also require a bit of work to set up.

elliotwaite commented 2 years ago

@elliotwaite Another interesting thing to see would be Likes : Comment count (likes on video per comment) - since both of these are positively correlated with "engagement" dividing one by the other could cancel that factor out. They are also both proportional to views, so dividing one by the other gives a dimensionless metric independent of view count (just like likes/dislikes).

@Greedquest, interesting idea. I just added this option (Likes-to-Comments) in version 1.5.2, as well as some options to A/B test it against the others.

The current function used is:

likesToComments = likes / comments
a = 0.15
score = 1 - Math.exp(-a * likesToComments)
percentage = 100 * score

And here's the Desmos graph for that function.

This one is interesting too. From looking at how it scores Shorts, it may give them a slightly higher rating, maybe because people watching Shorts are more likely to just like and swipe to the next one rather than also leave a comment, but even if that is true it might not be an issue.

Let me know what you guys think about this one.

Gaeriel commented 2 years ago

For me, what almost always gives me good results, is max(LtV,LtC) with the constants you're using now. Other constants might give better results, but I don't know how to test that.

Sometimes, neither work very well, I believe that's mostly with channels that incite discussions (PBS Space Time is an example). I believe that could be solved by not using the number of comments, but the number of commenters, but I suppose that data is not easily available?

Also: the ratio should also be shown on the video page, not only on the thumbnail, although I seldomly look at the ratio after I click on a video: that's what this extension is for :)

Greedquest commented 2 years ago

@Gaeriel yeah number of commenters rather than comments is a good shout, as like votes are one per user. Looking at the docs, unique commenter count is not one of the v3 api endpoints so it would probably require manual iteration over all the comments accumulating by user id, so could take a few minutes per video (a bit more complex to implement in a performant way than the current statistics but not impossible with some caching).

Alternatively I guess if number of unique commenters is proportional to engagement, and comments per user is also proportional, then maybe total comments are actually proportional to engagement squared. In which case a statistic like Likes^2 / (Comments * TotViews) might have better dimensions. At this point some dataset and graphs might be nice :)

Marfa commented 2 years ago

There's Tampermoneky script. It works through YouTube Data API key. However I don't understand how it gets dislike count, I'm not programmer.

And there's TODO "Real count", so...

Gaeriel commented 2 years ago

However I don't understand how it gets dislike count, I'm not programmer.

It looks like he uses the API to get it, so it won't work after December 13

Gaeriel commented 2 years ago

I found this on r/youtube : https://old.reddit.com/r/youtube/comments/qtyn45/i_coded_a_userscript_to_restore_the_dislike/?ref=share&ref_source=link

He claims an almost 100% accuracy of reproducing the dislike count, but his code is obfuscated, so I have no idea how he does it. It might be worth contacting him.

elliotwaite commented 2 years ago

I found this on r/youtube : https://old.reddit.com/r/youtube/comments/qtyn45/i_coded_a_userscript_to_restore_the_dislike/?ref=share&ref_source=link

He claims an almost 100% accuracy of reproducing the dislike count, but his code is obfuscated, so I have no idea how he does it. It might be worth contacting him.

@Gaeriel, thanks for sharing. I am skeptical but open to being proven wrong. Is there a way to test out if that code actually works prior to YouTube actually removing the dislike info?

Gaeriel commented 2 years ago

I'm skeptical too and I don't trust obfuscated code. I can think of no way of testing if it works without the dislike info in the API response, except for reverse engineering it. I tried a de-obfuscator, but it's still very obfuscated :)

elliotwaite commented 2 years ago

I'm skeptical too and I don't trust obfuscated code. I can think of no way of testing if it works without the dislike info in the API response, except for reverse engineering it. I tried a de-obfuscator, but it's still very obfuscated :)

I looked into deobfuscating it too. It looks doable but would probably take a while. For now, I'll wait till YouTube actually removes the dislikes to see if that code still works before pursuing this option further.

Gaeriel commented 2 years ago

he deobfuscated it :) https://textbin.net/8iyxfntpaa

Ok, so apparently there's still a ratio available on the page for the video:

document.querySelector("ytd-app").data.playerResponse.videoDetails.averageRating

He calculates the dislikes using that ratio and this formula:

Math.round(likes*((5-ratio)/(ratio-1)))

marvellz commented 2 years ago

Hi, guys. There is a given solution: https://github.com/Anarios/return-youtube-dislike Maybe collaboration 🤔

elliotwaite commented 2 years ago

document.querySelector("ytd-app").data.playerResponse.videoDetails.averageRating

@Gaeriel, got it. I'm assuming YouTube will remove that info as well when they remove the dislikes, but if they don't, I'll switch over the code to using it.

Hi, guys. There is a given solution: https://github.com/Anarios/return-youtube-dislike Maybe collaboration 🤔

@marvellz, thanks for the info. Looks like they are considering a similar strategy to what has been discussed here. I'm planning on implementing a strategy like this for this extension, but if for some reason their solution ends up being better, perhaps we can try to collab with them where we use their backend instead or something.

Anarios commented 2 years ago

@elliotwaite, will be happy to colab.

elliotwaite commented 2 years ago

@elliotwaite, will be happy to colab.

@Anarios, awesome. The plan that I'm currently considering is to get as much data as I can on past videos, then figure out a good way to predict dislikes based on that data (maybe a simple function, maybe a small neural network if needed), then also add a login for users so that I can track their likes/dislikes if they are logged in. Then make an API that can be called by logged-in users that will combine all of that (past data, user data, prediction model) to get a dislike estimate for specific videos.

It seems like your planned strategy is similar. I'm not sure what the best way to collab would be, but let me know if you have any ideas.

Anarios commented 2 years ago

At least sharing user-generated dislike data to avoid fragmentation is a must.

elliotwaite commented 2 years ago

At least sharing user-generated dislike data to avoid fragmentation is a must.

I have some concerns about sharing user data as the Chrome Web Store's Developer Program Policy seems to be pretty strict about it.

elliotwaite commented 2 years ago

Some are speculating that YouTube might actually not follow through with the change, but it looks like it's just speculation at this point: YouTube appears to backflip on controversial dislike removal announcement

ajayyy commented 2 years ago

If you haven't seen, this is what I'm working on https://github.com/ajayyy/SponsorBlock/issues/1039

I have some concerns about sharing user data

It should be fine sharing data when it's just the number of upvotes and downvotes per video, as that is not "user data". My plan was to always have explicit consent, ie. the user must click a submit button after clicking YouTube's button, so they can choose not to submit likes on some videos.

elliotwaite commented 2 years ago

If you haven't seen, this is what I'm working on ajayyy/SponsorBlock#1039

@ajayyy, thanks for letting me know. It looks like you are considering building a new extension to address the likes/dislikes situation. Your SponsorBlock extension has a lot of users, so your new extension might become the go-to one for crowd-sourced ratings. If your new extension makes this extension obsolete, I'm okay with that. Feel free to use any of the code in this repo if you want. Or if this extension could call into your API, maybe that would work too, and then I could advertise to my users to install your extension to contribute to your likes/dislikes database.

It might also be good if I try to create my own API solution as well so that users could test out both to see if there are benefits to doing it one way over the other. Perhaps they would be complimentary, or maybe users would just converge to one of them.

I mainly just want users to be able to see a useful rating bar on each video thumbnail in a way that is a good user experience. Whether that's through this extension or yours or a combo of the two is fine with me.

elliotwaite commented 2 years ago

@Anarios and @ajayyy, I'm thinking of adding an option to this extension to let users choose which backend likes/dislikes API to use. If you are both building APIs, I'd like to add both of your APIs as options. Would this work? If so, how can I call into your APIs?

I also have a collection of recent public YouTube likes/dislikes data that I could share with both of you if you could use it.

Also, feel free to DM me on Twitter if you'd like to discuss anything privately: https://twitter.com/elliotwaite

ajayyy commented 2 years ago

Here is the API docs for the one I am working on: https://wiki.sponsor.ajay.app/w/API_Docs/Ratings

No front-end exists for it yet, but it should still work right now.

The extra reporting categories described in https://github.com/ajayyy/SponsorBlock/issues/1039#issuecomment-972397761 are not implemented yet, but they will be added in a backwards compatible way.

elliotwaite commented 2 years ago

@ajayyy, thanks for the info. Would it be possible to add batch request support, similar to how the YouTube API does it, where it allows the video ID field to be a string of comma-separated video IDs (up to 50 per request)? So with your API, perhaps it would allow the prefix value to be a string of comma-separated video ID hash prefixes.

Also, for the video IDs I tried, I only get an empty array returned. Can you recommend a video ID that you have stats for in your database that I can test against?

Anarios commented 2 years ago

http://returnyoutubedislikeapi.com/swagger

here is mine. Main thing that you want is GET /votes?videoId

It's rate limited by IP though.

ajayyy commented 2 years ago

@elliotwaite Added a bulk fetching API

Example (most network libraries can convert from array to repeated parameter):

https://sponsor.ajay.app/api/ratings/rate?prefix=6745&prefix=5f6b

or

https://sponsor.ajay.app/api/ratings/rate?hashPrefixes=["6745","5f6b"]

[
  {
    "videoID": "jNQXAC9IVRw",
    "hash": "67454704342df24de2d91fae262fc75b3c9735d45135a6273239d4e68037d15c",
    "type": 1,
    "count": 1
  },
  {
    "videoID": "dQw4w9WgXcQ",
    "hash": "5f6b0b4e201f2a7e66927abb5cadeec81624dcc8efe6644b78aa182213f653a2",
    "type": 1,
    "count": 1
  }
]

Since I haven't finished the front-end yet, there isn't any data in the DB except for the example videos I linked.

elliotwaite commented 2 years ago

@ajayyy, okay, thanks. That should work for now.

elliotwaite commented 2 years ago

http://returnyoutubedislikeapi.com/swagger

here is mine. Main thing that you want is GET /votes?videoId

It's rate limited by IP though.

@Anarios, thanks, looks good. Would you be open to adding support for batch requests? My extension often needs to request data for many videos at a time (usually around 30 to 70). One way it could be implemented is to allow videoId to be a string of comma-separated video IDs, in which case (if a comma is detected in the string) it would return an array of data for those IDs. And you could cap it at 50 IDs per request or something.

elliotwaite commented 2 years ago

@Anarios and @ajayyy, have either of you considered this idea for your extensions (sorry if this isn't new or if you are already planning to do this):

This data could then be used to help extrapolate the real stats. For example, if a video has 80 likes and 20 dislikes in your user DB, and the actual video has a total of 800 likes, you could estimate it also has 200 dislikes. Also, the login requirement would help prevent people from abusing the API since each user could only like/dislike a video once.

elliotwaite commented 2 years ago

I updated the extension (version 1.6.x) to use the Return YouTube Dislike API. The Chrome version is going through the review process and the Firefox version is already available.

@ajayyy, I can add your API as an option as well once it's ready.

MichaelMMasi commented 2 years ago

@elliotwaite For many years, I have considered this extension to be a critical component to maximize Youtube viewing experience & productivity. I have been meaning to create an account here to praise and thank you for you work for some time.

I was dismayed when I heard the news that Google would be removing dislikes from Youtube.

I'm thrilled to see that you are still working to get around the new limitations and continue to provide an extension that at least mimics and substitutes the like/dislike ratio with something that serves a similar purpose. (I thought this would surely be the end of the road for the extension).

Thanks!

elliotwaite commented 2 years ago

@MichaelMMasi, thanks for the comment!

elliotwaite commented 2 years ago

The Chrome version is now available. After the update, you may need to approve the updated permissions to reenable the extension. The new permissions enable making API calls to returnyoutubedislikeapi.com.

elliotwaite commented 2 years ago

The new API is rate-limited by IP address, so let me know if any of you are running into rate-limiting issues, such as the rating bar not being added to some of the thumbnails.

Right now the extension caches ratings for the lifetime of the tab session, meaning that if you browse YouTube in the same tab without refreshing the page, any thumbnails that you come across for a second time will just use the cached rating instead of making a new API call. However, if you refresh the tab, or open a new tab, the cache for that tab is reset. But if needed, I could also enable a global cache across all tabs that is time-based, which might help further reduce the number of API calls.