1use crate::bindings::vtx::api::ffmpeg::{self, TranscodeParams};
2use crate::bindings::vtx::api::stream_io::Buffer;
3use crate::bindings::vtx::api::types::HttpResponse;
4use crate::error::{VtxError, VtxResult};
5
6pub struct FfmpegTask {
24 profile: String,
25 input_id: String,
26 args: Vec<String>,
27}
28
29impl FfmpegTask {
30 pub fn new(profile: impl Into<String>, input_id: impl Into<String>) -> Self {
36 Self {
37 profile: profile.into(),
38 input_id: input_id.into(),
39 args: Vec::new(),
40 }
41 }
42
43 pub fn new_pipe(profile: impl Into<String>) -> Self {
45 Self::new(profile, "pipe:0")
46 }
47
48 pub fn arg(mut self, arg: impl Into<String>) -> Self {
55 self.args.push(arg.into());
56 self
57 }
58
59 pub fn args<I, S>(mut self, args: I) -> Self
61 where
62 I: IntoIterator<Item = S>,
63 S: Into<String>,
64 {
65 for arg in args {
66 self.args.push(arg.into());
67 }
68 self
69 }
70
71 pub fn format(self, format: &str) -> Self {
74 self.arg("-f").arg(format)
75 }
76
77 pub fn seek(self, start: &str, duration: Option<&str>) -> Self {
80 let mut s = self.arg("-ss").arg(start);
81 if let Some(d) = duration {
82 s = s.arg("-t").arg(d);
83 }
84 s
85 }
86
87 pub fn execute_buffer(self) -> VtxResult<Buffer> {
91 let params = TranscodeParams {
92 profile: self.profile,
93 input_id: self.input_id,
94 args: self.args,
95 };
96
97 ffmpeg::execute(¶ms).map_err(VtxError::from_host_message)
98 }
99
100 pub fn execute(self) -> VtxResult<HttpResponse> {
105 let buffer = self.execute_buffer()?;
106 Ok(HttpResponse {
107 status: 200,
108 body: Some(buffer),
109 })
110 }
111}