Skip to content

Instantly share code, notes, and snippets.

@mlevkov
Created February 20, 2020 23:04
Show Gist options
  • Save mlevkov/be1d540d3fe8f50b92b83734da3e2008 to your computer and use it in GitHub Desktop.
Save mlevkov/be1d540d3fe8f50b92b83734da3e2008 to your computer and use it in GitHub Desktop.
#![allow(unused_imports)]
#![allow(non_snake_case)]
#[macro_use] extern crate log;
extern crate simple_logger;
extern crate xml;
extern crate yaserde;
#[macro_use] extern crate yaserde_derive;
use std::{io::BufReader, fs::File, fs::read_to_string, io::Read, io::Write};
use yaserde::{YaDeserialize, YaSerialize, ser::to_string};
//#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
//#[yaserde(rename_all = "camelCase")] // not working?
//pub struct Root { // for use with json
// #[yaserde(rename = "MPD")]
// pub mpd: Mpd,
//}
#[derive(Default, Debug, Clone, PartialEq, YaSerialize, YaDeserialize)]
#[yaserde(prefix="mpd", namespace="mpd: urn:mpeg:dash:schema:mpd:2011")]
pub struct MPD {
#[yaserde(attribute)]
pub mediaPresentationDuration: String,
#[yaserde(attribute)]
pub minBufferTime: String,
#[yaserde(attribute)]
pub profiles: String,
#[yaserde(attribute, rename = "type")]
pub typed: String,
#[yaserde(attribute)]
pub xmlns: Option<String>,
pub ProgramInformation: ProgramInformation,
pub Period: Vec<Period>,
}
#[derive(Default, Debug, Clone, PartialEq, YaSerialize, YaDeserialize)]
#[yaserde(prefix="mpd", namespace="mpd: urn:mpeg:dash:schema:mpd:2011")]
pub struct ProgramInformation {
#[yaserde(attribute)]
pub moreInformationUrl: String,
}
#[derive(Default, Debug, Clone, PartialEq, YaSerialize, YaDeserialize)]
#[yaserde(prefix="mpd", namespace="mpd: urn:mpeg:dash:schema:mpd:2011")]
pub struct Period {
#[yaserde(attribute)]
pub duration: String,
#[yaserde(attribute)]
pub id: String,
#[yaserde(attribute)]
pub start: String,
pub AdaptationSet: Vec<AdaptationSet>,
}
#[derive(Default, Debug, Clone, PartialEq, YaSerialize, YaDeserialize)]
#[yaserde(prefix="mpd", namespace="mpd: urn:mpeg:dash:schema:mpd:2011")]
pub struct AdaptationSet {
#[yaserde(attribute)]
pub bitstreamSwitching: String,
#[yaserde(attribute)]
pub maxBandwidth: Option<String>,
#[yaserde(attribute)]
pub mimeType: String,
#[yaserde(attribute)]
pub minBandwidth: Option<String>,
#[yaserde(attribute)]
pub segmentAlignment: String,
#[yaserde(attribute)]
pub startWithSAP: String,
#[yaserde(attribute)]
pub subsegmentAlignment: String,
#[yaserde(attribute)]
pub subsegmentStartsWithSAP: String,
ContentProtection: Vec<ContentProtection>,
pub Role: Role,
pub SegmentTemplate: SegmentTemplate,
Representation: Vec<Representation>,
#[yaserde(attribute)]
pub frameRate: Option<String>,
#[yaserde(attribute)]
pub id: Option<String>,
#[yaserde(attribute)]
pub maxHeight: Option<String>,
#[yaserde(attribute)]
pub maxWidth: Option<u32>,
#[yaserde(attribute)]
pub minHeight: Option<String>,
#[yaserde(attribute)]
pub minWidth: Option<String>,
#[yaserde(attribute)]
pub par: Option<String>,
#[yaserde(attribute)]
pub sar: Option<String>,
}
#[derive(Default, Debug, Clone, PartialEq, YaSerialize, YaDeserialize)]
#[yaserde(prefix="mpd", namespace="mpd: urn:mpeg:dash:schema:mpd:2011")]
struct ContentProtection {
#[yaserde(attribute)]
schemeIdUri: String,
#[yaserde(attribute)]
value: Option<String>,
}
#[derive(Default, Debug, Clone, PartialEq, YaSerialize, YaDeserialize)]
#[yaserde(prefix="mpd", namespace="mpd: urn:mpeg:dash:schema:mpd:2011")]
pub struct Role {
#[yaserde(attribute)]
pub schemeIdUri: String,
#[yaserde(attribute)]
pub value: String,
}
#[derive(Default, Debug, Clone, PartialEq, YaSerialize, YaDeserialize)]
#[yaserde(prefix="mpd", namespace="mpd: urn:mpeg:dash:schema:mpd:2011")]
pub struct SegmentTemplate {
#[yaserde(attribute)]
pub initialization: String,
#[yaserde(attribute)]
pub media: String,
#[yaserde(attribute)]
pub timescale: String,
pub SegmentTimeline: SegmentTimeline,
}
#[derive(Default, Debug, Clone, PartialEq, YaSerialize, YaDeserialize)]
#[yaserde(prefix="mpd", namespace="mpd: urn:mpeg:dash:schema:mpd:2011")]
pub struct SegmentTimeline {
pub S: Vec<S>,
}
#[derive(Default, Debug, Clone, PartialEq, YaSerialize, YaDeserialize)]
#[yaserde(prefix="mpd", namespace="mpd: urn:mpeg:dash:schema:mpd:2011")]
pub struct S {
#[yaserde(attribute)]
d: u64,
#[yaserde(attribute)]
t: u64,
#[yaserde(attribute)]
r: Option<u32>,
}
#[derive(Default, Debug, Clone, PartialEq, YaSerialize, YaDeserialize)]
#[yaserde(prefix="mpd", namespace="mpd: urn:mpeg:dash:schema:mpd:2011")]
struct Representation{
#[yaserde(attribute)]
audioSamplingRate: Option<String>,
#[yaserde(attribute)]
bandwidth: String,
#[yaserde(attribute)]
codecs: String,
#[yaserde(attribute)]
id: String,
AudioChannelConfiguration: Option<AudioChannelConfiguration>,
}
#[derive(Default, Debug, Clone, PartialEq, YaSerialize, YaDeserialize)]
#[yaserde(prefix="mpd", namespace="mpd: urn:mpeg:dash:schema:mpd:2011")]
struct AudioChannelConfiguration{
#[yaserde(attribute)]
schemeIdUri: String,
#[yaserde(attribute)]
value: Option<String>,
}
fn main() -> Result<(), Box<dyn std::error::Error + 'static>>{
let _raw_string = r##"
<?xml version="1.0" encoding="utf-8"?>
<MPD mediaPresentationDuration="PT1H50M47S" minBufferTime="PT19S" profiles="urn:mpeg:dash:profile:isoff-live:2011" type="static" xmlns="urn:mpeg:dash:schema:mpd:2011">
<ProgramInformation moreInformationURL="www.castLabs.com"/>
<Period duration="PT1H50M47S" id="0" start="PT0S">
<AdaptationSet bitstreamSwitching="True" maxBandwidth="127800" mimeType="audio/mp4" minBandwidth="63700" segmentAlignment="True" startWithSAP="1" subsegmentAlignment="True" subsegmentStartsWithSAP="1">
<ContentProtection schemeIdUri="urn:mpeg:dash:mp4protection:2011" value="cenc"/>
<ContentProtection schemeIdUri="urn:uuid:9a04f079-9840-4286-ab92-e65be0885f95"/>
<ContentProtection schemeIdUri="urn:uuid:edef8ba9-79d6-4ace-a3c8-27dcd51d21ed"/>
<Role schemeIdUri="urn:mpeg:dash:role:2011" value="main"/>
<SegmentTemplate initialization="$RepresentationID$/init.mp4" media="$RepresentationID$/media-$Time$.mp4" timescale="48000">
<SegmentTimeline>
<S d="192512" t="0"/>
<S d="137216" t="318799872"/>
<S d="137714" t="318937088"/>
</SegmentTimeline>
</SegmentTemplate>
<Representation audioSamplingRate="48000" bandwidth="63700" codecs="mp4a.40.2" id="519678732693145249_AO-00-00-00-71">
<AudioChannelConfiguration schemeIdUri="urn:mpeg:dash:23003:3:audio_channel_configuration:2011" value="2"/>
</Representation>
<Representation audioSamplingRate="48000" bandwidth="127800" codecs="mp4a.40.2" id="519678732693145249_AO-00-00-00-81">
<AudioChannelConfiguration schemeIdUri="urn:mpeg:dash:23003:3:audio_channel_configuration:2011" value="2"/>
</Representation>
</AdaptationSet>
<AdaptationSet bitstreamSwitching="True" mimeType="audio/mp4" segmentAlignment="True" startWithSAP="1" subsegmentAlignment="True" subsegmentStartsWithSAP="1">
<ContentProtection schemeIdUri="urn:mpeg:dash:mp4protection:2011" value="cenc"/>
<ContentProtection schemeIdUri="urn:uuid:9a04f079-9840-4286-ab92-e65be0885f95"/>
<ContentProtection schemeIdUri="urn:uuid:edef8ba9-79d6-4ace-a3c8-27dcd51d21ed"/>
<Role schemeIdUri="urn:mpeg:dash:role:2011" value="main"/>
<SegmentTemplate initialization="$RepresentationID$/init.mp4" media="$RepresentationID$/media-$Time$.mp4" timescale="48000">
<SegmentTimeline>
<S d="192000" t="1792"/>
<S d="176640" t="318721792"/>
</SegmentTimeline>
</SegmentTemplate>
<Representation audioSamplingRate="48000" bandwidth="192000" codecs="ec-3" id="519678732693145249_AO-00-00-00-73">
<AudioChannelConfiguration schemeIdUri="urn:dolby:dash:audio_channel_configuration:2011" value="F801"/>
</Representation>
</AdaptationSet>
<AdaptationSet bitstreamSwitching="True" mimeType="audio/mp4" segmentAlignment="True" startWithSAP="1" subsegmentAlignment="True" subsegmentStartsWithSAP="1">
<ContentProtection schemeIdUri="urn:mpeg:dash:mp4protection:2011" value="cenc"/>
<ContentProtection schemeIdUri="urn:uuid:9a04f079-9840-4286-ab92-e65be0885f95"/>
<ContentProtection schemeIdUri="urn:uuid:edef8ba9-79d6-4ace-a3c8-27dcd51d21ed"/>
<Role schemeIdUri="urn:mpeg:dash:role:2011" value="main"/>
<SegmentTemplate initialization="$RepresentationID$/init.mp4" media="$RepresentationID$/media-$Time$.mp4" timescale="48000">
<SegmentTimeline>
<S d="192000" t="1792"/>
<S d="176640" t="318721792"/>
</SegmentTimeline>
</SegmentTemplate>
<Representation audioSamplingRate="48000" bandwidth="384000" codecs="ac-3" id="519678732693145249_AO-00-00-00-74">
<AudioChannelConfiguration schemeIdUri="urn:dolby:dash:audio_channel_configuration:2011" value="F801"/>
</Representation>
</AdaptationSet>
<AdaptationSet bitstreamSwitching="True" frameRate="23976/1000" id="1" maxBandwidth="6771700" maxHeight="1080" maxWidth="1920" mimeType="video/mp4" minBandwidth="62300" minHeight="144" minWidth="256" par="16:9" sar="1:1" segmentAlignment="True" startWithSAP="1" subsegmentAlignment="True" subsegmentStartsWithSAP="1">
<ContentProtection schemeIdUri="urn:mpeg:dash:mp4protection:2011" value="cenc"/>
<ContentProtection schemeIdUri="urn:uuid:9a04f079-9840-4286-ab92-e65be0885f95"/>
<ContentProtection schemeIdUri="urn:uuid:edef8ba9-79d6-4ace-a3c8-27dcd51d21ed"/>
<Role schemeIdUri="urn:mpeg:dash:role:2011" value="main"/>
<SegmentTemplate initialization="$RepresentationID$/init.mp4" media="$RepresentationID$/media-$Time$.mp4" timescale="11988">
<SegmentTimeline>
<S d="48000" r="3" t="510"/>
<S d="32500" t="79656510"/>
<S d="24000" r="2" t="23952510"/>
</SegmentTimeline>
</SegmentTemplate>
<Representation bandwidth="4043800" codecs="avc1.4d4020" height="720" id="519678732693145249_AV-00-00-00-65" width="1280"/>
<Representation bandwidth="4555000" codecs="avc1.4d4020" height="720" id="519678732693145249_AV-00-00-00-76" width="1280"/>
<Representation bandwidth="5104900" codecs="avc1.4d4020" height="720" id="519678732693145249_AV-00-00-00-66" width="1280"/>
<Representation bandwidth="62300" codecs="avc1.4d401e" height="288" id="519678732693145249_AV-00-00-00-84" width="512"/>
<Representation bandwidth="249300" codecs="avc1.4d401e" height="288" id="519678732693145249_AV-00-00-00-82" width="512"/>
<Representation bandwidth="408500" codecs="avc1.4d401e" height="144" id="519678732693145249_AV-00-00-00-50" width="256"/>
<Representation bandwidth="491000" codecs="avc1.4d401e" height="432" id="519678732693145249_AV-00-00-00-51" width="768"/>
<Representation bandwidth="716700" codecs="avc1.4d401e" height="288" id="519678732693145249_AV-00-00-00-53" width="512"/>
<Representation bandwidth="731700" codecs="avc1.4d401e" height="432" id="519678732693145249_AV-00-00-00-52" width="768"/>
<Representation bandwidth="929100" codecs="avc1.4d401e" height="288" id="519678732693145249_AV-00-00-00-55" width="512"/>
<Representation bandwidth="965100" codecs="avc1.4d401e" height="432" id="519678732693145249_AV-00-00-00-54" width="768"/>
<Representation bandwidth="1418800" codecs="avc1.4d401e" height="432" id="519678732693145249_AV-00-00-00-56" width="768"/>
<Representation bandwidth="6771700" codecs="avc1.640028" height="1080" id="519678732693145249_AV-00-00-00-79" width="1920"/>
<Representation bandwidth="1731400" codecs="avc1.4d401e" height="432" id="519678732693145249_AV-00-00-00-57" width="768"/>
<Representation bandwidth="2050400" codecs="avc1.4d401e" height="432" id="519678732693145249_AV-00-00-00-58" width="768"/>
<Representation bandwidth="2416200" codecs="avc1.4d401e" height="540" id="519678732693145249_AV-00-00-00-75" width="960"/>
<Representation bandwidth="2697000" codecs="avc1.4d401e" height="432" id="519678732693145249_AV-00-00-00-59" width="768"/>
<Representation bandwidth="2854400" codecs="avc1.4d401e" height="540" id="519678732693145249_AV-00-00-00-61" width="960"/>
<Representation bandwidth="3472600" codecs="avc1.4d4020" height="720" id="519678732693145249_AV-00-00-00-64" width="1280"/>
</AdaptationSet>
</Period>
</MPD>
"##;
// read from file
//DEBUG let fl = File::open("./samples/manifest1.mpd").expect("unable to open file");
//DEBUG let reader = BufReader::new(fl);
let entire_fl_as_string = read_to_string("./samples/manifest1.mpd")?;
//DEBUG println!("{:#?}", entire_fl_as_string);
let data: MPD = yaserde::de::from_str(&entire_fl_as_string)?;
println!("======");
println!("+++");
let serialized = yaserde::ser::to_string(&data).unwrap();
let s = serialized
.replace("<mpd:","<")
.replace("</mpd:MPD", "</MPD")
.replace("</mpd:", "</")
.replace("xmlns:mpd", "xmlns")
.replace("\" />","\"/>");
println!("{}", s);
println!("=======");
Ok(())
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment