mirror of
https://github.com/rutgersc/m3u8-rs.git
synced 2025-02-28 20:06:19 +00:00
commit
b75379437d
2 changed files with 29 additions and 14 deletions
|
@ -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,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
22
tests/lib.rs
22
tests/lib.rs
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue