2 điểm bởi GN⁺ 2025-06-21 | Chưa có bình luận nào. | Chia sẻ qua WhatsApp
  • YouTube đang A/B test một cách thức tạo độ trễ trông như buffering giả trước khi video bắt đầu, thay vì hiển thị quảng cáo cho người dùng chặn quảng cáo
  • Độ trễ được triển khai bằng backoff của streaming SABR; InnerTube phản hồi yêu cầu /videoplayback nội dung đầu tiên rằng hãy chờ tương đương 80% thời lượng quảng cáo
  • Với người dùng không chặn quảng cáo, nội dung được tải trong lúc quảng cáo phát, nên dù có cùng backoff thì họ hầu như không cảm nhận được độ trễ
  • Nếu đặt isInlinePlaybackNoAd thành true, InnerTube sẽ không cung cấp quảng cáo, nên backoff của luồng GVS cũng biến mất; danh sách bộ lọc mặc định của uBlock Origin đã bao gồm cách обход liên quan
  • Trong một số thử nghiệm, YouTube dùng locker script để khóa các đối tượng toàn cục như JSON.stringify nhằm cản trở filter hook; trên Chromium, có thể обход bằng hook Object.assign

Điểm xuất hiện buffering giả

  • Trong vài tháng gần đây, YouTube đang A/B test các biện pháp chống chặn quảng cáo mới
  • Một trong các biện pháp quan sát được là buffering giả chỉ xuất hiện ở thời điểm bắt đầu video
    • Không xảy ra giữa video
    • Thời gian trễ bằng 80% thời lượng quảng cáo vốn sẽ được xem
    • Ngay cả khi dùng trình chặn quảng cáo, vẫn tiết kiệm thời gian hơn so với xem trọn quảng cáo
  • Ví dụ như sau
    • Nếu có quảng cáo 15 giây thì xảy ra backoff 12 giây
    • Nếu có cả quảng cáo 6 giây không thể bỏ qua và quảng cáo 15 giây, thì xảy ra backoff 16,8 giây

Vai trò của InnerTube, GVS và SABR

  • InnerTube là API nội bộ mà web client và ứng dụng di động của YouTube dùng để lấy thông tin video và dữ liệu chi tiết
    • Endpoint có dạng https://www.youtube.com/youtubei/
    • /youtubei/v1/player được gọi khi người dùng nhấp vào video để lấy dữ liệu URL và URL luồng GVS
  • GVS là Google Video Services, dịch vụ cung cấp luồng video cho YouTube, Google Drive và Google Photos
    • Để stream video từ GVS, cần nhận URL /videoplayback từ InnerTube hoặc API nội bộ của Drive/Photos
    • URL GVS được ký và thường có thời hạn hết hạn 6 giờ, nên không thể tự tạo trực tiếp
    • ISP có thể đặt máy chủ Google Global Cache trong hạ tầng của mình, nhờ đó phục vụ lưu lượng YouTube mà không đưa ra ngoài mạng ISP
    • GGC chỉ phục vụ các video YouTube công khai hoặc công khai một phần; video YouTube riêng tư và video Drive/Photos luôn được phục vụ từ trung tâm dữ liệu của Google
  • Web client YouTube trước đây stream bằng cách chỉ định phạm vi video cần thiết thông qua tham số truy vấn của URL GVS
  • Sau đó YouTube dùng SABR
    • SABR là Server ABR, tức giao thức nhị phân riêng của YouTube cho adaptive bitrate phía máy chủ
    • Được thiết kế để tránh buffering tốt hơn so với các định dạng mở như MPEG-DASH
    • Thay vì gửi dữ liệu video/âm thanh cho client, máy chủ có thể gửi backoff yêu cầu client chờ một khoảng thời gian rồi thử lại

backoff được áp dụng độc lập với phán đoán chặn quảng cáo

  • Buffering giả xảy ra khi InnerTube cung cấp luồng GVS có chứa backoff tương ứng 80% thời lượng quảng cáo trong yêu cầu /videoplayback nội dung đầu tiên
    • Đối tượng là luồng video nội dung, không phải luồng quảng cáo
    • Luồng quảng cáo và luồng nội dung vẫn tách biệt
    • Đây không phải chèn quảng cáo phía máy chủ; thử nghiệm chèn quảng cáo phía máy chủ của YouTube được tiến hành riêng
  • Hộp thoại “Experiencing interruptions” có khả năng được kích hoạt do backoff dài của GVS
  • Nếu nằm trong nhóm A/B test, backoff này luôn xảy ra bất kể YouTube có xác định người dùng là người chặn quảng cáo hay không
    • Nếu không chặn quảng cáo, web client tải video nội dung trong lúc phát quảng cáo
    • Khác biệt người dùng cảm nhận được là việc buffering video nội dung chỉ bắt đầu sau khi quảng cáo đã chạy được 80%
  • Các tuyên bố trên mạng rằng YouTube làm mức sử dụng CPU của người dùng chặn quảng cáo tăng vọt khiến máy tính hư hại là không đúng
    • YouTube không dùng CPU trong khi chờ backoff hết hạn
    • Ngay cả khi triển khai việc chờ bằng spinloop, việc dùng tối đa một nhân trong dưới 30 giây cũng không làm hỏng CPU

Cách tránh cung cấp quảng cáo bằng isInlinePlaybackNoAd

  • Để tránh backoff, thay vì chờ đến khi quảng cáo không thể bỏ qua kết thúc, cần khiến quảng cáo ngay từ đầu không được cung cấp
  • Nếu đặt thuộc tính playbackContext.contentPlaybackContext.isInlinePlaybackNoAd của yêu cầu player thành true, InnerTube sẽ không cung cấp quảng cáo
    • Nếu quảng cáo không được cung cấp, luồng GVS cũng không chứa backoff
  • Có thể tạo quy tắc bộ lọc thêm "isInlinePlaybackNoAd":true khi web client stringify JSON cho yêu cầu máy chủ
www.youtube.com##+js(trusted-replace-outbound-text, JSON.stringify, 'contentPlaybackContext":{', 'contentPlaybackContext":{"isInlinePlaybackNoAd":true,', condition, 'contentPlaybackContext')
  • Thuộc tính isInlinePlaybackNoAd được tham chiếu trong JavaScript frontend
  • Dùng req2proto có thể trích xuất định nghĩa protobuf dùng trong lệnh gọi /youtubei/v1/player và tìm thuộc tính đó
    • Web client YouTube giao tiếp với InnerTube bằng JSON, nhưng API JSON này được tạo từ định nghĩa Protocol Buffers

Giới hạn chỉ ổn định với warm navigation

  • Cách này chỉ hoạt động trong warm navigation, tức sau khi đã tải ứng dụng đơn trang YouTube rồi nhấp di chuyển bên trong
  • Với cold load, tức truy cập trực tiếp vào trang watch, backend YouTube chèn thẳng phản hồi player vào trang dưới dạng ytInitialPlayerResponse
    • Vì yêu cầu player được tạo ở backend, không thể đặt isInlinePlaybackNoAd
  • Một cách обход cold load là loại bỏ dữ liệu ban đầu để buộc tạo yêu cầu player có thể kiểm soát
www.youtube.com##+js(set, ytInitialData, undefined) ! bad idea, see below
www.youtube.com##+js(set, ytInitialPlayerResponse, undefined) ! bad idea!
  • Cách tiếp cận này có nhiều tác dụng phụ nên khó dùng
    • Làm hỏng hoàn toàn livestream
    • Các tính năng khác chưa được kiểm thử cũng có thể bị hỏng
    • Trình phát video nhấp nháy trong chốc lát
    • Thời gian tải trang chậm hơn

locker script và cách обход trên Chromium

  • Bộ lọc đã hoạt động ở mức nhất định, nhưng thỉnh thoảng uBlock Origin không hook được JSON.stringify
  • Trong một số A/B test, YouTube thêm locker script vào đầu thẻ <head> của HTML frontend
    • Script này dùng Object.defineProperty để biến fetch, JSON, JSON.stringify, JSON.parse, Array, Array.prototype.push, Array.prototype.forEach... thành non-writable
    • Sau đó ngăn mã thay đổi hành vi bằng Proxy
  • uBlock Origin chỉ có thể proxy JSON.stringify khi chạy trước locker script
  • Trên Firefox, có thể dùng HTML filter để xóa thẻ script đó khỏi HTML nguồn trước khi phân tích trang
  • Chromium không hỗ trợ API extension cần thiết nên không thể xử lý theo cùng cách
  • Cách обход hiện tại là hook Object.assign thay vì JSON.stringify
    • Object.assign cũng là hàm xử lý body yêu cầu trước khi fetch
    • Đây gần như là cách обход, không phải phương pháp vô hiệu hóa chính locker script
    • Vì uBO scriptlet không cho phép thay thế văn bản trong key của object, danh sách bộ lọc sẽ inject JavaScript
(() => {
    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)
})();
  • Các maintainer của uAssets đã hỗ trợ công việc обход này

Tài liệu tham khảo

Chưa có bình luận nào.

Chưa có bình luận nào.