From 8eca5b270ed10b6233371f5495cf059bc353dcb1 Mon Sep 17 00:00:00 2001 From: techmetx11 Date: Sat, 14 Jan 2023 01:49:58 +0100 Subject: [PATCH 1/4] Video: Fix 0 views, and empty license field --- locales/en-US.json | 1 + src/invidious/videos/parser.cr | 2 +- src/invidious/views/watch.ecr | 6 +++++- 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/locales/en-US.json b/locales/en-US.json index a5c16fd7..fbcc1341 100644 --- a/locales/en-US.json +++ b/locales/en-US.json @@ -183,6 +183,7 @@ "Show annotations": "Show annotations", "Genre: ": "Genre: ", "License: ": "License: ", + "Standard YouTube license": "Standard YouTube license", "Family friendly? ": "Family friendly? ", "Wilson score: ": "Wilson score: ", "Engagement: ": "Engagement: ", diff --git a/src/invidious/videos/parser.cr b/src/invidious/videos/parser.cr index cf43f1be..04ee7303 100644 --- a/src/invidious/videos/parser.cr +++ b/src/invidious/videos/parser.cr @@ -186,7 +186,7 @@ def parse_video_info(video_id : String, player_response : Hash(String, JSON::Any # then from videoDetails, as the latter is "0" for livestreams (we want # to get the amount of viewers watching). views_txt = video_primary_renderer - .try &.dig?("viewCount", "videoViewCountRenderer", "viewCount", "runs", 0, "text") + .try &.dig?("viewCount", "videoViewCountRenderer", "viewCount", "simpleText") views_txt ||= video_details["viewCount"]? views = views_txt.try &.as_s.gsub(/\D/, "").to_i64? diff --git a/src/invidious/views/watch.ecr b/src/invidious/views/watch.ecr index 666eb3b0..c23a9552 100644 --- a/src/invidious/views/watch.ecr +++ b/src/invidious/views/watch.ecr @@ -181,7 +181,11 @@ we're going to need to do it here in order to allow for translations. <% end %>

<% if video.license %> -

<%= translate(locale, "License: ") %><%= video.license %>

+ <% if video.license == "" %> +

<%= translate(locale, "License: ") %><%= translate(locale, "Standard YouTube license") %>

+ <% else %> +

<%= translate(locale, "License: ") %><%= video.license %>

+ <% end %> <% end %>

<%= translate(locale, "Family friendly? ") %><%= translate_bool(locale, video.is_family_friendly) %>

From 4ac263f1dfdc18e5de584d4fb8bbfd74141e2716 Mon Sep 17 00:00:00 2001 From: techmetx11 Date: Sun, 15 Jan 2023 16:26:51 +0100 Subject: [PATCH 2/4] Replace == with empty? --- src/invidious/views/watch.ecr | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/invidious/views/watch.ecr b/src/invidious/views/watch.ecr index c23a9552..1fc79495 100644 --- a/src/invidious/views/watch.ecr +++ b/src/invidious/views/watch.ecr @@ -181,7 +181,7 @@ we're going to need to do it here in order to allow for translations. <% end %>

<% if video.license %> - <% if video.license == "" %> + <% if video.license.empty? %>

<%= translate(locale, "License: ") %><%= translate(locale, "Standard YouTube license") %>

<% else %>

<%= translate(locale, "License: ") %><%= video.license %>

From 1f3317e257745a7ef4c44fcf8748ec18fe401fb0 Mon Sep 17 00:00:00 2001 From: Samantaz Fox Date: Mon, 27 Feb 2023 21:55:28 +0100 Subject: [PATCH 3/4] Update video spec --- mocks | 2 +- .../videos/regular_videos_extract_spec.cr | 36 ++--- .../videos/scheduled_live_extract_spec.cr | 148 ++---------------- 3 files changed, 33 insertions(+), 153 deletions(-) diff --git a/mocks b/mocks index dfd53ea6..cb16e034 160000 --- a/mocks +++ b/mocks @@ -1 +1 @@ -Subproject commit dfd53ea6ceb3cbcbbce6004f6ce60b330ad0f9b1 +Subproject commit cb16e0343c8f94182615610bfe3c503db89717a7 diff --git a/spec/invidious/videos/regular_videos_extract_spec.cr b/spec/invidious/videos/regular_videos_extract_spec.cr index 132b37a3..cbe80010 100644 --- a/spec/invidious/videos/regular_videos_extract_spec.cr +++ b/spec/invidious/videos/regular_videos_extract_spec.cr @@ -17,8 +17,8 @@ Spectator.describe "parse_video_info" do # Basic video infos expect(info["title"].as_s).to eq("I Gave My 100,000,000th Subscriber An Island") - expect(info["views"].as_i).to eq(32_846_329) - expect(info["likes"].as_i).to eq(2_611_650) + expect(info["views"].as_i).to eq(115_784_415) + expect(info["likes"].as_i).to eq(4_932_790) # For some reason the video length from VideoDetails and the # one from microformat differs by 1s... @@ -46,14 +46,14 @@ Spectator.describe "parse_video_info" do # Related videos - expect(info["relatedVideos"].as_a.size).to eq(19) + expect(info["relatedVideos"].as_a.size).to eq(20) - expect(info["relatedVideos"][0]["id"]).to eq("tVWWp1PqDus") - expect(info["relatedVideos"][0]["title"]).to eq("100 Girls Vs 100 Boys For $500,000") + expect(info["relatedVideos"][0]["id"]).to eq("iogcY_4xGjo") + expect(info["relatedVideos"][0]["title"]).to eq("$1 vs $1,000,000 Hotel Room!") expect(info["relatedVideos"][0]["author"]).to eq("MrBeast") expect(info["relatedVideos"][0]["ucid"]).to eq("UCX6OQ3DkcsbYNE6H8uQQuVA") - expect(info["relatedVideos"][0]["view_count"]).to eq("49702799") - expect(info["relatedVideos"][0]["short_view_count"]).to eq("49M") + expect(info["relatedVideos"][0]["view_count"]).to eq("172972109") + expect(info["relatedVideos"][0]["short_view_count"]).to eq("172M") expect(info["relatedVideos"][0]["author_verified"]).to eq("true") # Description @@ -76,11 +76,11 @@ Spectator.describe "parse_video_info" do expect(info["ucid"].as_s).to eq("UCX6OQ3DkcsbYNE6H8uQQuVA") expect(info["authorThumbnail"].as_s).to eq( - "https://yt3.ggpht.com/ytc/AMLnZu84dsnlYtuUFBMC8imQs0IUcTKA9khWAmUOgQZltw=s48-c-k-c0x00ffffff-no-rj" + "https://yt3.ggpht.com/ytc/AL5GRJUfhQdJS6n-YJtsAf-ouS2myDavDOq_zXBfebal3Q=s48-c-k-c0x00ffffff-no-rj" ) expect(info["authorVerified"].as_bool).to be_true - expect(info["subCountText"].as_s).to eq("101M") + expect(info["subCountText"].as_s).to eq("135M") end it "parses a regular video with no descrition/comments" do @@ -99,7 +99,7 @@ Spectator.describe "parse_video_info" do # Basic video infos expect(info["title"].as_s).to eq("Chris Rea - Auberge") - expect(info["views"].as_i).to eq(10_356_197) + expect(info["views"].as_i).to eq(10_698_554) expect(info["likes"].as_i).to eq(0) expect(info["lengthSeconds"].as_i).to eq(283_i64) expect(info["published"].as_s).to eq("2012-05-21T00:00:00Z") @@ -132,16 +132,14 @@ Spectator.describe "parse_video_info" do # Related videos - expect(info["relatedVideos"].as_a.size).to eq(19) + expect(info["relatedVideos"].as_a.size).to eq(18) - expect(info["relatedVideos"][0]["id"]).to eq("0bkrY_V0yZg") - expect(info["relatedVideos"][0]["title"]).to eq( - "Chris Rea Best Songs Collection - Chris Rea Greatest Hits Full Album 2022" - ) - expect(info["relatedVideos"][0]["author"]).to eq("Rock Ultimate") - expect(info["relatedVideos"][0]["ucid"]).to eq("UCekSc2A19di9koUIpj8gxlQ") - expect(info["relatedVideos"][0]["view_count"]).to eq("1992412") - expect(info["relatedVideos"][0]["short_view_count"]).to eq("1.9M") + expect(info["relatedVideos"][0]["id"]).to eq("rfyZrJUmzxU") + expect(info["relatedVideos"][0]["title"]).to eq("cheb mami - bekatni") + expect(info["relatedVideos"][0]["author"]).to eq("pelitovic") + expect(info["relatedVideos"][0]["ucid"]).to eq("UCsp6vFyJeGoLxgn-AsHp1tw") + expect(info["relatedVideos"][0]["view_count"]).to eq("13863619") + expect(info["relatedVideos"][0]["short_view_count"]).to eq("13M") expect(info["relatedVideos"][0]["author_verified"]).to eq("false") # Description diff --git a/spec/invidious/videos/scheduled_live_extract_spec.cr b/spec/invidious/videos/scheduled_live_extract_spec.cr index ff5aacd5..9dd22b97 100644 --- a/spec/invidious/videos/scheduled_live_extract_spec.cr +++ b/spec/invidious/videos/scheduled_live_extract_spec.cr @@ -1,114 +1,13 @@ require "../../parsers_helper.cr" Spectator.describe "parse_video_info" do - it "parses scheduled livestreams data (test 1)" do - # Enable mock - _player = load_mock("video/scheduled_live_nintendo.player") - _next = load_mock("video/scheduled_live_nintendo.next") - - raw_data = _player.merge!(_next) - info = parse_video_info("QMGibBzTu0g", raw_data) - - # Some basic verifications - expect(typeof(info)).to eq(Hash(String, JSON::Any)) - - expect(info["videoType"].as_s).to eq("Scheduled") - - # Basic video infos - - expect(info["title"].as_s).to eq("Xenoblade Chronicles 3 Nintendo Direct") - expect(info["views"].as_i).to eq(160) - expect(info["likes"].as_i).to eq(2_283) - expect(info["lengthSeconds"].as_i).to eq(0_i64) - expect(info["published"].as_s).to eq("2022-06-22T14:00:00Z") # Unix 1655906400 - - # Extra video infos - - expect(info["allowedRegions"].as_a).to_not be_empty - expect(info["allowedRegions"].as_a.size).to eq(249) - - expect(info["allowedRegions"].as_a).to contain( - "AD", "BA", "BB", "BW", "BY", "EG", "GG", "HN", "NP", "NR", "TR", - "TT", "TV", "TW", "TZ", "VA", "VC", "VE", "VG", "VI", "VN", "VU", - "WF", "WS", "YE", "YT", "ZA", "ZM", "ZW" - ) - - expect(info["keywords"].as_a).to_not be_empty - expect(info["keywords"].as_a.size).to eq(11) - - expect(info["keywords"].as_a).to contain_exactly( - "nintendo", - "game", - "gameplay", - "fun", - "video game", - "action", - "adventure", - "rpg", - "play", - "switch", - "nintendo switch" - ).in_any_order - - expect(info["allowRatings"].as_bool).to be_true - expect(info["isFamilyFriendly"].as_bool).to be_true - expect(info["isListed"].as_bool).to be_true - expect(info["isUpcoming"].as_bool).to be_true - - # Related videos - - expect(info["relatedVideos"].as_a.size).to eq(20) - - # related video #1 - expect(info["relatedVideos"][3]["id"].as_s).to eq("a-SN3lLIUEo") - expect(info["relatedVideos"][3]["author"].as_s).to eq("Nintendo") - expect(info["relatedVideos"][3]["ucid"].as_s).to eq("UCGIY_O-8vW4rfX98KlMkvRg") - expect(info["relatedVideos"][3]["view_count"].as_s).to eq("147796") - expect(info["relatedVideos"][3]["short_view_count"].as_s).to eq("147K") - expect(info["relatedVideos"][3]["author_verified"].as_s).to eq("true") - - # Related video #2 - expect(info["relatedVideos"][16]["id"].as_s).to eq("l_uC1jFK0lo") - expect(info["relatedVideos"][16]["author"].as_s).to eq("Nintendo") - expect(info["relatedVideos"][16]["ucid"].as_s).to eq("UCGIY_O-8vW4rfX98KlMkvRg") - expect(info["relatedVideos"][16]["view_count"].as_s).to eq("53510") - expect(info["relatedVideos"][16]["short_view_count"].as_s).to eq("53K") - expect(info["relatedVideos"][16]["author_verified"].as_s).to eq("true") - - # Description - - description = "Tune in on 6/22 at 7 a.m. PT for a livestreamed Xenoblade Chronicles 3 Direct presentation featuring roughly 20 minutes of information about the upcoming RPG adventure for Nintendo Switch." - - expect(info["description"].as_s).to eq(description) - expect(info["shortDescription"].as_s).to eq(description) - expect(info["descriptionHtml"].as_s).to eq(description) - - # Video metadata - - expect(info["genre"].as_s).to eq("Gaming") - expect(info["genreUcid"].as_s).to be_empty - expect(info["license"].as_s).to be_empty - - # Author infos - - expect(info["author"].as_s).to eq("Nintendo") - expect(info["ucid"].as_s).to eq("UCGIY_O-8vW4rfX98KlMkvRg") - - expect(info["authorThumbnail"].as_s).to eq( - "https://yt3.ggpht.com/ytc/AKedOLTt4vtjREUUNdHlyu9c4gtJjG90M9jQheRlLKy44A=s48-c-k-c0x00ffffff-no-rj" - ) - - expect(info["authorVerified"].as_bool).to be_true - expect(info["subCountText"].as_s).to eq("8.5M") - end - - it "parses scheduled livestreams data (test 2)" do + it "parses scheduled livestreams data" do # Enable mock _player = load_mock("video/scheduled_live_PBD-Podcast.player") _next = load_mock("video/scheduled_live_PBD-Podcast.next") raw_data = _player.merge!(_next) - info = parse_video_info("RG0cjYbXxME", raw_data) + info = parse_video_info("N-yVic7BbY0", raw_data) # Some basic verifications expect(typeof(info)).to eq(Hash(String, JSON::Any)) @@ -117,11 +16,11 @@ Spectator.describe "parse_video_info" do # Basic video infos - expect(info["title"].as_s).to eq("The Truth About Greenpeace w/ Dr. Patrick Moore | PBD Podcast | Ep. 171") - expect(info["views"].as_i).to eq(24) - expect(info["likes"].as_i).to eq(22) + expect(info["title"].as_s).to eq("Home Team | PBD Podcast | Ep. 241") + expect(info["views"].as_i).to eq(6) + expect(info["likes"].as_i).to eq(7) expect(info["lengthSeconds"].as_i).to eq(0_i64) - expect(info["published"].as_s).to eq("2022-07-14T13:00:00Z") # Unix 1657803600 + expect(info["published"].as_s).to eq("2023-02-28T14:00:00Z") # Unix 1677592800 # Extra video infos @@ -173,39 +72,22 @@ Spectator.describe "parse_video_info" do expect(info["relatedVideos"].as_a.size).to eq(20) - # related video #1 - expect(info["relatedVideos"][2]["id"]).to eq("La9oLLoI5Rc") - expect(info["relatedVideos"][2]["author"]).to eq("Tom Bilyeu") - expect(info["relatedVideos"][2]["ucid"]).to eq("UCnYMOamNKLGVlJgRUbamveA") - expect(info["relatedVideos"][2]["view_count"]).to eq("13329149") - expect(info["relatedVideos"][2]["short_view_count"]).to eq("13M") - expect(info["relatedVideos"][2]["author_verified"]).to eq("true") - - # Related video #2 - expect(info["relatedVideos"][9]["id"]).to eq("IQ_4fvpzYuA") - expect(info["relatedVideos"][9]["author"]).to eq("Business Today") - expect(info["relatedVideos"][9]["ucid"]).to eq("UCaPHWiExfUWaKsUtENLCv5w") - expect(info["relatedVideos"][9]["view_count"]).to eq("26432") - expect(info["relatedVideos"][9]["short_view_count"]).to eq("26K") - expect(info["relatedVideos"][9]["author_verified"]).to eq("true") + expect(info["relatedVideos"][0]["id"]).to eq("j7jPzzjbVuk") + expect(info["relatedVideos"][0]["author"]).to eq("Democracy Now!") + expect(info["relatedVideos"][0]["ucid"]).to eq("UCzuqE7-t13O4NIDYJfakrhw") + expect(info["relatedVideos"][0]["view_count"]).to eq("7576") + expect(info["relatedVideos"][0]["short_view_count"]).to eq("7.5K") + expect(info["relatedVideos"][0]["author_verified"]).to eq("true") # Description - description_start_text = <<-TXT - PBD Podcast Episode 171. In this episode, Patrick Bet-David is joined by Dr. Patrick Moore and Adam Sosnick. - - Join the channel to get exclusive access to perks: https://bit.ly/3Q9rSQL - TXT + description_start_text = "PBD Podcast Episode 241. The home team is ready and at it again with the latest news, interesting topics and trending conversations on topics that matter. Try our sponsor Aura for 14 days free - https://aura.com/pbd" expect(info["description"].as_s).to start_with(description_start_text) expect(info["shortDescription"].as_s).to start_with(description_start_text) expect(info["descriptionHtml"].as_s).to start_with( - <<-TXT - PBD Podcast Episode 171. In this episode, Patrick Bet-David is joined by Dr. Patrick Moore and Adam Sosnick. - - Join the channel to get exclusive access to perks: bit.ly/3Q9rSQL - TXT + "PBD Podcast Episode 241. The home team is ready and at it again with the latest news, interesting topics and trending conversations on topics that matter. Try our sponsor Aura for 14 days free - aura.com/pbd" ) # Video metadata @@ -223,6 +105,6 @@ Spectator.describe "parse_video_info" do "https://yt3.ggpht.com/61ArDiQshJrvSXcGLhpFfIO3hlMabe2fksitcf6oGob0Mdr5gztdkXxRljICUodL4iuTSrtxW4A=s48-c-k-c0x00ffffff-no-rj" ) expect(info["authorVerified"].as_bool).to be_false - expect(info["subCountText"].as_s).to eq("227K") + expect(info["subCountText"].as_s).to eq("594K") end end From 4ae158ef6dcb89c2cd0eec646a42f11ebc207fba Mon Sep 17 00:00:00 2001 From: Samantaz Fox Date: Sun, 19 Mar 2023 22:44:59 +0100 Subject: [PATCH 4/4] Videos: Add back support for views on livestreams --- src/invidious/videos/parser.cr | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/invidious/videos/parser.cr b/src/invidious/videos/parser.cr index 04ee7303..efc4b2e5 100644 --- a/src/invidious/videos/parser.cr +++ b/src/invidious/videos/parser.cr @@ -185,10 +185,12 @@ def parse_video_info(video_id : String, player_response : Hash(String, JSON::Any # We have to try to extract viewCount from videoPrimaryInfoRenderer first, # then from videoDetails, as the latter is "0" for livestreams (we want # to get the amount of viewers watching). - views_txt = video_primary_renderer - .try &.dig?("viewCount", "videoViewCountRenderer", "viewCount", "simpleText") - views_txt ||= video_details["viewCount"]? - views = views_txt.try &.as_s.gsub(/\D/, "").to_i64? + views_txt = extract_text( + video_primary_renderer + .try &.dig?("viewCount", "videoViewCountRenderer", "viewCount") + ) + views_txt ||= video_details["viewCount"]?.try &.as_s || "" + views = views_txt.gsub(/\D/, "").to_i64? length_txt = (microformat["lengthSeconds"]? || video_details["lengthSeconds"]) .try &.as_s.to_i64