1mod audio;
20mod common;
21mod video;
22
23pub use self::audio::Stream as Audio;
24pub use self::common::Stream as Common;
25pub use self::video::Stream as Video;
26use crate::{youtube::player_response::FormatType, Client};
27
28pub(crate) async fn get(
29 client: Client,
30 id: crate::video::Id,
31) -> crate::Result<impl Iterator<Item = Stream>> {
32 let player_response = client.api.streams(id).await?;
33
34 Ok(player_response
36 .streaming_data
37 .adaptive_formats
38 .into_iter()
39 .map(move |stream| Stream::new(stream, client.clone())))
40}
41
42#[derive(Clone)]
44pub enum Stream {
45 Audio(Audio),
47 Video(Video),
49}
50
51impl Stream {
52 pub(crate) fn new(format: crate::youtube::player_response::Format, client: Client) -> Self {
53 match format.ty {
54 FormatType::Audio(audio) => Self::Audio(Audio {
55 common: Common {
56 format: format.base,
57 client,
58 },
59 audio,
60 }),
61 FormatType::Video(video) => Self::Video(Video {
62 common: Common {
63 format: format.base,
64 client,
65 },
66 video,
67 }),
68 }
69 }
70
71 pub fn is_audio(&self) -> bool {
73 matches!(self, Self::Audio(..))
74 }
75
76 pub fn is_video(&self) -> bool {
78 matches!(self, Self::Video(..))
79 }
80}
81
82impl std::ops::Deref for Stream {
83 type Target = Common;
84
85 fn deref(&self) -> &Self::Target {
86 match self {
87 Stream::Audio(audio) => &audio.common,
88 Stream::Video(video) => &video.common,
89 }
90 }
91}
92
93impl std::fmt::Debug for Stream {
94 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
95 let mut debug = f.debug_struct("Stream");
96
97 match self {
98 Stream::Audio(audio) => {
99 audio.common.debug(&mut debug);
100 audio.debug(&mut debug);
101 }
102 Stream::Video(video) => {
103 video.common.debug(&mut debug);
104 video.debug(&mut debug);
105 }
106 }
107 debug.finish()?;
108
109 Ok(())
110 }
111}