native_whisperx/workflow/
progress.rs1use std::path::PathBuf;
4use std::sync::{
5 atomic::{AtomicBool, Ordering},
6 Arc,
7};
8
9use crate::config::NativeWhisperxReport;
10use crate::translation::{CuratedLanguage, TranslationPlanProvenance};
11
12#[derive(Debug, Clone, Default)]
18pub struct CancellationHandle {
19 requested: Arc<AtomicBool>,
20}
21
22impl CancellationHandle {
23 pub fn new() -> Self {
25 Self::default()
26 }
27
28 pub fn cancel(&self) {
30 self.requested.store(true, Ordering::Release);
31 }
32
33 pub fn is_cancelled(&self) -> bool {
35 self.requested.load(Ordering::Acquire)
36 }
37}
38
39#[derive(Debug, Clone, Copy, PartialEq, Eq)]
40pub enum TranscriptionProgressTask {
41 Decode,
42 Vad,
43 Asr,
44 Alignment,
45 Diarization,
46 Translation,
47 Output,
48}
49
50#[derive(Debug, Clone, PartialEq, Eq)]
52pub struct FiniteCancellation {
53 file_index: usize,
54 input: PathBuf,
55 task: Option<TranscriptionProgressTask>,
56}
57
58impl FiniteCancellation {
59 pub(crate) fn new(
60 file_index: usize,
61 input: PathBuf,
62 task: Option<TranscriptionProgressTask>,
63 ) -> Self {
64 Self {
65 file_index,
66 input,
67 task,
68 }
69 }
70
71 pub const fn file_index(&self) -> usize {
73 self.file_index
74 }
75
76 pub fn input(&self) -> &std::path::Path {
78 &self.input
79 }
80
81 pub const fn task(&self) -> Option<TranscriptionProgressTask> {
83 self.task
84 }
85}
86
87#[derive(Debug)]
89pub enum FiniteTranscriptionOutcome {
90 Completed(Box<NativeWhisperxReport>),
92 Cancelled(FiniteCancellation),
94}
95
96#[derive(Debug, Clone, PartialEq, Eq)]
98pub struct UnfinishedTranscription {
99 file_index: usize,
100 input: PathBuf,
101}
102
103impl UnfinishedTranscription {
104 pub(crate) fn new(file_index: usize, input: PathBuf) -> Self {
105 Self { file_index, input }
106 }
107
108 pub const fn file_index(&self) -> usize {
110 self.file_index
111 }
112
113 pub fn input(&self) -> &std::path::Path {
115 &self.input
116 }
117}
118
119#[derive(Debug)]
121pub enum MultiInputTranscriptionOutcome {
122 Completed(Vec<NativeWhisperxReport>),
124 Cancelled {
126 completed: Vec<NativeWhisperxReport>,
127 cancellation: FiniteCancellation,
128 unfinished: Vec<UnfinishedTranscription>,
129 },
130}
131
132#[non_exhaustive]
138#[derive(Debug, Clone, PartialEq)]
139pub enum TranscriptionProgressEvent {
140 RunStart {
141 total_files: usize,
142 },
143 RunEnd {
144 total_files: usize,
145 duration_seconds: f64,
146 },
147 FileStart {
148 file_index: usize,
149 total_files: usize,
150 input: PathBuf,
151 },
152 FileEnd {
153 file_index: usize,
154 total_files: usize,
155 input: PathBuf,
156 duration_seconds: f64,
157 },
158 TaskStart {
159 file_index: usize,
160 task: TranscriptionProgressTask,
161 },
162 TaskEnd {
163 file_index: usize,
164 task: TranscriptionProgressTask,
165 duration_seconds: f64,
166 },
167 ModelResolutionStart {
168 file_index: usize,
169 task: TranscriptionProgressTask,
170 provider: String,
171 model_id: String,
172 },
173 ModelResolutionEnd {
174 file_index: usize,
175 task: TranscriptionProgressTask,
176 provider: String,
177 model_id: String,
178 source: String,
179 },
180 ModelDownloadStart {
181 file_index: usize,
182 task: TranscriptionProgressTask,
183 provider: String,
184 model_id: String,
185 },
186 ModelDownloadEnd {
187 file_index: usize,
188 task: TranscriptionProgressTask,
189 provider: String,
190 model_id: String,
191 duration_seconds: f64,
192 },
193 ModelLoadStart {
194 file_index: usize,
195 task: TranscriptionProgressTask,
196 provider: String,
197 model_id: String,
198 },
199 ModelLoadEnd {
200 file_index: usize,
201 task: TranscriptionProgressTask,
202 provider: String,
203 model_id: String,
204 duration_seconds: f64,
205 },
206 ModelReuse {
207 file_index: usize,
208 task: TranscriptionProgressTask,
209 provider: String,
210 model_id: String,
211 },
212 TranslationLegStart {
213 file_index: usize,
214 leg_index: usize,
215 total_legs: usize,
216 provenance: TranslationPlanProvenance,
217 source: CuratedLanguage,
218 target: CuratedLanguage,
219 provider: String,
220 model_id: String,
221 },
222 TranslationLegEnd {
223 file_index: usize,
224 leg_index: usize,
225 total_legs: usize,
226 provenance: TranslationPlanProvenance,
227 source: CuratedLanguage,
228 target: CuratedLanguage,
229 provider: String,
230 model_id: String,
231 duration_seconds: f64,
232 },
233 Failure {
234 file_index: usize,
235 input: PathBuf,
236 task: Option<TranscriptionProgressTask>,
237 duration_seconds: f64,
238 message: String,
239 },
240 Cancelled {
241 file_index: usize,
242 input: PathBuf,
243 task: Option<TranscriptionProgressTask>,
244 duration_seconds: f64,
245 },
246}
247
248pub trait TranscriptionProgressObserver {
249 fn observe(&mut self, event: TranscriptionProgressEvent);
250}
251
252#[derive(Debug, Default)]
253pub struct NoopTranscriptionProgressObserver;
254
255impl TranscriptionProgressObserver for NoopTranscriptionProgressObserver {
256 fn observe(&mut self, _event: TranscriptionProgressEvent) {}
257}
258
259#[derive(Debug, Default)]
260pub(crate) struct ProgressTaskTracker {
261 current: Option<TranscriptionProgressTask>,
262}
263
264impl ProgressTaskTracker {
265 pub(crate) fn set_current(&mut self, task: Option<TranscriptionProgressTask>) {
266 self.current = task;
267 }
268
269 pub(crate) fn current(&self) -> Option<TranscriptionProgressTask> {
270 self.current
271 }
272}
273
274pub(crate) struct NativeProgressContext<'a> {
275 pub(crate) observer: &'a mut dyn TranscriptionProgressObserver,
276 pub(crate) file_index: usize,
277 pub(crate) task_tracker: &'a mut ProgressTaskTracker,
278 pub(crate) cancellation: &'a CancellationHandle,
279}