mirror of
https://github.com/yusufipk/YouTubeOutlierBadge.git
synced 2026-09-11 10:56:14 +00:00
Merge pull request #1 from yusufipk/claude/youtube-outlier-badge-bug-d58fe1
Score cards and the watch panel again after the player endpoint closed
This commit is contained in:
+27
-2
@@ -91,11 +91,26 @@
|
||||
|
||||
/* --- Kanal kimliği --------------------------------------------------- */
|
||||
|
||||
/* Kanal sayfasındaki kartlarda kanal bağlantısı hiç bulunmuyor: zaten o
|
||||
* kanaldasın, YouTube adı kartta tekrar etmiyor. O kartların kanalı sayfanın
|
||||
* kendi adresidir, video başına ayrı bir istek atmaya gerek yok. */
|
||||
function pageChannel() {
|
||||
var path = location.pathname;
|
||||
var m = /^\/channel\/(UC[\w-]{22})(?:\/|$)/.exec(path);
|
||||
if (m) return { channelId: m[1] };
|
||||
m = /^\/(@[\w.\-]+)(?:\/|$)/.exec(path);
|
||||
if (m) return { handle: m[1] };
|
||||
/* Eski /c/ ve /user/ adresleri: çözüm için tam adres gerekiyor. */
|
||||
m = /^\/((?:c|user)\/[^/]+)(?:\/|$)/.exec(path);
|
||||
if (m) return { handle: location.origin + "/" + m[1] };
|
||||
return null;
|
||||
}
|
||||
|
||||
/* Handle'dan kanal kimliğine çözüm kalıcıdır (değişmez), o yüzden TTL'siz
|
||||
* saklanır. İzleme sayfasının yan listesinde kartta kanal bağlantısı hiç
|
||||
* olmayabiliyor; orada son çare videonun kendi ucundan sorulur. */
|
||||
function channelIdOf(card, videoId) {
|
||||
var found = handleOf(card);
|
||||
var found = handleOf(card) || pageChannel();
|
||||
if (found && found.channelId) return Promise.resolve(found.channelId);
|
||||
if (found && found.handle) {
|
||||
return OBStore.readChannelId(found.handle).then(function (cached) {
|
||||
@@ -166,6 +181,16 @@
|
||||
return m ? m[1] : null;
|
||||
}
|
||||
|
||||
/* Videonun süresi InnerTube'un next yanıtında yok, sayfanın oynatıcısından
|
||||
* okunuyor. Okunamazsa normal video sayılır: /watch adresinde açılan bir
|
||||
* Short nadir, yanlış havuzda puanlamaktansa gecikmeli doğruyu beklemek
|
||||
* anlamsız olurdu. */
|
||||
function watchIsShort() {
|
||||
if (location.pathname.indexOf("/shorts/") === 0) return true;
|
||||
var v = document.querySelector("#movie_player video");
|
||||
return !!(v && isFinite(v.duration) && v.duration > 0 && v.duration <= 60);
|
||||
}
|
||||
|
||||
function updatePanel() {
|
||||
if (!settings || !settings.enabled || !settings.showPanel) { OBPanel.remove(); return; }
|
||||
var videoId = currentWatchId();
|
||||
@@ -179,7 +204,7 @@
|
||||
details = d;
|
||||
if (!d.channelId) throw new Error("kanal bulunamadı");
|
||||
OBStore.writeChannelId("v:" + videoId, d.channelId);
|
||||
var isShort = d.lengthSeconds != null && d.lengthSeconds <= 60;
|
||||
var isShort = watchIsShort();
|
||||
return OBScore.baseline(d.channelId, isShort).then(function (blob) {
|
||||
return { blob: blob, isShort: isShort };
|
||||
});
|
||||
|
||||
+22
-8
@@ -297,16 +297,30 @@ var OBTube = (function () {
|
||||
}
|
||||
|
||||
/* Videonun kanal kimliği ve tam izlenme sayısı. Kartta kanal bağlantısı
|
||||
* bulunamadığında son çare olarak kullanılır: video başına bir istek. */
|
||||
* bulunamadığında son çare olarak kullanılır: video başına bir istek.
|
||||
*
|
||||
* Buna `player` ucu daha uygun görünür ve bir zamanlar öyleydi; oturum
|
||||
* bilgisi göndermediğimiz için artık videoların büyük çoğunluğunda
|
||||
* LOGIN_REQUIRED ("Sign in to confirm you're not a bot") dönüyor ve
|
||||
* videoDetails hiç gelmiyor. `next` aynı iki alanı oturumsuz da veriyor.
|
||||
* Yanıt büyük olduğu için bu uç bilerek son çare, ilk seçenek değil. */
|
||||
function videoDetails(videoId) {
|
||||
return post("player", { videoId: videoId }).then(function (data) {
|
||||
var d = data.videoDetails || {};
|
||||
return post("next", { videoId: videoId }).then(function (data) {
|
||||
var owner = P.findFirst(data, "videoOwnerRenderer") || {};
|
||||
var endpoint = P.findFirst(owner, "browseEndpoint") || {};
|
||||
var channelId = endpoint.browseId || "";
|
||||
var counter = P.findFirst(data, "videoViewCountRenderer") || {};
|
||||
/* viewCount tam sayıyı verir ("63,087 views"); yoksa kısaltılmışa düş.
|
||||
* Süren canlı yayında aynı alan "12,345 watching now" der; bu izlenme
|
||||
* değil anlık izleyicidir, sayı sanılırsa skor uydurma çıkar. */
|
||||
var countText = P.textOf(counter.viewCount) || P.textOf(counter.shortViewCount);
|
||||
var views = /watching/i.test(countText) ? null : P.parseCountEn(countText);
|
||||
var primary = P.findFirst(data, "videoPrimaryInfoRenderer") || {};
|
||||
return {
|
||||
channelId: d.channelId || null,
|
||||
views: d.viewCount ? parseInt(d.viewCount, 10) : null,
|
||||
title: d.title || "",
|
||||
lengthSeconds: d.lengthSeconds ? parseInt(d.lengthSeconds, 10) : null,
|
||||
isLive: !!d.isLiveContent
|
||||
channelId: /^UC[\w-]{22}$/.test(channelId) ? channelId : null,
|
||||
views: views,
|
||||
title: P.textOf(primary.title),
|
||||
publishedText: P.textOf(primary.dateText)
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
+10
-3
@@ -98,6 +98,7 @@ eq(tiny.score, null, "3'ten az örnek: skor yok");
|
||||
|
||||
console.log("\n--- gerçek InnerTube çağrısı ---");
|
||||
const CHANNEL = process.argv[2] || "UCXuqSBlHAE6Xw-yeJA0Tunw"; /* Linus Tech Tips */
|
||||
let probe = null; /* videoDetails'ı sınamak için kanalın güncel bir videosu */
|
||||
OBTube.channelTab(CHANNEL, "videos", 30).then((items) => {
|
||||
console.log("videos sekmesi: " + items.length + " video");
|
||||
const withViews = items.filter((v) => v.views);
|
||||
@@ -108,6 +109,7 @@ OBTube.channelTab(CHANNEL, "videos", 30).then((items) => {
|
||||
console.log(" " + v.videoId + " | " + OBParse.humanCount(v.views) + " | " +
|
||||
(v.ageDays == null ? "?" : v.ageDays.toFixed(1) + " gün") + " | " + v.title.slice(0, 50));
|
||||
}
|
||||
probe = withViews.length ? withViews[0] : null;
|
||||
const views = withViews.map((v) => v.views);
|
||||
console.log("medyan: " + OBParse.humanCount(OBParse.median(views)));
|
||||
if (withViews.length < 10) { fails++; console.log("FAIL izlenmesi çözülen video sayısı çok düşük"); }
|
||||
@@ -118,10 +120,15 @@ OBTube.channelTab(CHANNEL, "videos", 30).then((items) => {
|
||||
return OBTube.resolveChannel("@LinusTechTips");
|
||||
}).then((id) => {
|
||||
eq(id, CHANNEL, "handle -> kanal kimliği");
|
||||
return OBTube.videoDetails("dQw4w9WgXcQ");
|
||||
/* Bilerek kanalın güncel bir videosu: sabit bir klasik ("dQw4w9WgXcQ")
|
||||
* YouTube tarafında ayrıcalıklı davranıp uç bozulduğunda bile yanıt
|
||||
* verebiliyor ve testi yanlış yere yeşil gösteriyordu. */
|
||||
if (!probe) { fails++; console.log("FAIL sınanacak video bulunamadı"); return {}; }
|
||||
return OBTube.videoDetails(probe.videoId);
|
||||
}).then((d) => {
|
||||
console.log("player ucu: kanal " + d.channelId + ", izlenme " + OBParse.humanCount(d.views));
|
||||
if (!d.channelId) { fails++; console.log("FAIL player ucu kanal kimliği vermedi"); }
|
||||
console.log("video ucu: kanal " + d.channelId + ", izlenme " + OBParse.humanCount(d.views));
|
||||
eq(d.channelId, CHANNEL, "video ucu kanal kimliği");
|
||||
if (!d.views) { fails++; console.log("FAIL video ucu izlenme vermedi"); }
|
||||
console.log(fails ? "\n" + fails + " test başarısız" : "\nhepsi geçti");
|
||||
process.exit(fails ? 1 : 0);
|
||||
}).catch((e) => {
|
||||
|
||||
Reference in New Issue
Block a user