• YouTube ad-block इस्तेमाल करने वाले उपयोगकर्ताओं के लिए विज्ञापन दिखाने के बजाय वीडियो शुरू होने से पहले नकली buffering जैसी दिखने वाली देरी देने वाले तरीके का A/B टेस्ट कर रहा है
  • यह देरी SABR streaming के backoff से लागू की जाती है, और InnerTube पहले content /videoplayback अनुरोध पर विज्ञापन की लंबाई के 80% जितना इंतज़ार करने का जवाब देता है
  • जो उपयोगकर्ता विज्ञापन ब्लॉक नहीं करते, उनके लिए विज्ञापन चलने के दौरान content loading आगे बढ़ती रहती है, इसलिए वही backoff होने पर भी उन्हें देरी लगभग महसूस नहीं होती
  • isInlinePlaybackNoAd को true करने पर InnerTube विज्ञापन देना बंद कर देता है, इसलिए GVS stream का backoff भी गायब हो जाता है, और uBlock Origin की default filter list में इससे जुड़ा bypass शामिल है
  • कुछ प्रयोगों में YouTube JSON.stringify जैसे global objects को लॉक करने वाली locker script से filter hook को बाधित करता है, जबकि Chromium में Object.assign hook से इसका bypass किया जाता है

नकली buffering कहाँ उत्पन्न होती है

  • पिछले कुछ महीनों से YouTube नए ad-block रोकथाम उपायों का A/B टेस्ट कर रहा है
  • देखे गए उपायों में से एक नकली buffering है, जो सिर्फ वीडियो शुरू होने के समय दिखाई देती है
    • वीडियो के बीच में यह नहीं होती
    • देरी का समय उस विज्ञापन की लंबाई का 80% होता है, जो सामान्यतः दिखता
    • ad blocker इस्तेमाल करने पर भी पूरा विज्ञापन देखने की तुलना में समय बचता है
  • उदाहरण इस प्रकार हैं
    • अगर 15 सेकंड का विज्ञापन है, तो 12 सेकंड का backoff होगा
    • अगर 6 सेकंड का non-skippable विज्ञापन और 15 सेकंड का विज्ञापन साथ हों, तो 16.8 सेकंड का backoff होगा

InnerTube, GVS, SABR की भूमिका

  • InnerTube YouTube web client और mobile app द्वारा वीडियो जानकारी और विस्तृत डेटा लाने के लिए इस्तेमाल होने वाला internal API है
    • इसका endpoint https://www.youtube.com/youtubei/ के रूप में होता है
    • /youtubei/v1/player तब कॉल किया जाता है जब उपयोगकर्ता वीडियो पर क्लिक करता है, ताकि URL data और GVS stream URL मिल सके
  • GVS Google Video Services है, जो YouTube, Google Drive, और Google Photos के लिए वीडियो stream उपलब्ध कराता है
    • GVS से वीडियो stream करने के लिए InnerTube या Drive/Photos internal API से /videoplayback URL लेना पड़ता है
    • GVS URL signed होते हैं और आम तौर पर 6 घंटे की expiry होती है, इसलिए इन्हें सीधे बनाया नहीं जा सकता
    • ISP अपने infrastructure में Google Global Cache servers रख सकते हैं, ताकि YouTube traffic को ISP network के बाहर भेजे बिना ही serve किया जा सके
    • GGC सिर्फ public या कुछ unlisted YouTube वीडियो serve करता है, जबकि private YouTube वीडियो और Drive/Photos वीडियो हमेशा Google data center से serve होते हैं
  • YouTube web client पहले GVS URL के query parameters से जरूरी वीडियो range तय करके streaming करता था
  • बाद में YouTube ने SABR का उपयोग शुरू किया
    • SABR का अर्थ Server ABR है, यानी server-side adaptive bitrate के लिए YouTube का proprietary binary protocol
    • इसे MPEG-DASH जैसे public formats की तुलना में buffering से बेहतर बचने के लिए डिज़ाइन किया गया है
    • server, client को वीडियो/ऑडियो data भेजने के बजाय कुछ समय इंतज़ार करके फिर से कोशिश करने के लिए backoff भेज सकता है

backoff ad-block पहचान से अलग लागू होता है

  • नकली buffering तब होती है जब InnerTube पहले content /videoplayback अनुरोध के लिए ऐसा GVS stream देता है, जिसमें विज्ञापन की लंबाई के 80% के बराबर backoff शामिल होता है
    • इसका लक्ष्य ad stream नहीं, बल्कि content video stream होता है
    • विज्ञापन और content stream अब भी अलग-अलग रहते हैं
    • यह server-side ad insertion नहीं है, और YouTube के server-side ad insertion experiment अलग से चल रहे हैं
  • “Experiencing interruptions” dialog संभवतः GVS के लंबे backoff की वजह से trigger होता है
  • अगर उपयोगकर्ता A/B टेस्ट समूह में है, तो यह backoff इस बात से अलग हमेशा लागू होता है कि YouTube उसे ad-block उपयोगकर्ता मानता है या नहीं
    • अगर विज्ञापन ब्लॉक नहीं किए गए हों, तो web client विज्ञापन चलने के दौरान content video load करता है
    • उपयोगकर्ता को महसूस होने वाला फर्क सिर्फ इतना है कि content video buffering विज्ञापन के 80% चलने के बाद ही शुरू होती है
  • यह ऑनलाइन दावा सही नहीं है कि YouTube ad-block उपयोगकर्ताओं की CPU usage बहुत बढ़ाकर कंप्यूटर को नुकसान पहुँचा रहा है
    • backoff समाप्त होने का इंतज़ार करते समय YouTube CPU का उपयोग नहीं करता
    • मान लें कि इंतज़ार spinloop से लागू हो, तब भी 30 सेकंड से कम समय के लिए एक single core को पूरी तरह उपयोग करना CPU को नुकसान नहीं पहुँचाता

isInlinePlaybackNoAd से विज्ञापन परोसने से बचने का तरीका

  • backoff से बचने के लिए non-skippable विज्ञापन खत्म होने का इंतज़ार करने के बजाय यह सुनिश्चित करना होगा कि विज्ञापन शुरू से ही serve न किया जाए
  • अगर player request की playbackContext.contentPlaybackContext.isInlinePlaybackNoAd property को true सेट किया जाए, तो InnerTube विज्ञापन serve नहीं करता
    • जब विज्ञापन serve नहीं होता, तो GVS stream में backoff भी शामिल नहीं होता
  • जब web client server request के लिए JSON को string में बदलता है, तब "isInlinePlaybackNoAd":true जोड़ने वाला filter rule बनाया जा सकता है
www.youtube.com##+js(trusted-replace-outbound-text, JSON.stringify, 'contentPlaybackContext":{', 'contentPlaybackContext":{"isInlinePlaybackNoAd":true,', condition, 'contentPlaybackContext')
  • isInlinePlaybackNoAd property का reference frontend JavaScript में मौजूद है
  • req2proto का उपयोग करके /youtubei/v1/player कॉल में इस्तेमाल होने वाली protobuf definition निकाली जा सकती है और इस property को खोजा जा सकता है
    • YouTube web client, InnerTube से JSON में संवाद करता है, लेकिन यह JSON API Protocol Buffers definitions से generate होती है

सिर्फ warm navigation में स्थिरता की सीमा

  • यह तरीका सिर्फ warm navigation में काम करता है, यानी जब YouTube single-page app पहले से लोड हो और उसके भीतर क्लिक करके आगे बढ़ा जाए
  • watch page पर सीधे जाने वाली cold load स्थिति में YouTube backend, player response को ytInitialPlayerResponse के रूप में सीधे page में inject कर देता है
    • क्योंकि player request backend पर बनती है, इसलिए isInlinePlaybackNoAd सेट नहीं किया जा सकता
  • cold load को bypass करने का एक तरीका है शुरुआती data हटाकर ऐसा player request ज़बरदस्ती बनवाना जिसे नियंत्रित किया जा सके
www.youtube.com##+js(set, ytInitialData, undefined) ! bad idea, see below
www.youtube.com##+js(set, ytInitialPlayerResponse, undefined) ! bad idea!
  • इस approach के side effects काफी बड़े हैं, इसलिए इसे इस्तेमाल करना मुश्किल है
    • livestream पूरी तरह टूट जाती है
    • दूसरी untested features भी टूट सकती हैं
    • video player थोड़ी देर के लिए flicker करता है
    • page loading time धीमा हो जाता है

locker script और Chromium bypass

  • filter कुछ हद तक काम कर रहा था, लेकिन कभी-कभी uBlock Origin JSON.stringify को hook नहीं कर पा रहा था
  • कुछ A/B tests में YouTube frontend HTML के <head> टैग की शुरुआत में locker script जोड़ता है
    • यह script Object.defineProperty से fetch, JSON, JSON.stringify, JSON.parse, Array, Array.prototype.push, Array.prototype.forEach आदि को non-writable बना देती है
    • इसके बाद आने वाला code Proxy से इनके behavior को बदल नहीं सकता
  • uBlock Origin सिर्फ तब JSON.stringify को proxy कर सकता है जब वह locker script से पहले चल जाए
  • Firefox में HTML filter से page parse होने से पहले source HTML से उस script tag को हटाया जा सकता है
  • Chromium जरूरी extension API को support नहीं करता, इसलिए वही तरीका वहाँ इस्तेमाल नहीं किया जा सकता
  • मौजूदा bypass JSON.stringify की जगह Object.assign को hook करने का है
    • Object.assign भी fetch से पहले request body को process करने वाला function है
    • यह locker script को निष्क्रिय करने का तरीका नहीं, बल्कि एक तरह का workaround है
    • uBO scriptlet object key के text replacement की अनुमति नहीं देता, इसलिए filter list JavaScript inject करती है
(() => {
    const e = {
        apply: (e, n, arguments) => {
            let t = Reflect.apply(e, n, arguments);
            return 3 === arguments.length && t?.body && "string" == typeof t.body && !t.body.includes(`"isInlinePlaybackNoAd":true`) && (t.body = t.body.replace(`"contentPlaybackContext":{`, `"contentPlaybackContext":{"isInlinePlaybackNoAd":true,`)), t
        }
    };
    window.Object.assign = new Proxy(window.Object.assign, e)
})();
  • इस bypass कार्य में uAssets maintainers ने मदद की

संदर्भ सामग्री

अभी कोई टिप्पणी नहीं है.

अभी कोई टिप्पणी नहीं है.