use crate::{youtube::player_response::CommonFormat, Client};
use reqwest::Url;
use std::time::Duration;
#[derive(Clone)]
pub struct Stream {
pub(super) format: CommonFormat,
pub(super) client: Client,
}
impl Stream {
pub fn url(&self) -> Url {
self.format.url.clone()
}
pub async fn content_length(&self) -> crate::Result<u64> {
if let Some(content_length) = self.format.content_length {
Ok(content_length)
} else {
let res = self
.client
.api
.http
.head(self.url())
.send()
.await?
.error_for_status()?;
Ok(res
.content_length()
.expect("HEAD request did not have a content-length"))
}
}
pub async fn get(
&self,
) -> crate::Result<impl futures_core::Stream<Item = Result<bytes::Bytes, reqwest::Error>>> {
Ok(self
.client
.api
.http
.get(self.url())
.send()
.await?
.error_for_status()?
.bytes_stream())
}
pub fn mime_type(&self) -> &str {
&self.format.mime_type
}
pub fn bitrate(&self) -> u64 {
self.format.bitrate
}
pub fn duration(&self) -> Option<Duration> {
self.format.duration
}
pub(super) fn debug(&self, debug: &mut std::fmt::DebugStruct<'_, '_>) {
debug
.field("url", &self.url())
.field("mime_type", &self.mime_type())
.field("bitrate", &self.bitrate())
.field("duration", &self.duration());
}
}
impl std::fmt::Debug for Stream {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let mut debug = f.debug_struct("CommonStream");
self.debug(&mut debug);
debug.finish()
}
}