Phase 4 (complete) — stream_extractor orchestrator
Wire the Android-primary fetch path + JSON-walking + URL post-processing
into a single stream_info(video_id) entry point. Mirrors NPE
YoutubeStreamExtractor.onFetchPage() per audit Track C §1.2.
src/youtube/stream_extractor.rs
* stream_info(video_id) + stream_info_with(video_id, options)
* fetch_android — reel endpoint (anonymous) OR /player (with po_token)
* check_playability_status — maps to ContentUnavailable variants
(AgeRestricted, GeoRestricted, Paid, Private, YoutubeMusicPremium,
AccountTerminated, Other)
* is_player_response_not_valid — decoy-video detection
* populate_video_details + populate_microformat + populate_streams +
populate_manifests + populate_captions
* process_url — sig deobf path (signatureCipher → JS function call)
+ unconditional nsig deobf + cpn append + pot append
* build_video_progressive / build_video_only / build_audio +
push_*_dedup helpers (FIX: NPE bug — dedup by itag id, not by
mediaFormat.id which collides 140/141)
Consolidated stream_helper's local ExtractionError into the crate-wide
exceptions::ExtractionError with a new DownloaderMissing variant.
Tests: 73 lib unit pass (+9 since Phase 3) + 7 new Phase 4 offline
integration tests = 80 lib green. Live YT end-to-end smoke deferred
to Straw integration; the code path is in place.
This commit is contained in:
parent
589e7446c3
commit
0d08f12b3b
5 changed files with 1014 additions and 11 deletions
|
|
@ -9,7 +9,7 @@
|
|||
use serde_json::{json, Map, Value};
|
||||
|
||||
use crate::downloader::request::Request;
|
||||
use crate::exceptions::{NetworkError, ParsingError};
|
||||
use crate::exceptions::{ExtractionError, NetworkError, ParsingError};
|
||||
use crate::localization::{ContentCountry, Localization};
|
||||
use crate::newpipe::NewPipe;
|
||||
use crate::youtube::client_request::{build_envelope, InnertubeClientRequestInfo};
|
||||
|
|
@ -226,16 +226,6 @@ fn post_youtube(
|
|||
Ok(parsed)
|
||||
}
|
||||
|
||||
#[derive(Debug, thiserror::Error)]
|
||||
pub enum ExtractionError {
|
||||
#[error("network: {0}")]
|
||||
Network(#[from] NetworkError),
|
||||
#[error("parsing: {0}")]
|
||||
Parsing(#[from] ParsingError),
|
||||
#[error("downloader not initialized")]
|
||||
DownloaderMissing,
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue