spotifyio/crates/spotifyio/src/util.rs

140 lines
4.6 KiB
Rust

//! Additional utilities for interacting with Spotify
use crate::pb::AudioFileFormat;
pub type SocketAddress = (String, u16);
/// User agent for HTTP requests
pub const USER_AGENT: &str = "Spotify/124500454 Linux/0 (PC desktop)";
/// Spotify app version
pub const SPOTIFY_VERSION: &str = "1.2.31.1205.g4d59ad7c";
/// Spotify app version number
pub const SPOTIFY_VERSION_NUMBER: u64 = 117300517;
/// Spotify OAuth client ID
pub const SPOTIFY_CLIENT_ID: &str = "65b708073fc0480ea92a077233ca87bd";
/// AES128 initialization vector for audio decryption
pub const AUDIO_AESIV: [u8; 16] = [
0x72, 0xe0, 0x67, 0xfb, 0xdd, 0xcb, 0xcf, 0x77, 0xeb, 0xe8, 0xbc, 0x64, 0x3f, 0x63, 0x0d, 0x93,
];
pub(crate) trait Seq {
fn next(&self) -> Self;
}
macro_rules! impl_seq {
($($ty:ty)*) => { $(
impl Seq for $ty {
fn next(&self) -> Self { (*self).wrapping_add(1) }
}
)* }
}
impl_seq!(u8 u16 u32 u64 usize);
#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord, Default)]
pub(crate) struct SeqGenerator<T: Seq>(T);
impl<T: Seq> SeqGenerator<T> {
pub fn new(value: T) -> Self {
SeqGenerator(value)
}
pub fn get(&mut self) -> T {
let value = self.0.next();
std::mem::replace(&mut self.0, value)
}
}
pub fn audio_format_extension(format: AudioFileFormat) -> Option<&'static str> {
match format {
AudioFileFormat::OGG_VORBIS_96
| AudioFileFormat::OGG_VORBIS_160
| AudioFileFormat::OGG_VORBIS_320 => Some(".ogg"),
AudioFileFormat::MP3_96
| AudioFileFormat::MP3_160
| AudioFileFormat::MP3_160_ENC
| AudioFileFormat::MP3_256
| AudioFileFormat::MP3_320 => Some(".mp3"),
AudioFileFormat::AAC_24 | AudioFileFormat::AAC_48 => Some(".aac"),
AudioFileFormat::MP4_128
| AudioFileFormat::MP4_128_DUAL
| AudioFileFormat::MP4_256
| AudioFileFormat::MP4_256_DUAL => Some(".m4a"),
AudioFileFormat::FLAC_FLAC => Some(".flac"),
AudioFileFormat::UNKNOWN_FORMAT => None,
}
}
pub fn audio_format_mime(format: AudioFileFormat) -> Option<&'static str> {
match format {
AudioFileFormat::OGG_VORBIS_96
| AudioFileFormat::OGG_VORBIS_160
| AudioFileFormat::OGG_VORBIS_320 => Some("audio/ogg"),
AudioFileFormat::MP3_96
| AudioFileFormat::MP3_160
| AudioFileFormat::MP3_160_ENC
| AudioFileFormat::MP3_256
| AudioFileFormat::MP3_320 => Some("audio/mp3"),
AudioFileFormat::AAC_24 | AudioFileFormat::AAC_48 => Some("audio/aac"),
AudioFileFormat::MP4_128
| AudioFileFormat::MP4_128_DUAL
| AudioFileFormat::MP4_256
| AudioFileFormat::MP4_256_DUAL => Some("audio/mp4"),
AudioFileFormat::FLAC_FLAC => Some("audio/flac"),
AudioFileFormat::UNKNOWN_FORMAT => None,
}
}
/// Get the bitrate of the audio format in kbit/s
pub fn audio_format_bitrate(format: AudioFileFormat) -> Option<u32> {
match format {
AudioFileFormat::OGG_VORBIS_96 | AudioFileFormat::MP3_96 => Some(96000),
AudioFileFormat::OGG_VORBIS_160
| AudioFileFormat::MP3_160
| AudioFileFormat::MP3_160_ENC => Some(160000),
AudioFileFormat::OGG_VORBIS_320 | AudioFileFormat::MP3_320 => Some(320000),
AudioFileFormat::MP4_128 | AudioFileFormat::MP4_128_DUAL => Some(128000),
AudioFileFormat::MP3_256 | AudioFileFormat::MP4_256 | AudioFileFormat::MP4_256_DUAL => {
Some(256000)
}
AudioFileFormat::AAC_24 => Some(24000),
AudioFileFormat::AAC_48 => Some(48000),
AudioFileFormat::FLAC_FLAC | AudioFileFormat::UNKNOWN_FORMAT => None,
}
}
pub fn audio_format_available(format: AudioFileFormat, is_premium: bool) -> bool {
match format {
AudioFileFormat::OGG_VORBIS_96
| AudioFileFormat::OGG_VORBIS_160
| AudioFileFormat::MP3_160
| AudioFileFormat::MP3_96
| AudioFileFormat::MP3_160_ENC
| AudioFileFormat::AAC_24
| AudioFileFormat::AAC_48
| AudioFileFormat::MP4_128
| AudioFileFormat::MP4_128_DUAL => true,
AudioFileFormat::OGG_VORBIS_320
| AudioFileFormat::MP3_256
| AudioFileFormat::MP3_320
| AudioFileFormat::MP4_256
| AudioFileFormat::MP4_256_DUAL
| AudioFileFormat::FLAC_FLAC => is_premium,
AudioFileFormat::UNKNOWN_FORMAT => false,
}
}
/// Return true if the audio format uses Widevine
pub fn audio_format_widevine(format: AudioFileFormat) -> bool {
matches!(
format,
AudioFileFormat::MP4_128
| AudioFileFormat::MP4_128_DUAL
| AudioFileFormat::MP4_256
| AudioFileFormat::MP4_256_DUAL
)
}