Add VideoStreamManager for keeping track of active streams

The stream manager should help prevent zombie processes and can later be
used for stopping video streams if the user exits the video before
finishing for example.
This commit is contained in:
Cameron Cordes
2021-02-09 21:30:27 -05:00
parent e4c23c0fe5
commit b595bdd642
3 changed files with 85 additions and 28 deletions

View File

@@ -1,13 +1,43 @@
use std::collections::HashMap;
use std::io::Result;
use std::path::Path;
use std::process::Command;
use std::process::{Child, Command, Stdio};
// ffmpeg -i test.mp4 -c:v h264 -flags +cgop -g 30 -hls_time 3 out.m3u8
// ffmpeg -i "filename.mp4" -preset veryfast -c:v libx264 -f hls -hls_list_size 100 -hls_time 2 -crf 24 -vf scale=1080:-2,setsar=1:1 attempt/vid_out.m3u8
pub fn create_playlist(video_path: &str, playlist_file: &str) {
pub(crate) struct VideoStreamManager {
streams: HashMap<String, Child>,
}
impl VideoStreamManager {
pub(crate) fn new() -> VideoStreamManager {
VideoStreamManager {
streams: HashMap::new(),
}
}
pub fn track_stream(&mut self, playlist_path: &dyn ToString, child_process: Child) {
println!("Tracking process for: {:?}", playlist_path.to_string());
self.streams
.insert(playlist_path.to_string(), child_process);
}
pub fn check_for_finished_streams(&mut self) {
self.streams.retain(|playlist_path, process| {
let is_done = process.try_wait().map_or(false, |status| status.is_some());
if is_done {
println!("Removing process: {:?}", playlist_path)
}
!is_done
});
}
}
pub fn create_playlist(video_path: &str, playlist_file: &str) -> Result<Child> {
if Path::new(playlist_file).exists() {
println!("Playlist already exists: {}", playlist_file);
return;
return Err(std::io::Error::from(std::io::ErrorKind::AlreadyExists));
}
let result = Command::new("ffmpeg")
@@ -26,16 +56,22 @@ pub fn create_playlist(video_path: &str, playlist_file: &str) {
.arg("-vf")
.arg("scale=1080:-2,setsar=1:1")
.arg(playlist_file)
.stdout(Stdio::null())
.stderr(Stdio::null())
.spawn();
let start_time = std::time::Instant::now();
loop {
std::thread::sleep(std::time::Duration::from_secs(1));
if Path::new(playlist_file).exists() || std::time::Instant::now() - start_time > std::time::Duration::from_secs(5) {
if Path::new(playlist_file).exists()
|| std::time::Instant::now() - start_time > std::time::Duration::from_secs(5)
{
break;
}
}
result
}
pub fn generate_video_thumbnail(path: &Path, destination: &Path) {