1use crate::bindings::vtx::api::ffmpeg::{self, TranscodeParams};
4use crate::bindings::vtx::api::stream_io::Buffer;
5use crate::bindings::vtx::api::types::HttpResponse;
6use crate::error::{VtxError, VtxResult};
7
8pub struct FfmpegTask {
26 profile: String,
27 input_id: String,
28 args: Vec<String>,
29}
30
31impl FfmpegTask {
32 pub fn new(profile: impl Into<String>, input_id: impl Into<String>) -> Self {
38 Self {
39 profile: profile.into(),
40 input_id: input_id.into(),
41 args: Vec::new(),
42 }
43 }
44
45 pub fn new_pipe(profile: impl Into<String>) -> Self {
47 Self::new(profile, "pipe:0")
48 }
49
50 pub fn arg(mut self, arg: impl Into<String>) -> Self {
57 self.args.push(arg.into());
58 self
59 }
60
61 pub fn args<I, S>(mut self, args: I) -> Self
63 where
64 I: IntoIterator<Item = S>,
65 S: Into<String>,
66 {
67 for arg in args {
68 self.args.push(arg.into());
69 }
70 self
71 }
72
73 pub fn format(self, format: &str) -> Self {
76 self.arg("-f").arg(format)
77 }
78
79 pub fn seek(self, start: &str, duration: Option<&str>) -> Self {
82 let mut s = self.arg("-ss").arg(start);
83 if let Some(d) = duration {
84 s = s.arg("-t").arg(d);
85 }
86 s
87 }
88
89 pub fn execute_buffer(self) -> VtxResult<Buffer> {
93 let params = TranscodeParams {
94 profile: self.profile,
95 input_id: self.input_id,
96 args: self.args,
97 };
98
99 ffmpeg::execute(¶ms).map_err(VtxError::from_host_message)
100 }
101
102 pub fn execute(self) -> VtxResult<HttpResponse> {
107 let buffer = self.execute_buffer()?;
108 Ok(HttpResponse {
109 status: 200,
110 body: Some(buffer),
111 })
112 }
113}