hlscmafsink: Add playlist-root-init property

Adding a property to allow setting base path for init fragment to be
written in manifest file

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1773>
This commit is contained in:
Seungha Yang 2024-09-10 23:51:59 +09:00
parent 1d20028b00
commit 1675e517b3
4 changed files with 32 additions and 5 deletions

View file

@ -2923,6 +2923,18 @@
"type": "gchararray", "type": "gchararray",
"writable": true "writable": true
}, },
"playlist-root-init": {
"blurb": "Base path for the init fragment in the playlist file.",
"conditionally-available": false,
"construct": false,
"construct-only": false,
"controllable": false,
"default": "NULL",
"mutable": "null",
"readable": true,
"type": "gchararray",
"writable": true
},
"playlist-type": { "playlist-type": {
"blurb": "The type of the playlist to use. When VOD type is set, the playlist will be live until the pipeline ends execution.", "blurb": "The type of the playlist to use. When VOD type is set, the playlist will be live until the pipeline ends execution.",
"conditionally-available": false, "conditionally-available": false,

View file

@ -352,7 +352,7 @@ impl HlsBaseSink {
Some((stream, location)) Some((stream, location))
} }
pub fn get_segment_uri(&self, location: &str) -> String { pub fn get_segment_uri(&self, location: &str, prefix: Option<&str>) -> String {
let settings = self.settings.lock().unwrap(); let settings = self.settings.lock().unwrap();
let file_name = path::Path::new(&location) let file_name = path::Path::new(&location)
.file_name() .file_name()
@ -360,7 +360,9 @@ impl HlsBaseSink {
.to_str() .to_str()
.unwrap(); .unwrap();
if let Some(playlist_root) = &settings.playlist_root { if let Some(prefix) = prefix {
format!("{prefix}/{file_name}")
} else if let Some(playlist_root) = &settings.playlist_root {
format!("{playlist_root}/{file_name}") format!("{playlist_root}/{file_name}")
} else { } else {
file_name.to_string() file_name.to_string()

View file

@ -50,6 +50,7 @@ struct HlsCmafSinkSettings {
playlist_type: Option<MediaPlaylistType>, playlist_type: Option<MediaPlaylistType>,
sync: bool, sync: bool,
latency: gst::ClockTime, latency: gst::ClockTime,
playlist_root_init: Option<String>,
cmafmux: gst::Element, cmafmux: gst::Element,
appsink: gst_app::AppSink, appsink: gst_app::AppSink,
@ -79,6 +80,7 @@ impl Default for HlsCmafSinkSettings {
playlist_type: None, playlist_type: None,
sync: DEFAULT_SYNC, sync: DEFAULT_SYNC,
latency: DEFAULT_LATENCY, latency: DEFAULT_LATENCY,
playlist_root_init: None,
cmafmux, cmafmux,
appsink, appsink,
} }
@ -145,6 +147,10 @@ impl ObjectImpl for HlsCmafSink {
.maximum(i64::MAX as u64) .maximum(i64::MAX as u64)
.default_value(DEFAULT_LATENCY.nseconds()) .default_value(DEFAULT_LATENCY.nseconds())
.build(), .build(),
glib::ParamSpecString::builder("playlist-root-init")
.nick("Playlist Root Init")
.blurb("Base path for the init fragment in the playlist file.")
.build(),
] ]
}); });
@ -187,6 +193,11 @@ impl ObjectImpl for HlsCmafSink {
settings.latency = value.get().expect("type checked upstream"); settings.latency = value.get().expect("type checked upstream");
settings.cmafmux.set_property("latency", settings.latency); settings.cmafmux.set_property("latency", settings.latency);
} }
"playlist-root-init" => {
settings.playlist_root_init = value
.get::<Option<String>>()
.expect("type checked upstream");
}
_ => unimplemented!(), _ => unimplemented!(),
}; };
} }
@ -203,6 +214,7 @@ impl ObjectImpl for HlsCmafSink {
} }
"sync" => settings.sync.to_value(), "sync" => settings.sync.to_value(),
"latency" => settings.latency.to_value(), "latency" => settings.latency.to_value(),
"playlist-root-init" => settings.playlist_root_init.to_value(),
_ => unimplemented!(), _ => unimplemented!(),
} }
} }
@ -419,7 +431,8 @@ impl HlsCmafSink {
.ok_or_else(|| String::from("Error while getting fragment stream"))? .ok_or_else(|| String::from("Error while getting fragment stream"))?
.into_write(); .into_write();
let uri = base_imp!(self).get_segment_uri(&location); let uri =
base_imp!(self).get_segment_uri(&location, settings.playlist_root_init.as_deref());
state.init_segment = Some(m3u8_rs::Map { state.init_segment = Some(m3u8_rs::Map {
uri, uri,
@ -450,7 +463,7 @@ impl HlsCmafSink {
running_time: Option<gst::ClockTime>, running_time: Option<gst::ClockTime>,
location: String, location: String,
) -> Result<gst::FlowSuccess, gst::FlowError> { ) -> Result<gst::FlowSuccess, gst::FlowError> {
let uri = base_imp!(self).get_segment_uri(&location); let uri = base_imp!(self).get_segment_uri(&location, None);
let mut state = self.state.lock().unwrap(); let mut state = self.state.lock().unwrap();
let map = if state.new_header { let map = if state.new_header {

View file

@ -582,7 +582,7 @@ impl HlsSink3 {
let obj = self.obj(); let obj = self.obj();
let base_imp = obj.upcast_ref::<HlsBaseSink>().imp(); let base_imp = obj.upcast_ref::<HlsBaseSink>().imp();
let uri = base_imp.get_segment_uri(&location); let uri = base_imp.get_segment_uri(&location, None);
let _ = base_imp.add_segment( let _ = base_imp.add_segment(
&location, &location,
running_time, running_time,