use iri_string::types::{IriAbsoluteString, IriString};
use serde::{Deserialize, Serialize};
mod oembed;
use crate::models::media::oembed::OEmbed;
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct MediaEmbed {
content: String,
width: u16,
scrolling: bool,
media_domain_url: Option<IriString>,
height: u16,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
#[serde(untagged)]
pub enum Media {
OEmbed(OEmbed),
RedditVideo { reddit_video: RedditVideo },
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
#[serde(rename_all = "snake_case")]
pub struct RedditVideo {
pub bitrate_kbps: u32,
pub fallback_url: IriAbsoluteString,
pub height: u32,
pub width: u32,
pub scrubber_media_url: IriAbsoluteString,
pub dash_url: IriAbsoluteString,
pub duration: u32,
pub hls_url: IriAbsoluteString,
pub is_gif: bool,
pub transcoding_status: TranscodingStatus,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct MediaThumbnail {
#[serde(rename = "thumbnail_width")]
width: u16,
#[serde(rename = "thumbnail_height")]
height: u16,
#[serde(rename = "thumbnail_url")]
url: IriAbsoluteString,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
#[serde(rename_all = "snake_case")]
pub enum TranscodingStatus {
Completed,
}
#[cfg(test)]
mod test_media {
#![allow(clippy::pedantic)]
use super::*;
use crate::models::media::oembed::{
streamable, OEmbedData, OEmbedProvider, OEmbedType, OEmbedVersion,
};
#[test]
fn test_youtube() {
let media = Media::OEmbed(OEmbed::YouTube(OEmbedData {
height: Default::default(),
width: Default::default(),
html: Default::default(),
provider: OEmbedProvider {
name: Default::default(),
url: "https://www.reddit.com/".parse().unwrap(),
},
version: OEmbedVersion::V1_0,
thumbnail: Some(MediaThumbnail {
width: Default::default(),
url: "https://www.reddit.com/".parse().unwrap(),
height: Default::default(),
}),
ty: OEmbedType::Video,
vendor_specific_data: oembed::youtube::YouTube {
title: Default::default(),
author_name: Default::default(),
author_url: "https://www.reddit.com/".parse().unwrap(),
},
}));
let _json = serde_json::to_string_pretty(&media).unwrap();
}
#[test]
fn test_streamable() {
let media = Media::OEmbed(OEmbed::Streamable(OEmbedData {
height: Default::default(),
width: Default::default(),
html: Default::default(),
provider: OEmbedProvider {
name: Default::default(),
url: "https://www.reddit.com/".parse().unwrap(),
},
version: OEmbedVersion::V1_0,
thumbnail: Some(MediaThumbnail {
width: Default::default(),
url: "https://www.reddit.com/".parse().unwrap(),
height: Default::default(),
}),
ty: OEmbedType::Video,
vendor_specific_data: streamable::Streamable {
title: Default::default(),
description: Default::default(),
},
}));
let json = serde_json::to_string_pretty(&media).unwrap();
// println!("{}", json);
let json = r#"
{
"oembed": {
"provider_url": "https://streamable.com",
"description": "Watch this video on Streamable.",
"title": "Streamable Video",
"thumbnail_width": 1280,
"height": 338,
"width": 600,
"html": "<iframe class=\"embedly-embed\" src=\"https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fstreamable.com%2Fo%2Fgixxf0&display_name=Streamable&url=https%3A%2F%2Fstreamable.com%2Fgixxf0&image=https%3A%2F%2Fcdn-cf-east.streamable.com%2Fimage%2Fgixxf0.jpg%3FExpires%3D1634216820%26Signature%3DdoMgebEgi-eHwDrMcGIUyMTfOSBbA5tjLo9PtT4D4tjPPL3oLGzOGEEaro3kGUhP6L-0PplxBbHiuNBoFGDiKMJv0KWMBQ4VEdLSIQ0wB78%7EPe4kYENxS3gDtYk%7EUjUktnu3fFLeTCLCYTFVNm7e1mEqpIrB0yB6b9RAQ9igkaa2jhpRHceh0yOvQgXe-a-yg4VaDMPHHE4XAYHwzhO68s7066cWtvgj-Uci1PA%7E5W5qt7FqFDPT3FAmLgGbKopfQq-y8mKfTHu7KOfWVQgwEuEnHGe9I10cVW7e%7EMyfO9PY5oDzczhH7ffGU1fnDRXTQ2GGjhdkV2joVOgQ4CuX2Q__%26Key-Pair-Id%3DAPKAIEYUVEN4EVB2OKEQ&key=ed8fa8699ce04833838e66ce79ba05f1&type=text%2Fhtml&schema=streamable\" width=\"600\" height=\"338\" scrolling=\"no\" title=\"Streamable embed\" frameborder=\"0\" allow=\"autoplay; fullscreen\" allowfullscreen=\"true\"></iframe>",
"version": "1.0",
"provider_name": "Streamable",
"thumbnail_url": "https://cdn-cf-east.streamable.com/image/gixxf0.jpg?Expires=1634216820&Signature=doMgebEgi-eHwDrMcGIUyMTfOSBbA5tjLo9PtT4D4tjPPL3oLGzOGEEaro3kGUhP6L-0PplxBbHiuNBoFGDiKMJv0KWMBQ4VEdLSIQ0wB78~Pe4kYENxS3gDtYk~UjUktnu3fFLeTCLCYTFVNm7e1mEqpIrB0yB6b9RAQ9igkaa2jhpRHceh0yOvQgXe-a-yg4VaDMPHHE4XAYHwzhO68s7066cWtvgj-Uci1PA~5W5qt7FqFDPT3FAmLgGbKopfQq-y8mKfTHu7KOfWVQgwEuEnHGe9I10cVW7e~MyfO9PY5oDzczhH7ffGU1fnDRXTQ2GGjhdkV2joVOgQ4CuX2Q__&Key-Pair-Id=APKAIEYUVEN4EVB2OKEQ",
"type": "video",
"thumbnail_height": 720
},
"type": "streamable.com"
}"#;
dbg!(serde_json::from_str::<Media>(json).unwrap());
}
#[test]
fn test_twitter() {
let json = r##"
{
"type": "twitter.com",
"oembed": {
"version": "1.0",
"url": "https://twitter.com/LordKebun/status/1447420243010281473",
"author_name": "Kebun",
"height": null,
"width": 350,
"html": "\u003Cblockquote class=\"twitter-video\"\u003E\u003Cp lang=\"en\" dir=\"ltr\"\u003ERate my Ramee RP Impersonation. \u003Ca href=\"https://t.co/vipSaqsrDe\"\u003Epic.twitter.com/vipSaqsrDe\u003C/a\u003E\u003C/p\u003E\u0026mdash; Kebun (@LordKebun) \u003Ca href=\"https://twitter.com/LordKebun/status/1447420243010281473?ref_src=twsrc%5Etfw\"\u003EOctober 11, 2021\u003C/a\u003E\u003C/blockquote\u003E\n\u003Cscript async src=\"https://platform.twitter.com/widgets.js\" charset=\"utf-8\"\u003E\u003C/script\u003E\n",
"author_url": "https://twitter.com/LordKebun",
"cache_age": 3153600000,
"type": "rich",
"provider_url": "https://twitter.com",
"provider_name": "Twitter"
}
}"##;
dbg!(serde_json::from_str::<Media>(json).unwrap());
}
#[test]
fn test_oembed_bandcamp() {
let json = r##"{
"type": "futurespiritualman.bandcamp.com",
"oembed": {
"provider_url": "http://bandcamp.com",
"description": "beaf by futurespiritualman, released 01 January 2021 1. b-horn ft._Lil Peter_&_Frank.mp3 2. funk_part_2._ft_FUNKEYMAN_supreme.mp3 3. the_toop_ft._Lil_Peter.mp3 4. i_eat_rocks.mp3 5. dog_walker_ft._Gizzer_NP_.mp3 6. beefstew_ft._SuizideDeth.mp3 7. going_to_jail_part_II.mp3 8. breats_ft._Lil_Peter.mp3 9. my_truck_ft._BigK2000.mp3 10. balls2man.mp3 11. FIVE_thefourtyninerswinin2075.mp3 12. good_he.mp3 13. i_eat_rocks.mp3 14. truck_(_truck_truck_truck_truck_).mp3 15. my_truck_part_2._ft._Frank(version_1_).mp3 16. cum)lord__.mp3 17. joe.mp3 18. truck_4_(version2).mp3 19. i_love_youft.__Frank.mp3 20. RAP_ft._thelegendsupreme.mp3 21.",
"title": "beaf, by futurespiritualman",
"type": "rich",
"thumbnail_width": 700,
"height": 467,
"width": 350,
"html": "<iframe class=\"embedly-embed\" src=\"https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fbandcamp.com%2FEmbeddedPlayer%2Fv%3D2%2Falbum%3D1766047770%2Fsize%3Dlarge%2Flinkcol%3D0084B4%2Fnotracklist%3Dtrue%2Ftwittercard%3Dtrue%2F&display_name=BandCamp&url=https%3A%2F%2Ffuturespiritualman.bandcamp.com%2Falbum%2Fbeaf&image=https%3A%2F%2Ff4.bcbits.com%2Fimg%2Fa2778328046_5.jpg&key=ed8fa8699ce04833838e66ce79ba05f1&type=text%2Fhtml&schema=bandcamp\" width=\"350\" height=\"467\" scrolling=\"no\" title=\"BandCamp embed\" frameborder=\"0\" allow=\"autoplay; fullscreen\" allowfullscreen=\"true\"></iframe>",
"version": "1.0",
"provider_name": "BandCamp",
"thumbnail_url": "https://f4.bcbits.com/img/a2778328046_5.jpg",
"thumbnail_height": 700
}
}"##;
dbg!(serde_json::from_str::<Media>(json).unwrap());
}
}