1
0
Fork 0
mirror of https://github.com/sile/hls_m3u8.git synced 2025-02-17 21:55:15 +00:00

added media_segment builder

This commit is contained in:
Luro02 2019-09-14 21:21:44 +02:00
parent dd1a40abc9
commit 51b66d2adf
2 changed files with 44 additions and 85 deletions

View file

@ -6,7 +6,7 @@ use std::time::Duration;
use derive_builder::Builder; use derive_builder::Builder;
use crate::line::{Line, Lines, Tag}; use crate::line::{Line, Lines, Tag};
use crate::media_segment::{MediaSegment, MediaSegmentBuilder}; use crate::media_segment::MediaSegment;
use crate::tags::{ use crate::tags::{
ExtM3u, ExtXDiscontinuitySequence, ExtXEndList, ExtXIFramesOnly, ExtXIndependentSegments, ExtM3u, ExtXDiscontinuitySequence, ExtXEndList, ExtXIFramesOnly, ExtXIndependentSegments,
ExtXMediaSequence, ExtXPlaylistType, ExtXStart, ExtXTargetDuration, ExtXVersion, ExtXMediaSequence, ExtXPlaylistType, ExtXStart, ExtXTargetDuration, ExtXVersion,
@ -314,7 +314,7 @@ fn parse_media_playlist(
input: &str, input: &str,
builder: &mut MediaPlaylistBuilder, builder: &mut MediaPlaylistBuilder,
) -> crate::Result<MediaPlaylist> { ) -> crate::Result<MediaPlaylist> {
let mut segment = MediaSegmentBuilder::new(); let mut segment = MediaSegment::builder();
let mut segments = vec![]; let mut segments = vec![];
let mut has_partial_segment = false; let mut has_partial_segment = false;
@ -336,32 +336,32 @@ fn parse_media_playlist(
} }
Tag::ExtInf(t) => { Tag::ExtInf(t) => {
has_partial_segment = true; has_partial_segment = true;
segment.tag(t); segment.inf_tag(t);
} }
Tag::ExtXByteRange(t) => { Tag::ExtXByteRange(t) => {
has_partial_segment = true; has_partial_segment = true;
segment.tag(t); segment.byte_range_tag(t);
} }
Tag::ExtXDiscontinuity(t) => { Tag::ExtXDiscontinuity(t) => {
has_discontinuity_tag = true; has_discontinuity_tag = true;
has_partial_segment = true; has_partial_segment = true;
segment.tag(t); segment.discontinuity_tag(t);
} }
Tag::ExtXKey(t) => { Tag::ExtXKey(t) => {
has_partial_segment = true; has_partial_segment = true;
segment.tag(t); segment.push_key_tag(t);
} }
Tag::ExtXMap(t) => { Tag::ExtXMap(t) => {
has_partial_segment = true; has_partial_segment = true;
segment.tag(t); segment.map_tag(t);
} }
Tag::ExtXProgramDateTime(t) => { Tag::ExtXProgramDateTime(t) => {
has_partial_segment = true; has_partial_segment = true;
segment.tag(t); segment.program_date_time_tag(t);
} }
Tag::ExtXDateRange(t) => { Tag::ExtXDateRange(t) => {
has_partial_segment = true; has_partial_segment = true;
segment.tag(t); segment.date_range_tag(t);
} }
Tag::ExtXTargetDuration(t) => { Tag::ExtXTargetDuration(t) => {
builder.target_duration_tag(t); builder.target_duration_tag(t);
@ -408,8 +408,8 @@ fn parse_media_playlist(
} }
Line::Uri(uri) => { Line::Uri(uri) => {
segment.uri(uri); segment.uri(uri);
segments.push(segment.finish()?); segments.push(segment.build().map_err(Error::builder_error)?);
segment = MediaSegmentBuilder::new(); segment = MediaSegment::builder();
has_partial_segment = false; has_partial_segment = false;
} }
} }

View file

@ -1,96 +1,51 @@
use std::fmt; use std::fmt;
use std::iter; use std::iter;
use derive_builder::Builder;
use crate::tags::{ use crate::tags::{
ExtInf, ExtXByteRange, ExtXDateRange, ExtXDiscontinuity, ExtXKey, ExtXMap, ExtXProgramDateTime, ExtInf, ExtXByteRange, ExtXDateRange, ExtXDiscontinuity, ExtXKey, ExtXMap, ExtXProgramDateTime,
MediaSegmentTag,
}; };
use crate::types::{ProtocolVersion, SingleLineString}; use crate::types::{ProtocolVersion, SingleLineString};
use crate::Error;
/// Media segment builder. /// Media segment.
#[derive(Debug, Clone)] #[derive(Debug, Clone, Builder)]
pub struct MediaSegmentBuilder { #[builder(setter(into, strip_option))]
pub struct MediaSegment {
#[builder(default)]
/// Sets all [ExtXKey] tags.
key_tags: Vec<ExtXKey>, key_tags: Vec<ExtXKey>,
#[builder(default)]
/// Sets an [ExtXMap] tag.
map_tag: Option<ExtXMap>, map_tag: Option<ExtXMap>,
#[builder(default)]
/// Sets an [ExtXByteRange] tag.
byte_range_tag: Option<ExtXByteRange>, byte_range_tag: Option<ExtXByteRange>,
#[builder(default)]
/// Sets an [ExtXDateRange] tag.
date_range_tag: Option<ExtXDateRange>, date_range_tag: Option<ExtXDateRange>,
#[builder(default)]
/// Sets an [ExtXDiscontinuity] tag.
discontinuity_tag: Option<ExtXDiscontinuity>, discontinuity_tag: Option<ExtXDiscontinuity>,
#[builder(default)]
/// Sets an [ExtXProgramDateTime] tag.
program_date_time_tag: Option<ExtXProgramDateTime>, program_date_time_tag: Option<ExtXProgramDateTime>,
inf_tag: Option<ExtInf>, /// Sets an [ExtInf] tag.
uri: Option<SingleLineString>, inf_tag: ExtInf,
/// Sets an Uri.
uri: SingleLineString,
} }
impl MediaSegmentBuilder { impl MediaSegmentBuilder {
/// Makes a new `MediaSegmentBuilder` instance. /// Pushes an [ExtXKey] tag.
pub fn new() -> Self { pub fn push_key_tag<VALUE: Into<ExtXKey>>(&mut self, value: VALUE) -> &mut Self {
MediaSegmentBuilder { if let Some(key_tags) = &mut self.key_tags {
key_tags: Vec::new(), key_tags.push(value.into());
map_tag: None, } else {
byte_range_tag: None, self.key_tags = Some(vec![value.into()]);
date_range_tag: None,
discontinuity_tag: None,
program_date_time_tag: None,
inf_tag: None,
uri: None,
}
}
/// Sets the URI of the resulting media segment.
pub fn uri(&mut self, uri: SingleLineString) -> &mut Self {
self.uri = Some(uri);
self
}
/// Sets the given tag to the resulting media segment.
pub fn tag<T: Into<MediaSegmentTag>>(&mut self, tag: T) -> &mut Self {
match tag.into() {
MediaSegmentTag::ExtInf(t) => self.inf_tag = Some(t),
MediaSegmentTag::ExtXByteRange(t) => self.byte_range_tag = Some(t),
MediaSegmentTag::ExtXDateRange(t) => self.date_range_tag = Some(t),
MediaSegmentTag::ExtXDiscontinuity(t) => self.discontinuity_tag = Some(t),
MediaSegmentTag::ExtXKey(t) => self.key_tags.push(t),
MediaSegmentTag::ExtXMap(t) => self.map_tag = Some(t),
MediaSegmentTag::ExtXProgramDateTime(t) => self.program_date_time_tag = Some(t),
} }
self self
} }
/// Builds a `MediaSegment` instance.
pub fn finish(self) -> crate::Result<MediaSegment> {
let uri = self.uri.ok_or(Error::missing_value("self.uri"))?;
let inf_tag = self.inf_tag.ok_or(Error::missing_value("self.inf_tag"))?;
Ok(MediaSegment {
key_tags: self.key_tags,
map_tag: self.map_tag,
byte_range_tag: self.byte_range_tag,
date_range_tag: self.date_range_tag,
discontinuity_tag: self.discontinuity_tag,
program_date_time_tag: self.program_date_time_tag,
inf_tag,
uri,
})
}
}
impl Default for MediaSegmentBuilder {
fn default() -> Self {
Self::new()
}
}
/// Media segment.
#[derive(Debug, Clone)]
pub struct MediaSegment {
key_tags: Vec<ExtXKey>,
map_tag: Option<ExtXMap>,
byte_range_tag: Option<ExtXByteRange>,
date_range_tag: Option<ExtXDateRange>,
discontinuity_tag: Option<ExtXDiscontinuity>,
program_date_time_tag: Option<ExtXProgramDateTime>,
inf_tag: ExtInf,
uri: SingleLineString,
} }
impl fmt::Display for MediaSegment { impl fmt::Display for MediaSegment {
@ -120,6 +75,10 @@ impl fmt::Display for MediaSegment {
} }
impl MediaSegment { impl MediaSegment {
/// Creates a [MediaSegmentBuilder].
pub fn builder() -> MediaSegmentBuilder {
MediaSegmentBuilder::default()
}
/// Returns the URI of the media segment. /// Returns the URI of the media segment.
pub const fn uri(&self) -> &SingleLineString { pub const fn uri(&self) -> &SingleLineString {
&self.uri &self.uri
@ -175,6 +134,6 @@ impl MediaSegment {
) )
.chain(iter::once(self.inf_tag.requires_version())) .chain(iter::once(self.inf_tag.requires_version()))
.max() .max()
.expect("Never fails") .unwrap_or(ProtocolVersion::V7)
} }
} }