From be0306e234d6f56135b952bcaaa023a4501494f5 Mon Sep 17 00:00:00 2001 From: ThetaDev Date: Thu, 3 Nov 2022 10:06:49 +0100 Subject: [PATCH] feat: add audio track volume/channel count, stream duration --- src/client/player.rs | 4 +++ src/client/response/player.rs | 4 +++ src/client/response/video_item.rs | 1 + ...layer__tests__map_player_data_android.snap | 26 +++++++++++++++++ ...layer__tests__map_player_data_desktop.snap | 28 +++++++++++++++++++ ...__tests__map_player_data_desktopmusic.snap | 22 +++++++++++++++ ...t__player__tests__map_player_data_ios.snap | 8 ++++++ ...__tests__map_player_data_tvhtml5embed.snap | 28 +++++++++++++++++++ src/model/mod.rs | 10 +++++++ 9 files changed, 131 insertions(+) diff --git a/src/client/player.rs b/src/client/player.rs index 674efea..88f3d90 100644 --- a/src/client/player.rs +++ b/src/client/player.rs @@ -421,6 +421,7 @@ fn map_video_stream( size: f.content_length, index_range: f.index_range, init_range: f.init_range, + duration_ms: f.approx_duration_ms, // Note that the format has already been verified using // is_video(), so these unwraps are safe width: f.width.unwrap(), @@ -478,6 +479,7 @@ fn map_audio_stream( size: f.content_length.unwrap(), index_range: f.index_range, init_range: f.init_range, + duration_ms: f.approx_duration_ms, mime: f.mime_type.to_owned(), format: some_or_bail!( get_audio_format(mtype), @@ -487,6 +489,8 @@ fn map_audio_stream( } ), codec: get_audio_codec(codecs), + channels: f.audio_channels, + loudness_db: f.loudness_db, throttled, track: match f.audio_track { Some(t) => { diff --git a/src/client/response/player.rs b/src/client/response/player.rs index 4c2e31b..1dbb8af 100644 --- a/src/client/response/player.rs +++ b/src/client/response/player.rs @@ -72,6 +72,8 @@ pub(crate) struct Format { pub width: Option, pub height: Option, + #[serde_as(as = "Option")] + pub approx_duration_ms: Option, #[serde_as(as = "Option")] pub index_range: Option>, @@ -95,6 +97,8 @@ pub(crate) struct Format { pub audio_quality: Option, #[serde_as(as = "Option")] pub audio_sample_rate: Option, + pub audio_channels: Option, + pub loudness_db: Option, pub audio_track: Option, pub signature_cipher: Option, diff --git a/src/client/response/video_item.rs b/src/client/response/video_item.rs index f4d2bfa..5546676 100644 --- a/src/client/response/video_item.rs +++ b/src/client/response/video_item.rs @@ -133,6 +133,7 @@ pub(crate) struct ReelItemRenderer { /// Dashes may be `\u2013` (emdash) #[serde_as(as = "Option")] pub accessibility: Option, + #[serde(default)] #[serde_as(as = "DefaultOnError")] pub navigation_endpoint: Option, } diff --git a/src/client/snapshots/rustypipe__client__player__tests__map_player_data_android.snap b/src/client/snapshots/rustypipe__client__player__tests__map_player_data_android.snap index 0a578f7..881ddbd 100644 --- a/src/client/snapshots/rustypipe__client__player__tests__map_player_data_android.snap +++ b/src/client/snapshots/rustypipe__client__player__tests__map_player_data_android.snap @@ -70,6 +70,7 @@ VideoPlayer( size: Some(1619781), index_range: None, init_range: None, + duration_ms: Some(163143), width: 176, height: 144, fps: 7, @@ -88,6 +89,7 @@ VideoPlayer( size: Some(11439331), index_range: None, init_range: None, + duration_ms: Some(163096), width: 640, height: 360, fps: 30, @@ -114,6 +116,7 @@ VideoPlayer( start: 0, end: 699, )), + duration_ms: Some(163029), width: 256, height: 144, fps: 30, @@ -138,6 +141,7 @@ VideoPlayer( start: 0, end: 699, )), + duration_ms: Some(163029), width: 426, height: 240, fps: 30, @@ -162,6 +166,7 @@ VideoPlayer( start: 0, end: 739, )), + duration_ms: Some(163029), width: 640, height: 360, fps: 30, @@ -186,6 +191,7 @@ VideoPlayer( start: 0, end: 699, )), + duration_ms: Some(163029), width: 640, height: 360, fps: 30, @@ -210,6 +216,7 @@ VideoPlayer( start: 0, end: 699, )), + duration_ms: Some(163029), width: 854, height: 480, fps: 30, @@ -228,6 +235,7 @@ VideoPlayer( size: None, index_range: None, init_range: None, + duration_ms: Some(163096), width: 1280, height: 720, fps: 30, @@ -252,6 +260,7 @@ VideoPlayer( start: 0, end: 699, )), + duration_ms: Some(163046), width: 1280, height: 720, fps: 60, @@ -276,6 +285,7 @@ VideoPlayer( start: 0, end: 739, )), + duration_ms: Some(163046), width: 1920, height: 1080, fps: 60, @@ -300,6 +310,7 @@ VideoPlayer( start: 0, end: 699, )), + duration_ms: Some(163046), width: 1920, height: 1080, fps: 60, @@ -326,9 +337,12 @@ VideoPlayer( start: 0, end: 640, )), + duration_ms: Some(163189), mime: "audio/mp4; codecs=\"mp4a.40.5\"", format: m4a, codec: mp4a, + channels: Some(2), + loudness_db: None, throttled: false, track: None, ), @@ -346,9 +360,12 @@ VideoPlayer( start: 0, end: 265, )), + duration_ms: Some(163061), mime: "audio/webm; codecs=\"opus\"", format: webm, codec: opus, + channels: Some(2), + loudness_db: None, throttled: false, track: None, ), @@ -366,9 +383,12 @@ VideoPlayer( start: 0, end: 265, )), + duration_ms: Some(163061), mime: "audio/webm; codecs=\"opus\"", format: webm, codec: opus, + channels: Some(2), + loudness_db: None, throttled: false, track: None, ), @@ -386,9 +406,12 @@ VideoPlayer( start: 0, end: 631, )), + duration_ms: Some(163096), mime: "audio/mp4; codecs=\"mp4a.40.2\"", format: m4a, codec: mp4a, + channels: Some(2), + loudness_db: None, throttled: false, track: None, ), @@ -406,9 +429,12 @@ VideoPlayer( start: 0, end: 265, )), + duration_ms: Some(163061), mime: "audio/webm; codecs=\"opus\"", format: webm, codec: opus, + channels: Some(2), + loudness_db: None, throttled: false, track: None, ), diff --git a/src/client/snapshots/rustypipe__client__player__tests__map_player_data_desktop.snap b/src/client/snapshots/rustypipe__client__player__tests__map_player_data_desktop.snap index 2a06529..ce972b5 100644 --- a/src/client/snapshots/rustypipe__client__player__tests__map_player_data_desktop.snap +++ b/src/client/snapshots/rustypipe__client__player__tests__map_player_data_desktop.snap @@ -75,6 +75,7 @@ VideoPlayer( size: Some(11439331), index_range: None, init_range: None, + duration_ms: Some(163096), width: 640, height: 360, fps: 30, @@ -101,6 +102,7 @@ VideoPlayer( start: 0, end: 217, )), + duration_ms: Some(163029), width: 256, height: 144, fps: 30, @@ -125,6 +127,7 @@ VideoPlayer( start: 0, end: 699, )), + duration_ms: Some(163029), width: 256, height: 144, fps: 30, @@ -149,6 +152,7 @@ VideoPlayer( start: 0, end: 218, )), + duration_ms: Some(163029), width: 426, height: 240, fps: 30, @@ -173,6 +177,7 @@ VideoPlayer( start: 0, end: 699, )), + duration_ms: Some(163029), width: 426, height: 240, fps: 30, @@ -197,6 +202,7 @@ VideoPlayer( start: 0, end: 739, )), + duration_ms: Some(163029), width: 640, height: 360, fps: 30, @@ -221,6 +227,7 @@ VideoPlayer( start: 0, end: 219, )), + duration_ms: Some(163029), width: 640, height: 360, fps: 30, @@ -245,6 +252,7 @@ VideoPlayer( start: 0, end: 699, )), + duration_ms: Some(163029), width: 640, height: 360, fps: 30, @@ -269,6 +277,7 @@ VideoPlayer( start: 0, end: 219, )), + duration_ms: Some(163029), width: 854, height: 480, fps: 30, @@ -293,6 +302,7 @@ VideoPlayer( start: 0, end: 699, )), + duration_ms: Some(163029), width: 854, height: 480, fps: 30, @@ -317,6 +327,7 @@ VideoPlayer( start: 0, end: 219, )), + duration_ms: Some(163029), width: 1280, height: 720, fps: 30, @@ -341,6 +352,7 @@ VideoPlayer( start: 0, end: 218, )), + duration_ms: Some(163046), width: 1280, height: 720, fps: 60, @@ -365,6 +377,7 @@ VideoPlayer( start: 0, end: 699, )), + duration_ms: Some(163046), width: 1280, height: 720, fps: 60, @@ -389,6 +402,7 @@ VideoPlayer( start: 0, end: 739, )), + duration_ms: Some(163046), width: 1920, height: 1080, fps: 60, @@ -413,6 +427,7 @@ VideoPlayer( start: 0, end: 218, )), + duration_ms: Some(163046), width: 1920, height: 1080, fps: 60, @@ -437,6 +452,7 @@ VideoPlayer( start: 0, end: 699, )), + duration_ms: Some(163046), width: 1920, height: 1080, fps: 60, @@ -463,9 +479,12 @@ VideoPlayer( start: 0, end: 265, )), + duration_ms: Some(163061), mime: "audio/webm; codecs=\"opus\"", format: webm, codec: opus, + channels: Some(2), + loudness_db: Some(5.2200003), throttled: false, track: None, ), @@ -483,9 +502,12 @@ VideoPlayer( start: 0, end: 265, )), + duration_ms: Some(163061), mime: "audio/webm; codecs=\"opus\"", format: webm, codec: opus, + channels: Some(2), + loudness_db: Some(5.2200003), throttled: false, track: None, ), @@ -503,9 +525,12 @@ VideoPlayer( start: 0, end: 631, )), + duration_ms: Some(163096), mime: "audio/mp4; codecs=\"mp4a.40.2\"", format: m4a, codec: mp4a, + channels: Some(2), + loudness_db: Some(5.2159004), throttled: false, track: None, ), @@ -523,9 +548,12 @@ VideoPlayer( start: 0, end: 265, )), + duration_ms: Some(163061), mime: "audio/webm; codecs=\"opus\"", format: webm, codec: opus, + channels: Some(2), + loudness_db: Some(5.2200003), throttled: false, track: None, ), diff --git a/src/client/snapshots/rustypipe__client__player__tests__map_player_data_desktopmusic.snap b/src/client/snapshots/rustypipe__client__player__tests__map_player_data_desktopmusic.snap index d0bbd69..bbe110a 100644 --- a/src/client/snapshots/rustypipe__client__player__tests__map_player_data_desktopmusic.snap +++ b/src/client/snapshots/rustypipe__client__player__tests__map_player_data_desktopmusic.snap @@ -43,6 +43,7 @@ VideoPlayer( size: Some(11439331), index_range: None, init_range: None, + duration_ms: Some(163096), width: 640, height: 360, fps: 30, @@ -69,6 +70,7 @@ VideoPlayer( start: 0, end: 217, )), + duration_ms: Some(163029), width: 256, height: 144, fps: 30, @@ -93,6 +95,7 @@ VideoPlayer( start: 0, end: 218, )), + duration_ms: Some(163029), width: 426, height: 240, fps: 30, @@ -117,6 +120,7 @@ VideoPlayer( start: 0, end: 739, )), + duration_ms: Some(163029), width: 640, height: 360, fps: 30, @@ -141,6 +145,7 @@ VideoPlayer( start: 0, end: 219, )), + duration_ms: Some(163029), width: 640, height: 360, fps: 30, @@ -165,6 +170,7 @@ VideoPlayer( start: 0, end: 219, )), + duration_ms: Some(163029), width: 854, height: 480, fps: 30, @@ -189,6 +195,7 @@ VideoPlayer( start: 0, end: 219, )), + duration_ms: Some(163029), width: 1280, height: 720, fps: 30, @@ -213,6 +220,7 @@ VideoPlayer( start: 0, end: 218, )), + duration_ms: Some(163046), width: 1280, height: 720, fps: 60, @@ -237,6 +245,7 @@ VideoPlayer( start: 0, end: 739, )), + duration_ms: Some(163046), width: 1920, height: 1080, fps: 60, @@ -261,6 +270,7 @@ VideoPlayer( start: 0, end: 218, )), + duration_ms: Some(163046), width: 1920, height: 1080, fps: 60, @@ -287,9 +297,12 @@ VideoPlayer( start: 0, end: 265, )), + duration_ms: Some(163061), mime: "audio/webm; codecs=\"opus\"", format: webm, codec: opus, + channels: Some(2), + loudness_db: Some(0.0006532669), throttled: false, track: None, ), @@ -307,9 +320,12 @@ VideoPlayer( start: 0, end: 265, )), + duration_ms: Some(163061), mime: "audio/webm; codecs=\"opus\"", format: webm, codec: opus, + channels: Some(2), + loudness_db: Some(0.0006532669), throttled: false, track: None, ), @@ -327,9 +343,12 @@ VideoPlayer( start: 0, end: 631, )), + duration_ms: Some(163096), mime: "audio/mp4; codecs=\"mp4a.40.2\"", format: m4a, codec: mp4a, + channels: Some(2), + loudness_db: Some(-0.003446579), throttled: false, track: None, ), @@ -347,9 +366,12 @@ VideoPlayer( start: 0, end: 265, )), + duration_ms: Some(163061), mime: "audio/webm; codecs=\"opus\"", format: webm, codec: opus, + channels: Some(2), + loudness_db: Some(0.0006532669), throttled: false, track: None, ), diff --git a/src/client/snapshots/rustypipe__client__player__tests__map_player_data_ios.snap b/src/client/snapshots/rustypipe__client__player__tests__map_player_data_ios.snap index 287bb21..2336758 100644 --- a/src/client/snapshots/rustypipe__client__player__tests__map_player_data_ios.snap +++ b/src/client/snapshots/rustypipe__client__player__tests__map_player_data_ios.snap @@ -72,6 +72,7 @@ VideoPlayer( start: 0, end: 739, )), + duration_ms: Some(163029), width: 640, height: 360, fps: 30, @@ -96,6 +97,7 @@ VideoPlayer( start: 0, end: 739, )), + duration_ms: Some(163046), width: 1920, height: 1080, fps: 60, @@ -122,9 +124,12 @@ VideoPlayer( start: 0, end: 640, )), + duration_ms: Some(163189), mime: "audio/mp4; codecs=\"mp4a.40.5\"", format: m4a, codec: mp4a, + channels: Some(2), + loudness_db: Some(5.2159004), throttled: false, track: None, ), @@ -142,9 +147,12 @@ VideoPlayer( start: 0, end: 631, )), + duration_ms: Some(163096), mime: "audio/mp4; codecs=\"mp4a.40.2\"", format: m4a, codec: mp4a, + channels: Some(2), + loudness_db: Some(5.2159004), throttled: false, track: None, ), diff --git a/src/client/snapshots/rustypipe__client__player__tests__map_player_data_tvhtml5embed.snap b/src/client/snapshots/rustypipe__client__player__tests__map_player_data_tvhtml5embed.snap index dcffdf7..f55226c 100644 --- a/src/client/snapshots/rustypipe__client__player__tests__map_player_data_tvhtml5embed.snap +++ b/src/client/snapshots/rustypipe__client__player__tests__map_player_data_tvhtml5embed.snap @@ -75,6 +75,7 @@ VideoPlayer( size: Some(11439331), index_range: None, init_range: None, + duration_ms: Some(163096), width: 640, height: 360, fps: 30, @@ -101,6 +102,7 @@ VideoPlayer( start: 0, end: 217, )), + duration_ms: Some(163029), width: 256, height: 144, fps: 30, @@ -125,6 +127,7 @@ VideoPlayer( start: 0, end: 699, )), + duration_ms: Some(163029), width: 256, height: 144, fps: 30, @@ -149,6 +152,7 @@ VideoPlayer( start: 0, end: 218, )), + duration_ms: Some(163029), width: 426, height: 240, fps: 30, @@ -173,6 +177,7 @@ VideoPlayer( start: 0, end: 699, )), + duration_ms: Some(163029), width: 426, height: 240, fps: 30, @@ -197,6 +202,7 @@ VideoPlayer( start: 0, end: 739, )), + duration_ms: Some(163029), width: 640, height: 360, fps: 30, @@ -221,6 +227,7 @@ VideoPlayer( start: 0, end: 219, )), + duration_ms: Some(163029), width: 640, height: 360, fps: 30, @@ -245,6 +252,7 @@ VideoPlayer( start: 0, end: 699, )), + duration_ms: Some(163029), width: 640, height: 360, fps: 30, @@ -269,6 +277,7 @@ VideoPlayer( start: 0, end: 219, )), + duration_ms: Some(163029), width: 854, height: 480, fps: 30, @@ -293,6 +302,7 @@ VideoPlayer( start: 0, end: 699, )), + duration_ms: Some(163029), width: 854, height: 480, fps: 30, @@ -317,6 +327,7 @@ VideoPlayer( start: 0, end: 219, )), + duration_ms: Some(163029), width: 1280, height: 720, fps: 30, @@ -341,6 +352,7 @@ VideoPlayer( start: 0, end: 218, )), + duration_ms: Some(163046), width: 1280, height: 720, fps: 60, @@ -365,6 +377,7 @@ VideoPlayer( start: 0, end: 699, )), + duration_ms: Some(163046), width: 1280, height: 720, fps: 60, @@ -389,6 +402,7 @@ VideoPlayer( start: 0, end: 739, )), + duration_ms: Some(163046), width: 1920, height: 1080, fps: 60, @@ -413,6 +427,7 @@ VideoPlayer( start: 0, end: 218, )), + duration_ms: Some(163046), width: 1920, height: 1080, fps: 60, @@ -437,6 +452,7 @@ VideoPlayer( start: 0, end: 699, )), + duration_ms: Some(163046), width: 1920, height: 1080, fps: 60, @@ -463,9 +479,12 @@ VideoPlayer( start: 0, end: 265, )), + duration_ms: Some(163061), mime: "audio/webm; codecs=\"opus\"", format: webm, codec: opus, + channels: Some(2), + loudness_db: Some(5.2200003), throttled: false, track: None, ), @@ -483,9 +502,12 @@ VideoPlayer( start: 0, end: 265, )), + duration_ms: Some(163061), mime: "audio/webm; codecs=\"opus\"", format: webm, codec: opus, + channels: Some(2), + loudness_db: Some(5.2200003), throttled: false, track: None, ), @@ -503,9 +525,12 @@ VideoPlayer( start: 0, end: 631, )), + duration_ms: Some(163096), mime: "audio/mp4; codecs=\"mp4a.40.2\"", format: m4a, codec: mp4a, + channels: Some(2), + loudness_db: Some(5.2159004), throttled: false, track: None, ), @@ -523,9 +548,12 @@ VideoPlayer( start: 0, end: 265, )), + duration_ms: Some(163061), mime: "audio/webm; codecs=\"opus\"", format: webm, codec: opus, + channels: Some(2), + loudness_db: Some(5.2200003), throttled: false, track: None, ), diff --git a/src/model/mod.rs b/src/model/mod.rs index b57e069..085e955 100644 --- a/src/model/mod.rs +++ b/src/model/mod.rs @@ -167,6 +167,8 @@ pub struct VideoStream { pub size: Option, pub index_range: Option>, pub init_range: Option>, + // Video duration in milliseconds + pub duration_ms: Option, /// Video width in pixels pub width: u32, /// Video height in pixels @@ -202,12 +204,20 @@ pub struct AudioStream { pub size: u64, pub index_range: Option>, pub init_range: Option>, + // Audio duration in milliseconds + pub duration_ms: Option, /// MIME file type pub mime: String, /// Audio file format pub format: AudioFormat, /// Audio codec pub codec: AudioCodec, + /// Number of audio channels + pub channels: Option, + /// Loudness + /// + /// Not available when using the Android client + pub loudness_db: Option, /// True if the deobfuscation of the nsig url parameter failed /// and the stream will be throttled pub throttled: bool,