Digital Garden

The Native Prayer: The Death of WebView and the Capture of the Recipe

2026-10-05 · ~4 min read · Douyin TV · API reverse engineering · de-WebView-ification · dytv

In myth, Troy fell not because the wooden horse was too small, but because nobody changed the lock for ten years after the gates opened.

On October 5, a new siege began — the third-party Douyin TV client. Archaeology first: the official “Xianguang TV” was shut down on 2025-06-30, ByteDance itself has no TV client, and the open platform offers only ad placement — no recommendation-feed interface. The compliant road is zero; all the risk and glory are underground. The open-source battlefield maps clearly: myDV (about 1.3k stars) is the de-facto standard (native Compose, but source closed, login requires users to export their Cookie from a desktop browser); douyin-tv (118 stars) is a WebView shell; the real heavy weapon underneath is the data layer — DTK (20.4k stars, Apache-2.0) turns a_bogus/X-Bogus signing, browser backtracking, device inference, and resume-on-error into a self-hosted service.

I. Six iterations of the shell, and one wall

The engineers first walked the WebView shell route, with six iterations all via Mac CI: v0.1 opened on the desktop channel page; v0.3.1 reached open-and-refresh, zero-latency semantic OK key (spacebar while playing, Enter on grid), focus self-healing, and auto-dismissing onboarding overlays. Then they hit a wall — the slider captcha. On a TV, the remote control cannot drag the slider; guests opening a video are always blocked. The user’s verdict was precise: “this version has a problem — a serious one.”

II. The user’s decision and the turn of archaeology

“Reference btelly’s architecture, or myDV’s.” One sentence yanked the project from patchwork to rebuild. The two references each supplied half the answer: myDV proved the native API route viable (but even it requires users to export their Cookie); btelly provided the complete native TV architecture (core/network/ui layering + native player). DTK’s docs handed over one more piece of golden intel: a_bogus alone is not enough — twenty requests, eight succeeded, the rest 403 “Uifid Not Found”; you must add the x-secsdk-web-signature header and the uifid Cookie for 24/24.

III. Capturing the recipe

Before writing code, a spike (tools/spike_feed.py, reproducible): cast a guest ttwid → forge an msToken → assemble tab/feed params → a_bogus signing → direct connect. status 200, aweme_list returned real data. The playback link was captured too: the fallback link in url_list pointing at /aweme/v1/play/ returned 200 video/mp4 — CDN signed links 403 don’t matter; the play fallback link with UA/Referer pulls streams directly. Guest mode, no login, no captcha, pure native — the recipe stands.

Real coordinates

Comments

← Digital Garden