This commit is contained in:
Anton Eicher 2024-01-30 10:44:19 +00:00 committed by GitHub
commit ebf40a71ea
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 86 additions and 2 deletions

View file

@ -0,0 +1,30 @@
#EXTM3U
#EXT-X-TARGETDURATION:11
#EXT-X-VERSION:4
#EXT-X-MEDIA-SEQUENCE:0
#EXT-X-PLAYLIST-TYPE:VOD
#EXTINF:9.00000,
#EXT-X-BYTERANGE:86920@0
main.aac
#EXTINF:10.00000,
#EXT-X-BYTERANGE:136595@86920
main.aac
#EXTINF:9.00000,
#EXT-X-BYTERANGE:136567@223515
main.aac
#EXTINF:10.00000,
#EXT-X-BYTERANGE:136954@360082
main.aac
#EXTINF:10.00000,
#EXT-X-BYTERANGE:137116@497036
main.aac
#EXTINF:9.00000,
#EXT-X-BYTERANGE:136770@634152
main.aac
#EXTINF:10.00000,
#EXT-X-BYTERANGE:137219@770922
main.aac
#EXTINF:10.00000,
#EXT-X-BYTERANGE:137132@908141
main.acc
#EXT-X-ENDLIST

View file

@ -821,7 +821,7 @@ impl Default for MediaPlaylistType {
/// A [Media Segment](https://tools.ietf.org/html/draft-pantos-http-live-streaming-19#section-3)
/// is specified by a URI and optionally a byte range.
#[derive(Debug, Default, PartialEq, Clone)]
#[derive(Debug, PartialEq, Clone)]
pub struct MediaSegment {
pub uri: String,
/// `#EXTINF:<duration>,[<title>]`
@ -842,9 +842,13 @@ pub struct MediaSegment {
pub daterange: Option<DateRange>,
/// `#EXT-`
pub unknown_tags: Vec<ExtTag>,
/// Precision of floating-point values, such as `#EXTINF:<duration>`
pub float_precision: usize,
}
impl MediaSegment {
pub const DEFAULT_FLOAT_PRECISION: usize = 5;
pub fn empty() -> MediaSegment {
Default::default()
}
@ -884,7 +888,7 @@ impl MediaSegment {
writeln!(w, "{}", unknown_tag)?;
}
write!(w, "#EXTINF:{},", self.duration)?;
write!(w, "#EXTINF:{:.*},", self.float_precision, self.duration)?;
if let Some(ref v) = self.title {
writeln!(w, "{}", v)?;
@ -896,6 +900,24 @@ impl MediaSegment {
}
}
impl Default for MediaSegment {
fn default() -> Self {
Self {
uri: Default::default(),
duration: Default::default(),
title: Default::default(),
byte_range: Default::default(),
discontinuity: Default::default(),
key: Default::default(),
map: Default::default(),
program_date_time: Default::default(),
daterange: Default::default(),
unknown_tags: Default::default(),
float_precision: MediaSegment::DEFAULT_FLOAT_PRECISION,
}
}
}
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Clone)]
pub enum KeyMethod {
None,

View file

@ -198,6 +198,37 @@ fn create_and_parse_master_playlist_empty() {
assert_eq!(playlist_original, playlist_parsed);
}
#[test]
fn create_segment_float_inf() {
let mut playlist = MediaPlaylist {
version: Some(6),
target_duration: 3.0,
media_sequence: 338559,
discontinuity_sequence: 1234,
end_list: true,
playlist_type: Some(MediaPlaylistType::Vod),
segments: vec![MediaSegment {
uri: "20140311T113819-01-338559live.ts".into(),
duration: 2.000f32,
title: Some("title".into()),
..Default::default()
}],
..Default::default()
};
let mut v: Vec<u8> = Vec::new();
playlist.write_to(&mut v).unwrap();
let m3u8_str: &str = std::str::from_utf8(&v).unwrap();
assert!(m3u8_str.contains("#EXTINF:2.00000,title"));
playlist.segments[0].float_precision = 0;
playlist.write_to(&mut v).unwrap();
let m3u8_str: &str = std::str::from_utf8(&v).unwrap();
assert!(m3u8_str.contains("#EXTINF:2,title"));
}
#[test]
fn create_and_parse_master_playlist_full() {
let mut playlist_original = Playlist::MasterPlaylist(MasterPlaylist {
@ -382,6 +413,7 @@ fn create_and_parse_media_playlist_full() {
tag: "X-CUE-OUT".into(),
rest: Some("DURATION=2.002".into()),
}],
..Default::default()
}],
unknown_tags: vec![],
});