From 7f990b061a1b0ade750219310b1b47b1d9c623a7 Mon Sep 17 00:00:00 2001 From: XZH Date: Sat, 5 Sep 2026 00:41:45 -0700 Subject: [PATCH] fix(captions): rank human tracks before regional specificity Keep preference slot first, then human before auto-generated, and only then use language specificity so an exact auto regional match cannot beat a human base-language track. --- spec/invidious/videos/captions_matching_spec.cr | 8 ++++++++ src/invidious/videos/caption.cr | 5 +++-- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/spec/invidious/videos/captions_matching_spec.cr b/spec/invidious/videos/captions_matching_spec.cr index ec36a9754..7ad0abde2 100644 --- a/spec/invidious/videos/captions_matching_spec.cr +++ b/spec/invidious/videos/captions_matching_spec.cr @@ -51,6 +51,14 @@ Spectator.describe Invidious::Videos::Captions do expect(matched.map(&.name)).to eq(["en-US", "en-GB"]) end + it "prefers human base-language English over exact regional auto-generated" do + human = Invidious::Videos::Captions::Metadata.new("English", "en", "http://x", false) + auto_us = Invidious::Videos::Captions::Metadata.new("en-US", "en-US", "http://x", true) + + matched = Invidious::Videos::Captions.matching([auto_us, human], ["English (United States)"]) + expect(matched.map(&.name)).to eq(["English", "en-US"]) + end + it "ignores blank preference slots" do arabic = Invidious::Videos::Captions::Metadata.new("Arabic (auto-generated)", "ar", "http://x", true) matched = Invidious::Videos::Captions.matching([arabic], ["", "", ""]) diff --git a/src/invidious/videos/caption.cr b/src/invidious/videos/caption.cr index 7340ffcb7..bdc498c96 100644 --- a/src/invidious/videos/caption.cr +++ b/src/invidious/videos/caption.cr @@ -87,7 +87,8 @@ module Invidious::Videos end # Tracks whose name or language matches the user's caption preferences, - # ranked by preference slot then human tracks before auto-generated. + # ranked by preference slot, then human tracks before auto-generated, + # then more-specific language matches ahead of base-language fallbacks. def self.matching(captions : Array(Metadata), names : Array(String)) : Array(Metadata) wanted = names.map(&.strip).reject(&.empty?) return [] of Metadata if wanted.empty? @@ -208,7 +209,7 @@ module Invidious::Videos end auto_rank = caption.auto_generated ? 1 : 0 - {pref_rank, specificity, auto_rank} + {pref_rank, auto_rank, specificity} end # List of all caption languages available on Youtube.