1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
use std::error::Error;
use async_process::{Stdio, Child};
use crate::runtime;
use crate::socket::SocketPool;
use crate::types::ImageDigest;
pub fn default_image() -> ImageDigest {
ImageDigest::parse(
"docker.io/jrottenberg/ffmpeg:4.3.1-scratch38",
"68126e39534eff79a8a4a4b7b546a11b8165a1ee8f1af93166d3071b170280a1"
).unwrap()
}
#[derive(Clone, Debug)]
pub struct TranscodeConfig {
pub image: ImageDigest,
pub args: Vec<String>,
pub allow_networking: bool,
pub segment_time: f32,
}
pub async fn start(tc: TranscodeConfig, pool: &SocketPool) -> Result<Child, Box<dyn Error>> {
if !runtime::image_exists(&tc.image).await? {
runtime::pull(&tc.image).await?;
}
let mut command = runtime::command();
command
.arg("run")
.arg("--rm")
.arg("--attach=stdout")
.arg("--attach=stderr")
.arg("--env-host=false")
.arg("--read-only")
.arg("--restart=no")
.arg("--detach=false")
.arg("--privileged=false");
if tc.allow_networking {
command
.arg("--net=slirp4netns")
.arg("--dns-search=.");
} else {
command.arg("--net=none");
}
command
.args(&pool.mount_args)
.arg(tc.image.digest.as_str())
.args(tc.args);
command
.arg("-nostats")
.arg("-nostdin")
.arg("-loglevel").arg("error")
.arg("-f").arg("stream_segment")
.arg("-segment_format").arg("mpegts")
.arg("-segment_wrap").arg("1")
.arg("-segment_time").arg(tc.segment_time.to_string())
.arg("unix:///out/%d.ts");
log::info!("starting, {:?}", command);
Ok(command
.stdout(Stdio::inherit())
.stderr(Stdio::inherit())
.spawn()?)
}