1
0
Fork 0
mirror of https://github.com/sile/hls_m3u8.git synced 2024-11-25 16:41:00 +00:00

fix key parsing and printing

This commit is contained in:
Luro02 2020-02-16 12:51:49 +01:00
parent b2c997d04d
commit b54b17df73
No known key found for this signature in database
GPG key ID: B66FD4F74501A9CF
2 changed files with 51 additions and 23 deletions

View file

@ -1,3 +1,4 @@
use std::collections::HashSet;
use std::fmt; use std::fmt;
use std::str::FromStr; use std::str::FromStr;
use std::time::Duration; use std::time::Duration;
@ -257,7 +258,33 @@ impl fmt::Display for MediaPlaylist {
writeln!(f, "{}", value)?; writeln!(f, "{}", value)?;
} }
// most likely only 1 ExtXKey will be in the HashSet:
let mut available_keys = HashSet::with_capacity(1);
for segment in &self.segments { for segment in &self.segments {
for key in segment.keys() {
// the key is new:
if available_keys.insert(key) {
let mut remove_key = None;
// an old key might be removed:
for k in &available_keys {
if k.key_format() == key.key_format() && &key != k {
remove_key = Some(k.clone());
break;
}
}
if let Some(k) = remove_key {
// this should always be true:
let res = available_keys.remove(k);
debug_assert!(res);
}
writeln!(f, "{}", key)?;
}
}
write!(f, "{}", segment)?; write!(f, "{}", segment)?;
} }
@ -305,25 +332,28 @@ fn parse_media_playlist(
has_partial_segment = true; has_partial_segment = true;
segment.discontinuity(t); segment.discontinuity(t);
} }
Tag::ExtXKey(t) => { Tag::ExtXKey(key) => {
has_partial_segment = true; has_partial_segment = true;
if available_keys.is_empty() {
// An ExtXKey applies to every MediaSegment and to every Media // An ExtXKey applies to every MediaSegment and to every Media
// Initialization Section declared by an EXT-X-MAP tag, that appears // Initialization Section declared by an ExtXMap tag, that appears
// between it and the next EXT-X-KEY tag in the Playlist file with the // between it and the next ExtXKey tag in the Playlist file with the
// same KEYFORMAT attribute (or the end of the Playlist file). // same KEYFORMAT attribute (or the end of the Playlist file).
available_keys = available_keys
.into_iter() let mut is_new_key = true;
.map(|k| {
if t.key_format() == k.key_format() { for old_key in &mut available_keys {
t.clone() if old_key.key_format() == key.key_format() {
} else { *old_key = key.clone();
k is_new_key = false;
// there are no keys with the same key_format in available_keys
// so the loop can stop here:
break;
} }
}) }
.collect();
} else { if is_new_key {
available_keys.push(t); available_keys.push(key);
} }
} }
Tag::ExtXMap(mut t) => { Tag::ExtXMap(mut t) => {

View file

@ -60,9 +60,7 @@ impl MediaSegmentBuilder {
impl fmt::Display for MediaSegment { impl fmt::Display for MediaSegment {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
for value in &self.keys { // self.keys will be printed by MediaPlaylist!
writeln!(f, "{}", value)?;
}
if let Some(value) = &self.map { if let Some(value) = &self.map {
writeln!(f, "{}", value)?; writeln!(f, "{}", value)?;
@ -120,7 +118,7 @@ mod tests {
fn test_display() { fn test_display() {
assert_eq!( assert_eq!(
MediaSegment::builder() MediaSegment::builder()
.keys(vec![ExtXKey::empty()]) //.keys(vec![ExtXKey::empty()])
.map(ExtXMap::new("https://www.example.com/")) .map(ExtXMap::new("https://www.example.com/"))
.byte_range(ExtXByteRange::new(20, Some(5))) .byte_range(ExtXByteRange::new(20, Some(5)))
//.date_range() // TODO! //.date_range() // TODO!
@ -131,7 +129,7 @@ mod tests {
.unwrap() .unwrap()
.to_string(), .to_string(),
concat!( concat!(
"#EXT-X-KEY:METHOD=NONE\n", //"#EXT-X-KEY:METHOD=NONE\n",
"#EXT-X-MAP:URI=\"https://www.example.com/\"\n", "#EXT-X-MAP:URI=\"https://www.example.com/\"\n",
"#EXT-X-BYTERANGE:20@5\n", "#EXT-X-BYTERANGE:20@5\n",
"#EXT-X-DISCONTINUITY\n", "#EXT-X-DISCONTINUITY\n",