channel-worker 2.5.27 → 2.5.28
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/scripts/warmup_youtube.js +19 -22
package/package.json
CHANGED
|
@@ -114,28 +114,24 @@ async function collectResultVideoUrls(page) {
|
|
|
114
114
|
// skippable ad; non-skippable ads have no button (we wait them out). Multiple
|
|
115
115
|
// pre-rolls can chain, so this is called every tick of the watch loop.
|
|
116
116
|
async function trySkipAd(page) {
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
const phrases = /bỏ qua quảng cáo|skip ad\b|skip ads/i;
|
|
133
|
-
for (const b of document.querySelectorAll('.ytp-ad-skip-button-text, .ytp-ad-skip-button button, button')) {
|
|
134
|
-
const t = (b.innerText || b.textContent || '').trim();
|
|
135
|
-
if (t && phrases.test(t) && b.offsetParent !== null) { b.click(); return true; }
|
|
117
|
+
// Use Playwright's real .click() (trusted pointer event) — a synthetic
|
|
118
|
+
// el.click() from page.evaluate is ignored by YouTube's player, so the ad
|
|
119
|
+
// never actually skipped (saw 52 "skips" with the ad still playing). The
|
|
120
|
+
// skip button only becomes clickable ~5s into the ad; an early click times
|
|
121
|
+
// out → return false → retried next tick.
|
|
122
|
+
const sels = [
|
|
123
|
+
'.ytp-ad-skip-button-modern',
|
|
124
|
+
'.ytp-ad-skip-button',
|
|
125
|
+
'.ytp-skip-ad-button',
|
|
126
|
+
'.ytp-ad-skip-button-container button',
|
|
127
|
+
];
|
|
128
|
+
for (const s of sels) {
|
|
129
|
+
const loc = page.locator(s).first();
|
|
130
|
+
if (await loc.isVisible().catch(() => false)) {
|
|
131
|
+
try { await loc.click({ timeout: 1500 }); return true; } catch { /* not yet clickable */ }
|
|
136
132
|
}
|
|
137
|
-
|
|
138
|
-
|
|
133
|
+
}
|
|
134
|
+
return false;
|
|
139
135
|
}
|
|
140
136
|
|
|
141
137
|
// True while an ad is ACTUALLY playing (pre/mid-roll). Relies on the player's
|
|
@@ -187,7 +183,8 @@ async function watchVideo(page, url, minSec, maxSec, log) {
|
|
|
187
183
|
await page.waitForTimeout(TICK);
|
|
188
184
|
}
|
|
189
185
|
if (skips) log('info', `[warmup] ${url.slice(-11)} — skipped ${skips} ad tick(s), real watch ${Math.round(realWatched/1000)}s`);
|
|
190
|
-
|
|
186
|
+
// Only count as a watched video if real (non-ad) content actually played.
|
|
187
|
+
return realWatched > 0;
|
|
191
188
|
} catch (e) {
|
|
192
189
|
log('warn', `[warmup] watch failed (${url.slice(-11)}): ${String(e.message || e).slice(0, 100)}`);
|
|
193
190
|
return false;
|