trying to only use next endpoint for the major data#5003
trying to only use next endpoint for the major data#5003unixfox wants to merge 3 commits intoiv-org:masterfrom
Conversation
de76e24 to
250cffb
Compare
da00958 to
a340868
Compare
60a5c1c to
9438a6d
Compare
|
Thank you very much for this. Looking at instance yewtu.be which uses invidious-custom, it seems to be working just as expected, exactly as described in my linked issue, and with a 100% success rate. Thank you for this great work - this is a huge step towards making Invidious convenient to use again. For me personally, it solves the entire problem. The only thing I can potentially suggest is for the video thumbnail to be loaded and displayed on the page, separately from the broken video player. But that would be just a nice-to-have feature, and I'm guessing it may not be trivial to implement, when the official Youtube website just shows a black error screen, with the thumbnail nowhere to be seen. |
| if reason = info["reason"]? | ||
| if info["reason"]? && info["subreason"]? | ||
| reason = info["reason"].as_s | ||
| puts info |
There was a problem hiding this comment.
Please remove the debug puts here
| next_steps = error_redirect_helper(env) | ||
| error_message = <<-END_HTML | ||
| <div class="error_message"> | ||
| <h2>#{translate(locale, "error_processing_data_youtube")}</h2> | ||
| <p>#{translate(locale, message)}</p> | ||
| #{error_redirect_helper(env)} | ||
| </div> | ||
| END_HTML |
There was a problem hiding this comment.
Your changes here will show the Error while processing the data sent by YouTube message on any InfoException while also removing the next steps message on all InfoExceptions
Example:
And InfoExceptions are raised in places unrelated to YouTube as well such as when a user inserts the wrong password.
Related: #4651
|
|
||
| <div class="h-box"> | ||
| <%= error_message %> | ||
| <%= next_steps %> |
There was a problem hiding this comment.
The error page is used for everything and not just the watch page, so it must contain at least the "refresh" and "switch instance" buttons. Alternatively, we could split the error page logic for the watch page from the rest.
| <%= translate(locale, "error_from_youtube_unplayable") %> <%= video.reason %> | ||
| </h3> | ||
| <h3> | ||
| <%= translate(locale, "next_steps_error_message") %> |
There was a problem hiding this comment.
You probably want to use error_redirect_helper(). This error message alone (without any actions listed underneath) will be very confusing.
| <span id="refresh-page"> | ||
| <a href="<% env.request.resource %>"><%= translate(locale, "refresh_page") %></a> | ||
| </span> |
There was a problem hiding this comment.
Why did you add this link here? All browsers allow to refresh the page natively, and the close procimity with the "watch on youtube" link is prone to miss-clicks.
| if !(video_details = player_response.dig?("videoDetails")) | ||
| video_details = {} of String => JSON::Any | ||
| end |
There was a problem hiding this comment.
Here you can use the more compact form:
| if !(video_details = player_response.dig?("videoDetails")) | |
| video_details = {} of String => JSON::Any | |
| end | |
| video_details = player_response.dig?("videoDetails") | |
| video_details ||= {} of String => JSON::Any |
| published_txt = video_primary_renderer | ||
| .try &.dig?("dateText", "simpleText") | ||
|
|
||
| if published_txt.try &.as_s.includes?("ago") && !published_txt.nil? | ||
| published = decode_date(published_txt.as_s.lchop("Started streaming ")) | ||
| elsif published_txt && published_txt.try &.as_s.matches?(/(\w{3} \d{1,2}, \d{4})$/) | ||
| published = Time.parse(published_txt.as_s.match!(/(\w{3} \d{1,2}, \d{4})$/)[0], "%b %-d, %Y", Time::Location::UTC) | ||
| else | ||
| published = Time.utc | ||
| end |
There was a problem hiding this comment.
Here I'd recommend using "scheduledStartTime" (see below) in the player response, as it's more accurate and doesn't need complex parsing logic.
{
"playabilityStatus": {
"status": "LIVE_STREAM_OFFLINE",
"reason": "This live event will begin in 32 hours.",
"playableInEmbed": true,
"liveStreamability": {
"liveStreamabilityRenderer": {
"videoId": "hUoukmX_BRQ",
"offlineSlate": {
"liveStreamOfflineSlateRenderer": {
"scheduledStartTime": "1729468800",
"mainText": {
"runs": [
{"text": "Live in "},
{"text": "32 hours"}
]
},
"subtitleText": {
"simpleText": "October 21 at 12:00 AM"
}
}
}
}
}
}
}| <% if video.reason %> | ||
| <h3> | ||
| <%= video.reason %> | ||
| <%= translate(locale, "error_from_youtube_unplayable") %> <%= video.reason %> |
There was a problem hiding this comment.
Ditto: keeping the error message inside a player placeholder.
| # dont error when it's a premiere. | ||
| # we already parsed most of the data and display the premiere date | ||
| raise InfoException.new(reason.as_s || "") | ||
| raise NotFoundException.new(reason + ": Video not found" || "") |
There was a problem hiding this comment.
That will expand to "Video unavailable: Video not found", which is not very explicit, imo.
| if info.dig?("subreason").nil? | ||
| subreason = info["subreason"].as_s | ||
| else | ||
| subreason = "No additional reason" | ||
| end |
There was a problem hiding this comment.
This bloc of code can be summarized to the following, as you're already checking info["subreason"]? falsiness in the parent if
| if info.dig?("subreason").nil? | |
| subreason = info["subreason"].as_s | |
| else | |
| subreason = "No additional reason" | |
| end | |
| subreason = info["subreason"].as_s |
| else | ||
| video = fetch_video(id, region) | ||
| Invidious::Database::Videos.insert(video) if !region | ||
| Invidious::Database::Videos.insert(video) if !region && !video.info.dig?("reason") |
There was a problem hiding this comment.
You should make a getter dunction inside the Video class for reason/subreason.
| "reason" => JSON::Any.new(reason), | ||
| "version" => JSON::Any.new(Video::SCHEMA_VERSION.to_i64), | ||
| "reason" => JSON::Any.new(reason), | ||
| "subreason" => JSON::Any.new(subreason), |
There was a problem hiding this comment.
Don't forget to bump SCHEMA_VERSION in the Video class!
To clarify, does this mean using the YouTube embedded player within the usual invidious video page? I know it wouldn't be "privacy respecting" in the same way as traditional invidious, so maybe as a sort of optional "compatibility mode" in the settings?
It sounds like some people have suggested something similar but instead mention just linking to the embed URL ( (heck, I found out that you can even use various custom adblock filters to hide the "fluff" of the embed player such as suggestions & recommendations, and even end-screen video links/thumbnails, which makes me wonder if even invidious could similarly do that on the server side, or if that's only possible on the client side.) ...and now as I'm typing this, I'm remembering that YouTube supposedly has a newer type of embedded player that's "brandless" and lacks the fluff? Maybe that'd be better to use for embedding into the invidious video page...except, now that I review where I read about it, sounds like it's not something the user can choose and it's determined by the video channel itself?
Honestly my main use of invidious is just avoiding the "modern" bloated web page design of "javascript all of the things!" and the like, hence why I tend to still use invidious for navigating youtube even if I subsequently watch a video via the |
No, it would just mean displaying video info even if the player is unable to be rendered for whatever reason. Everything will still be in Invidious. |
|
This should also close #4073 |
|
Found this via #4744 . Is there any feedback still needed? Can I do something to help this move forward? |
|
@mk-pmb There is still all the reviews that needs to be taken care off. If you know about crystal, I would be happy to receive some contribution. If that's what you can help us, feel free to do a PR on my branch: https://github.com/unixfox/invidious/tree/use-only-next-for-extra-info or create a new PR in the invidious project :). |
|
I don't know crystal but I can try and replicate your changes based on current master, with the suggestions from this thread applied. 👍 |
This comment was marked as outdated.
This comment was marked as outdated.
|
hello @mk-pmb, yes sure sorry for the delay. I have created the branch: https://github.com/unixfox/invidious/tree/use-only-next-for-extra-info-base I have opened the issues on my fork too. I have a better idea, I invited you as a collaborator on my forked invidious repo, this way it will be easier to work on the branch Thanks |


Description
This PR aims to avoid throwing a raw error and instead display all the data that we can extract from the /next endpoint but without displaying the "player" (video.js) element.
This is one big step towards #4985. Invidious will have to be able to display the watch page even when YouTube is blocking the IP.
This will give the same result as on www.youtube.com:
This way the user can still view the title of the video, accessing the channel page, viewing the comments and much more which is not yet blocked.
What changed?
TODO
Try these videos ID for testing - on both a blocked IP and a not blocked one
Fixes