Merge pull request #16 from rafaelcaricio/master

Expose unknown tags
This commit is contained in:
rutgersc 2021-04-20 19:35:58 +02:00 committed by GitHub
commit b75379437d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 29 additions and 14 deletions

View file

@ -69,7 +69,8 @@ pub struct MasterPlaylist {
pub session_key: Option<SessionKey>, pub session_key: Option<SessionKey>,
pub start: Option<Start>, pub start: Option<Start>,
pub independent_segments: bool, pub independent_segments: bool,
pub alternatives: Vec<AlternativeMedia> // EXT-X-MEDIA tags pub alternatives: Vec<AlternativeMedia>, // EXT-X-MEDIA tags
pub unknown_tags: Vec<ExtTag>
} }
impl MasterPlaylist { impl MasterPlaylist {
@ -105,8 +106,8 @@ impl MasterPlaylist {
MasterPlaylistTag::IndependentSegments => { MasterPlaylistTag::IndependentSegments => {
master_playlist.independent_segments = true; master_playlist.independent_segments = true;
} }
MasterPlaylistTag::Unknown(_) => { MasterPlaylistTag::Unknown(unknown) => {
// println!("Unknown master tag \n{:?}\n", t); master_playlist.unknown_tags.push(unknown);
} }
_ => (), _ => (),
} }
@ -142,6 +143,9 @@ impl MasterPlaylist {
if self.independent_segments { if self.independent_segments {
writeln!(w, "#EXT-X-INDEPENDENT-SEGMENTS")?; writeln!(w, "#EXT-X-INDEPENDENT-SEGMENTS")?;
} }
for unknown_tag in &self.unknown_tags {
write!(w, "#EXT-{}:{}\n", unknown_tag.tag, unknown_tag.rest)?;
}
Ok(()) Ok(())
} }
@ -405,6 +409,8 @@ pub struct MediaPlaylist {
pub start: Option<Start>, pub start: Option<Start>,
/// `#EXT-X-INDEPENDENT-SEGMENTS` /// `#EXT-X-INDEPENDENT-SEGMENTS`
pub independent_segments: bool, pub independent_segments: bool,
/// `#EXT-X-`
pub unknown_tags: Vec<ExtTag>
} }
impl MediaPlaylist { impl MediaPlaylist {
@ -469,6 +475,9 @@ impl MediaPlaylist {
SegmentTag::DateRange(d) => { SegmentTag::DateRange(d) => {
next_segment.daterange = Some(d); next_segment.daterange = Some(d);
} }
SegmentTag::Unknown(t) => {
media_playlist.unknown_tags.push(t);
}
SegmentTag::Uri(u) => { SegmentTag::Uri(u) => {
next_segment.key = encryption_key.clone(); next_segment.key = encryption_key.clone();
next_segment.map = map.clone(); next_segment.map = map.clone();
@ -516,6 +525,9 @@ impl MediaPlaylist {
for segment in &self.segments { for segment in &self.segments {
segment.write_to(w)?; segment.write_to(w)?;
} }
for unknown_tag in &self.unknown_tags {
write!(w, "#EXT-{}:{}\n", unknown_tag.tag, unknown_tag.rest)?;
}
Ok(()) Ok(())
} }
@ -789,8 +801,9 @@ impl Start {
} }
/// A simple `#EXT-` tag /// A simple `#EXT-` tag
#[derive(Debug, Default, Clone)] #[derive(Debug, Default, PartialEq, Clone)]
pub struct ExtTag { pub struct ExtTag {
pub tag: String, pub tag: String,
pub rest: String, pub rest: String,
} }

View file

@ -130,7 +130,7 @@ fn playlist_types() {
println!("{:?} = {:?}", path, is_master); println!("{:?} = {:?}", path, is_master);
assert!(path.to_lowercase().contains("master") == is_master); assert!(path.to_lowercase().contains("master") == is_master);
} }
} }
@ -191,7 +191,7 @@ fn test_key_value_pair() {
Result::Ok(( Result::Ok((
"rest".as_bytes(), "rest".as_bytes(),
("PROGRAM-ID".to_string(), "1".to_string()) ("PROGRAM-ID".to_string(), "1".to_string())
)) ))
); );
} }
@ -276,9 +276,9 @@ fn print_create_and_parse_playlist(playlist_original: &mut Playlist) -> Playlist
let m3u8_str: &str = std::str::from_utf8(&utf8).unwrap(); let m3u8_str: &str = std::str::from_utf8(&utf8).unwrap();
let playlist_parsed = match *playlist_original { let playlist_parsed = match *playlist_original {
Playlist::MasterPlaylist(_) => Playlist::MasterPlaylist(_) =>
Playlist::MasterPlaylist(parse_master_playlist_res(m3u8_str.as_bytes()).unwrap()), Playlist::MasterPlaylist(parse_master_playlist_res(m3u8_str.as_bytes()).unwrap()),
Playlist::MediaPlaylist(_) => Playlist::MediaPlaylist(_) =>
Playlist::MediaPlaylist(parse_media_playlist_res(m3u8_str.as_bytes()).unwrap()), Playlist::MediaPlaylist(parse_media_playlist_res(m3u8_str.as_bytes()).unwrap()),
}; };
@ -336,8 +336,8 @@ fn create_and_parse_master_playlist_full() {
data_id: "****".into(), data_id: "****".into(),
value: "%%%%".into(), value: "%%%%".into(),
uri: "++++".into(), uri: "++++".into(),
language: Some("SessionDataLanguage".into()), language: Some("SessionDataLanguage".into()),
}), }),
session_key: Some(SessionKey(Key { session_key: Some(SessionKey(Key {
method: "AES-128".into(), method: "AES-128".into(),
uri: Some("https://secure.domain.com".into()), uri: Some("https://secure.domain.com".into()),
@ -350,6 +350,7 @@ fn create_and_parse_master_playlist_full() {
precise: Some("YES".into()), precise: Some("YES".into()),
}), }),
independent_segments: true, independent_segments: true,
unknown_tags: vec![],
}); });
let playlist_parsed = print_create_and_parse_playlist(&mut playlist_original); let playlist_parsed = print_create_and_parse_playlist(&mut playlist_original);
assert_eq!(playlist_original, playlist_parsed); assert_eq!(playlist_original, playlist_parsed);
@ -364,7 +365,7 @@ fn create_and_parse_media_playlist_empty() {
#[test] #[test]
fn create_and_parse_media_playlist_single_segment() { fn create_and_parse_media_playlist_single_segment() {
let mut playlist_original = Playlist::MediaPlaylist(MediaPlaylist { let mut playlist_original = Playlist::MediaPlaylist(MediaPlaylist {
segments: vec![ segments: vec![
MediaSegment { MediaSegment {
uri: "20140311T113819-01-338559live.ts".into(), uri: "20140311T113819-01-338559live.ts".into(),
@ -394,7 +395,7 @@ fn create_and_parse_media_playlist_full() {
time_offset: "9999".into(), time_offset: "9999".into(),
precise: Some("YES".into()), precise: Some("YES".into()),
}), }),
independent_segments: true, independent_segments: true,
segments: vec![ segments: vec![
MediaSegment { MediaSegment {
uri: "20140311T113819-01-338559live.ts".into(), uri: "20140311T113819-01-338559live.ts".into(),
@ -408,7 +409,7 @@ fn create_and_parse_media_playlist_full() {
iv: Some("0xb059217aa2649ce170b734".into()), iv: Some("0xb059217aa2649ce170b734".into()),
keyformat: Some("xXkeyformatXx".into()), keyformat: Some("xXkeyformatXx".into()),
keyformatversions: Some("xXFormatVers".into()), keyformatversions: Some("xXFormatVers".into()),
}), }),
map: Some(Map { map: Some(Map {
uri: "www.map-uri.com".into(), uri: "www.map-uri.com".into(),
byte_range: Some(ByteRange::from("137116@497036")), byte_range: Some(ByteRange::from("137116@497036")),
@ -417,6 +418,7 @@ fn create_and_parse_media_playlist_full() {
daterange: None, daterange: None,
}, },
], ],
unknown_tags: vec![],
}); });
let playlist_parsed = print_create_and_parse_playlist(&mut playlist_original); let playlist_parsed = print_create_and_parse_playlist(&mut playlist_original);
assert_eq!(playlist_original, playlist_parsed); assert_eq!(playlist_original, playlist_parsed);
@ -439,7 +441,7 @@ fn parsing_write_to_should_produce_the_same_structure() {
assert_eq!( assert_eq!(
expected, actual, expected, actual,
"\n\nFailed parser input:\n\n{}\n\nOriginal input:\n\n{}", "\n\nFailed parser input:\n\n{}\n\nOriginal input:\n\n{}",
std::str::from_utf8(&written).unwrap(), input); std::str::from_utf8(&written).unwrap(), input);
} }
} }