This repository has no description
0

Configure Feed

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

at main 3.4 kB View raw
1use crate::{ 2 Video, 3 ui::{Log, Pretty}, 4 video::{encoders::vgv::VGVTranscodeMode, engine::EngineOutput}, 5}; 6use anyhow::Result; 7use std::path::PathBuf; 8 9pub mod ffmpeg; 10pub mod vgv; 11 12pub trait Encoder { 13 fn name(&self) -> String; 14 fn encode_frames( 15 &mut self, 16 outputs: Vec<EngineOutput>, 17 ) -> Result<std::ops::ControlFlow<()>>; 18 fn finish(&mut self) -> Result<()>; 19 fn finish_message(&self, time_elapsed: std::time::Duration) -> String; 20 fn progress_message(&self, current: u64, total: u64) -> String { 21 format!("{}/{} frames", current, total,) 22 } 23} 24 25impl<C: Default> Video<C> { 26 pub(crate) fn setup_encoder( 27 &mut self, 28 output_path: impl Into<PathBuf>, 29 ) -> Result<Box<dyn Encoder + Send>> { 30 let (width, height) = 31 self.initial_canvas.resolution_to_size_even(self.resolution); 32 33 let destination = output_path.into(); 34 let pb = &self.progress_bars.encoding; 35 36 if destination.exists() { 37 std::fs::remove_file(&destination)?; 38 } 39 40 std::fs::create_dir_all( 41 &destination 42 .parent() 43 .expect("Given output file has no parent"), 44 )?; 45 46 Ok(match destination.full_extension() { 47 ".vgv.html" => { 48 self.progress_bars.encoding.log( 49 "Selecting", 50 &format!( 51 "VGV encoder with HTML transcoding as {} ends with .vgv.html", 52 destination.pretty(), 53 ), 54 ); 55 56 Box::new(self.setup_vgv_encoder( 57 VGVTranscodeMode::ToHTML, 58 width as _, 59 height as _, 60 &self.initial_canvas, 61 destination, 62 )?) 63 } 64 ".vgv" => { 65 self.progress_bars.encoding.log( 66 "Selecting", 67 &format!( 68 "VGV encoder as {} ends with .vgv (use .vgv.html for HTML transcoding)", 69 destination.pretty(), 70 ), 71 ); 72 73 Box::new(self.setup_vgv_encoder( 74 VGVTranscodeMode::None, 75 width as _, 76 height as _, 77 &self.initial_canvas, 78 destination, 79 )?) 80 } 81 _ => { 82 pb.log( 83 "Selecting", 84 &format!( 85 "FFMpeg encoder as {} ends with {}", 86 destination.pretty(), 87 destination.full_extension() 88 ), 89 ); 90 91 self.initial_canvas.load_fonts()?; 92 Box::new(self.setup_ffmpeg_encoder(width, height, destination)?) 93 } 94 }) 95 } 96} 97 98// Because .extension() sucks 99 100trait FullExtension { 101 fn full_extension(&self) -> &str; 102} 103 104impl FullExtension for PathBuf { 105 fn full_extension(&self) -> &str { 106 let filename = self 107 .file_name() 108 .and_then(|f| f.to_str()) 109 .unwrap_or_default(); 110 let parts: Vec<&str> = filename.split('.').collect(); 111 if parts.len() <= 1 { 112 "" 113 } else { 114 &filename[filename.find('.').unwrap()..] 115 } 116 } 117}