use std::path::Path;
use crate::{
models::{
hls_video::HlsVideoResolution, hls_video_processing_settings::HlsVideoProcessingSettings,
},
tools::{
command_runner::run_command, gstreamer_command_builder::GStreamerCommandBuilder,
hlskit_error::HlsKitError, internals::hls_output_config::HlsOutputEncryptionConfig,
segment_tools::read_playlist_and_segments,
},
traits::video_processing_backend::VideoProcessingBackend,
VideoProcessorEncryptionSettings,
};
#[derive(Default)]
pub struct GStreamerBackend;
impl VideoProcessingBackend for GStreamerBackend {
async fn process_profile(
&self,
input: String,
profile: &HlsVideoProcessingSettings,
output_dir: &Path,
stream_index: i32,
encryption: Option<&VideoProcessorEncryptionSettings>,
) -> Result<HlsVideoResolution, HlsKitError> {
let (width, height) = profile.resolution;
let segment_filename = format!(
"{}/data_{}_%03d.ts",
output_dir.to_str().unwrap(),
stream_index
);
let playlist_filename = format!(
"{}/playlist_{}.m3u8",
output_dir.to_str().unwrap(),
stream_index
);
let encryption_settings = encryption.map(|enc| HlsOutputEncryptionConfig {
encryption_key_path: enc.encryption_key_path.clone(),
iv: enc.iv.clone(),
});
let encryption_key_url = encryption.map(|enc| enc.encryption_key_url.as_str());
let command = GStreamerCommandBuilder::new()
.input(&input)
.dimensions(width, height)
.bitrate(profile.constant_rate_factor)
.enable_hls(
&segment_filename,
None, encryption_key_url,
encryption_settings,
10, )
.output(&playlist_filename)
.build()?;
let gtreamer_pipeline: &Vec<String> = &command
.iter()
.flat_map(|arg| {
arg.split_whitespace()
.map(|s| s.to_string())
.collect::<Vec<_>>()
})
.collect();
run_command(gtreamer_pipeline).await?;
let resolution = read_playlist_and_segments(
&playlist_filename,
&segment_filename,
profile.resolution,
stream_index,
)?;
Ok(resolution)
}
}