archivebate: app clients get resolved media URLs with headers, resolved concurrently
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MUYdCh2nCVsQYgJAT7gwSi
This commit is contained in:
@@ -815,6 +815,53 @@ impl ArchivebateProvider {
|
||||
item
|
||||
}
|
||||
|
||||
/// For Hot Tub app clients: resolve every item's real media URL at the same
|
||||
/// time (one task per item, no concurrency cap) and hand the app that URL
|
||||
/// with the headers the CDN is played with, instead of the lazy
|
||||
/// `/proxy/archivebate` redirect. Items that fail or time out keep the
|
||||
/// proxied format, which re-resolves at playback time.
|
||||
async fn resolve_direct_formats(
|
||||
videos: Vec<VideoItem>,
|
||||
options: &ServerOptions,
|
||||
) -> Vec<VideoItem> {
|
||||
let tasks: Vec<_> = videos
|
||||
.iter()
|
||||
.map(|video| {
|
||||
let detail_url = video.url.clone();
|
||||
let mut requester =
|
||||
requester_or_default(options, CHANNEL_ID, "archivebate.resolve_direct");
|
||||
tokio::spawn(async move {
|
||||
timeout(
|
||||
StdDuration::from_secs(25),
|
||||
crate::proxies::archivebate::resolve_media(&mut requester, &detail_url),
|
||||
)
|
||||
.await
|
||||
.ok()
|
||||
.flatten()
|
||||
})
|
||||
})
|
||||
.collect();
|
||||
|
||||
let resolved = futures::future::join_all(tasks).await;
|
||||
videos
|
||||
.into_iter()
|
||||
.zip(resolved)
|
||||
.map(|(mut video, resolved)| match resolved.ok().flatten() {
|
||||
Some(media) => {
|
||||
video.formats = Some(vec![Self::video_format_with_headers(
|
||||
VideoFormat::new(media.media_url, "source".to_string(), "mp4".to_string()),
|
||||
vec![
|
||||
("Referer".to_string(), media.embed_url),
|
||||
("User-Agent".to_string(), FIREFOX_UA.to_string()),
|
||||
],
|
||||
)]);
|
||||
video
|
||||
}
|
||||
None => Self::with_default_format(video, options),
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
async fn enrich_video(&self, item: VideoItem, options: &ServerOptions) -> VideoItem {
|
||||
let page_url = item.url.clone();
|
||||
let format_url = Self::proxied_video(options, &page_url);
|
||||
@@ -1208,6 +1255,14 @@ impl Provider for ArchivebateProvider {
|
||||
if videos.is_empty() {
|
||||
return videos;
|
||||
}
|
||||
let is_app_client = options
|
||||
.client_version
|
||||
.as_ref()
|
||||
.map(ClientVersion::is_verified_hottub)
|
||||
.unwrap_or(false);
|
||||
if is_app_client {
|
||||
return Self::resolve_direct_formats(videos, &options).await;
|
||||
}
|
||||
stream::iter(videos.into_iter().map(|video| {
|
||||
let provider = self.clone();
|
||||
let options = options.clone();
|
||||
|
||||
Reference in New Issue
Block a user