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:
parent
dd1a40abc9
commit
51b66d2adf
2 changed files with 44 additions and 85 deletions
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue