This repository has no description
0

Configure Feed

Select the types of activity you want to include in your feed.

1use crate::{ 2 synchronization::sync::{SyncData, Syncable}, 3 ui::MaybeProgressBar, 4}; 5use anyhow::{Result, anyhow}; 6use serde::Deserialize; 7use serde_aux::field_attributes::deserialize_number_from_string; 8use std::{collections::HashMap, io::Read, path::PathBuf, process::Stdio}; 9 10use super::sync::TimestampMS; 11 12pub struct CueMarkersSynchronizer { 13 pub path: PathBuf, 14} 15 16#[derive(Debug, Deserialize)] 17struct FFprobeChapterTags { 18 title: String, 19} 20 21#[derive(Debug, Deserialize)] 22struct FFprobeChapter { 23 // id: usize, 24 // time_base: String, 25 26 // start: usize, 27 #[serde(deserialize_with = "deserialize_number_from_string")] 28 start_time: f32, 29 30 // end: usize, 31 // #[serde(deserialize_with = "deserialize_number_from_string")] 32 // end_time: f32, 33 tags: FFprobeChapterTags, 34} 35 36#[derive(Debug, Deserialize)] 37struct FFprobeOutput { 38 chapters: Vec<FFprobeChapter>, 39} 40 41impl Syncable for CueMarkersSynchronizer { 42 fn new(path: impl Into<PathBuf>) -> Self { 43 Self { path: path.into() } 44 } 45 46 fn load( 47 &self, 48 progress: Option<&indicatif::ProgressBar>, 49 ) -> Result<SyncData> { 50 progress.set_length(4); 51 progress.set_message("Running ffprobe"); 52 53 let mut ffprobe = std::process::Command::new("ffprobe") 54 .args(["-v", "error"]) 55 .args(["-i", &self.path.to_string_lossy()]) 56 .args(["-output_format", "json"]) 57 .arg("-show_chapters") 58 .stdout(Stdio::piped()) 59 .spawn()?; 60 61 progress.inc(1); 62 progress.set_message("Getting ffprobe output"); 63 64 let mut raw_output = String::new(); 65 ffprobe 66 .stdout 67 .take() 68 .ok_or(anyhow!("Couldn't get stdout of ffprobe"))? 69 .read_to_string(&mut raw_output) 70 .map_err(|e| anyhow!("Couldn't read ffprobe stdout: {e:?}"))?; 71 72 progress.inc(1); 73 progress.set_message("Parsing ffprobe output"); 74 75 let output: FFprobeOutput = serde_json::from_str(&raw_output)?; 76 77 progress.inc(1); 78 progress.set_message("Gathering chapters"); 79 80 Ok(SyncData { 81 stems: HashMap::new(), 82 bpm: None, 83 markers: output 84 .chapters 85 .iter() 86 .map(|ch| { 87 ( 88 (ch.start_time.to_owned() * 1_000.0) as TimestampMS, 89 ch.tags.title.clone(), 90 ) 91 }) 92 .collect(), 93 }) 94 } 95}