1use std::fs;
2
3use futures::future::try_join_all;
4use models::{
5 hls_video::{HlsVideo, HlsVideoResolution},
6 hls_video_processing_settings::HlsVideoProcessingSettings,
7};
8use services::hls_video_processing_service::process_video_profile;
9use tempfile::TempDir;
10use tools::{hlskit_error::HlsKitError, m3u8_tools::generate_master_playlist};
11
12pub mod models;
13pub mod services;
14pub mod tools;
15
16pub async fn process_video(
17 input_bytes: Vec<u8>,
18 output_profiles: Vec<HlsVideoProcessingSettings>,
19) -> Result<HlsVideo, HlsKitError> {
20 let output_dir = TempDir::new()?.into_path();
21
22 println!("processing video at: {}", &output_dir.display());
23
24 let tasks: Vec<_> = output_profiles
25 .iter()
26 .enumerate()
27 .map(|(index, profile)| {
28 process_video_profile(
29 input_bytes.clone(),
30 profile.resolution,
31 profile.constant_rate_factor,
32 profile.preset.value(),
33 &output_dir,
34 index.try_into().unwrap(),
35 )
36 })
37 .collect();
38
39 let resolution_results: Vec<HlsVideoResolution> = try_join_all(tasks).await?;
40
41 let master_m3u8_data = generate_master_playlist(
42 &output_dir,
43 resolution_results
44 .iter()
45 .map(|result| result.resolution)
46 .collect(),
47 resolution_results
48 .iter()
49 .map(|result| result.playlist_name.as_str())
50 .collect(),
51 )
52 .await?;
53
54 let hls_video = HlsVideo {
55 master_m3u8_data,
56 resolutions: resolution_results,
57 };
58
59 fs::remove_dir_all(output_dir)?;
60
61 Ok(hls_video)
62}