13 KiB
WCO feasibility investigation
Observed 2026-10-20 UTC. Scope: adding Western-cartoon browsing and native playback to Tubular, using ordinary HTTPS without browser automation, challenge/login/premium bypass, fabricated ad-verification results, or weakened TLS. No production implementation was added.
Decision
Browsing is feasible for the sampled catalog. Native video extraction and playback are not established. The current declared free-player route reaches a JavaScript ad-verification step; investigation stopped before submitting that verification or requesting the post-gate player. Separately, the current Tubular/Terebi source and progress contracts reject an honest WCO identity.
Do not build another full browser UI or weaken Terebi's network policy on this evidence alone. The missing prerequisite is a legitimately obtained final media URL, its required headers, and a successful native decode/seek probe. Nothing below demonstrates that WCO cannot ever support a native client.
Evidence labels:
- Observed: live requests or an executed check in this investigation.
- Source: current site markup, JavaScript, or implementation inspection.
- [INFERENCE]: architectural implication, not verified WCO playback.
Live native HTTP evidence
A temporary Rust example used the project's existing ureq 3.4.2 dependency with its rustls feature: default agent, TLS verification enabled, 25-second global timeout, http_status_as_error(false), and zero automatic redirects. Responses were bounded to 512 KiB, or 4 KiB for the artwork signature check. No cookies, browser impersonation, proxy, script execution, or challenge solution was supplied. Player/initialization requests carried their referring page explicitly.
| Resource | Transport | HTTP | Content-Type | Body bytes read |
|---|---|---|---|---|
| Cartoon directory | ureq/rustls | 200 | text/html | 311285 |
| OTGW series | ureq/rustls | 200 | text/html | 42840 |
| Adventure Time series | ureq/rustls | 200 | text/html | 148050 |
| OTGW episode 1 | ureq/rustls | 200 | text/html | 39154 |
Episode's declared iframe, embed.wcostream.com/inc/embed/index.php |
ureq/rustls | 200 | text/html | 9177 |
| Declared player initialization | ureq/rustls | 200 | application/javascript | 3871 |
| OTGW cover | ureq/rustls | 200 | image/jpeg | 4096 |
| Same OTGW episode-1 URL | Python urllib | 403 | text/html | 5601 |
| Same OTGW episode-1 URL | curl | 403 | text/html | 5580 |
Observed: the cover prefix has a JPEG signature. Full image decoding was not tested. Native successful page responses contained neither the Cloudflare challenge markers checked nor the explicit premium-only marker. Python's episode response contained Cloudflare's “Just a moment”; curl independently returned 403 HTML. Accessibility is transport-dependent; successful web-reader access alone would not have established local native access.
Smallest catalog integration
Observed/Source: the directory and series metadata are server-rendered. No JavaScript execution is needed to read the sampled listings.
GET /cartoon-list; parse#ddmcc_containertitle/series links.- Filter that Western-cartoon directory locally. The site's own directory search performs case-insensitive substring filtering, not another API request.
- Fetch the selected series page for description, genres, cover reference, season labels, and
#episodeList a.dark-episode-itementries. - Preserve the provider's actual playable-item labels and opaque page paths.
The global search form declares POST /search, with catara=<query> and konuara=series or episodes; the input declares a 40-character maximum. This is a markup contract, not a successful live POST probe. Local directory filtering avoids depending on that unverified endpoint for Western-cartoon title search. Site form; reference search implementation.
Series identity should use the observed canonical provider path, not a slug generated from the display title or the numeric artwork filename. The directory contains historical paths such as /anime/american-dad-season-1 for “American Dad!”. Long-term URL stability has not been established. Directory.
Artwork is available through og:image and #sidebar_cat img.img5; normalize scheme-relative references. Sidebar prose and genre links are available, but quality varies: Adventure Time's synopsis describes its pilot rather than the whole series. No episode runtime, publication date, or chapter timestamps were established.
Identity and ordering traps
- OTGW has eight page entries covering ten numbered segments: 1–6 separately, 7–8 together, 9–10 together. These eight links were also extracted from the native response.
- Adventure Time season 1 labels one video “Episode 1 Slumber Party Panic / Trouble in Lumpy Space”; season 10 has a combined “Episode 13–16 Come Along with Me”. Pilot, specials, Distant Lands and Side Quests coexist on the series page.
- Map
data-seasonthrough#seasonFilter option[value]; preserve the token and label. Adventure Time includess-1-0, labeled “Special: Distant Lands”. - Read the direct title span, not all anchor text: quality/finale badges are separate metadata.
- Preserve source order initially. It is mostly descending, but not consistently numerically sorted.
- Use an opaque episode-page identity, not series ID plus an assumed single positive episode number. Do not synthesize chapters, segment boundaries, or separate watched states from slash-separated titles.
Sources: OTGW, Adventure Time. The current Miruro identity cannot be reused unchanged: src/miruro.rs:28-77.
Actual page-to-player boundary
Observed: ordinary native requests reached this sequence:
- The episode HTML contains a statically encoded iframe string. Its visible script applies Base64 decoding, retains decimal digits, subtracts a page-supplied constant, then constructs characters. This transform was decoded as data; no downloaded JavaScript was executed.
- The decoded iframe targets
embed.wcostream.com/inc/embed/index.phpwith episode query parameters. - That iframe returns an “Announcement” document, not an MP4/HLS URL. Its close button is initially disabled, with a 10-second countdown and a 12-second fallback timer.
- The document loads
/inc/embed/pre-init.js?v2. That script generates a browser nonce, performs DOM ad-bait and script-loading checks, and sends an/ad-verifybeacon containing the nonce, video ID andclear/blockedresult. - Closing the announcement normally navigates to
video-js.php, usingAdGate.buildUrl()to append the nonce. The page also has a fallback navigation ifAdGateis unavailable; that fallback was not requested to skip verification.
Boundary: no /ad-verify request was submitted; no DOM results were fabricated, scripts executed, announcement flow skipped, alternative player endpoint substituted, premium workaround invoked, or post-gate player/media requested. Server-side enforcement of the nonce was not tested. A script containing a gate is not proof that every WCO stream is inaccessible to a native client.
The Kodi resolver is reference code, not a proven current contract. It rewrites index.php to video-js-new.php, parses internal source JSON, resolves media redirects, and contains separate premium-workaround paths. Those behaviors were not transplanted or exercised. Its recent maintenance does not establish that this sample is playable through Tubular's permitted flow.
Unverified: current source-JSON schema after the gate; final media type/codecs; required headers/cookies; redirect chain; URL expiration/IP binding; byte-range/seek support; nested HLS origins; subtitles; actual Terebi playback. No episode media was downloaded.
Actual Tubular/Terebi compatibility
Executed source-contract smoke
A temporary Foundation-only Swift executable compiled the actual ../terebi/Sources/App/ResolvedSource.swift unchanged. It validated a synthetic, otherwise valid source document with provider miruro, then changed only the provider to wco and required rejection. The synthetic example URL was not fetched.
Observed output, exit 0:
Actual Terebi validator: Miruro control accepted; identical document with provider=wco rejected
This proves source-contract rejection, not anything about live media decoding. No player UI was launched.
Required integration changes if usable media is established
- Provider selection: Tubular's chooser is Boolean/two-way, not a third-provider interface:
src/main.rs:3674-3698,3762-3774. - Honest stable identity: Tubular's
Identityvalidation/key parsing and Terebi's source validator hardcode Miruro. WCO needs a provider-correct opaque playback-item identity that accommodates paired episodes and specials. Do not disguise WCO media as Miruro.src/miruro.rs:28-77;../terebi/Sources/App/ResolvedSource.swift:84-102. - Native admission and safety: native progress identity validation accepts only canonical YouTube URLs or
miruro:. Resolved-source security classification also usesstarts_with("miruro:"). Updating Swift admission alone is insufficient and would not apply the protected resolved-source path.../terebi/Sources/Core/progress_reporter.cpp:62-90;../terebi/Sources/Core/player.cpp:565-567,1460-1466. - Progress/state: native version-2 reporting emits a literal Miruro provider. Tubular sessions, snapshot validation, report admission and provider-specific collection filtering also need coordinated changes. Broadening the Miruro identity parser without updating its UI callers would mix WCO records into Miruro collections.
../terebi/Sources/Core/progress_reporter.cpp:163-186;src/video_state.rs:379-396,651-669;src/miruro_ui.rs:265-268,989-990,1938-1941. - Reuse, not another player: the existing source launcher already passes private source/progress files to Terebi. Resume storage is identity-keyed. No new playback framework is indicated.
src/youtube.rs:937-981;../terebi/Sources/App/TerebiApp.swift:516-524,1525-1530;../terebi/Sources/App/PlaybackProgress.swift:24-35,54-57.
[INFERENCE] Direct MP4 should fit the general native media architecture. Source-file validation is not HLS-only; native FFmpeg opens input without forcing a demuxer and discovers audio/video streams. The HLS-only rule belongs to Miruro's Sun projection, not the general source document. WCO must not be routed through that projection. src/miruro.rs:101-178; ../terebi/Sources/Core/player.cpp:543-547,565-580.
The existing protected network path rejects all media redirects, even same-origin redirects, and requires HLS variants/segments/keys/init resources to share the initial media origin. Preserve that policy. A resolver would need to obtain an already-final acceptable URL through a separately reviewed extraction flow; no need for redirect/cross-origin support has yet been established. ../terebi/Sources/Core/player.cpp:111-126,532-537.
The existing resolved-playback-check is not an unchanged subtitle-free WCO smoke: it requires a default subtitle and two cues. The full player suite also requires graphical/audio resources. Neither was run. See ../terebi/Checks/resolved-playback.swift:24-80 and ../terebi/README.md:178-190.
Recommendation and limits
- Go: a native WCO catalog is evidenced for the sampled directory, two shows, episode page and cover host.
- Not yet go: do not implement end-to-end WCO playback on the strength of catalog access or old extractor code.
- Next prerequisite: observe/document an authorized normal free-player route through the verification boundary, or obtain a supported native playback interface. Browser observation would need explicit permission and would not itself prove native extraction. Do not emulate successful ad-verification results or weaken security to create a passing demo.
- Then: resolve one real item, inspect only bounded media/manifest data with explicit headers, and verify native decode, duration and seek behavior before implementing browsing/state changes. Test a combined entry as well as a single episode before claiming identity correctness.
Investigation changes are this report only; temporary HTTP/Swift probes and response files were removed. No application behavior, player source, dependency, remote state, or persistent stream token was changed. Findings are a point-in-time sample, not a service reliability or distribution-rights guarantee.