Less error prone interstitial playback

This commit is contained in:
Jan-Henrik 2024-03-19 22:21:14 +01:00
parent 1d4c93b4da
commit b962a1882b
2 changed files with 53 additions and 39 deletions

View file

@ -28,6 +28,9 @@ struct Config {
#[envconfig(from = "SONG_PREFETCH", default = "2")] #[envconfig(from = "SONG_PREFETCH", default = "2")]
pub song_prefetch: u32, pub song_prefetch: u32,
#[envconfig(from = "INTERSTITIAL_PATH")]
pub interstitial_path: Option<String>,
} }
async fn get_time_file_map( async fn get_time_file_map(
@ -53,13 +56,11 @@ async fn get_time_file_map(
let hour = name_split let hour = name_split
.next() .next()
.ok_or(anyhow::anyhow!("No hour!"))? .ok_or(anyhow::anyhow!("No hour!"))?
.parse() .parse()?;
.unwrap();
let minute = name_split let minute = name_split
.next() .next()
.ok_or(anyhow::anyhow!("No minute!"))? .ok_or(anyhow::anyhow!("No minute!"))?
.parse() .parse()?;
.unwrap();
let time = chrono::NaiveTime::from_hms_opt(hour, minute, 0) let time = chrono::NaiveTime::from_hms_opt(hour, minute, 0)
.ok_or(anyhow::anyhow!("Can't parse time"))?; .ok_or(anyhow::anyhow!("Can't parse time"))?;
Ok::<_, anyhow::Error>((time, path)) Ok::<_, anyhow::Error>((time, path))
@ -149,8 +150,16 @@ async fn main() -> anyhow::Result<()> {
let mut time_announce_mixer_controller = mixer_controller.clone(); let mut time_announce_mixer_controller = mixer_controller.clone();
tokio::task::spawn(async move { tokio::task::spawn(async move {
let time_file_map = if config.interstitial_path.is_none() {
get_time_file_map(&std::path::PathBuf::from("./interstitials/time")).await; println!("No interstitials, skipping interstitial task. Specify a folder with INTERSTITIAL_PATH.");
return;
}
let mut time_file_path = std::path::PathBuf::from(config.interstitial_path.unwrap());
time_file_path.push("time");
println!("Looking for time files at {:?}", time_file_path);
let time_file_map = get_time_file_map(&time_file_path).await;
loop { loop {
tokio::task::yield_now().await; tokio::task::yield_now().await;
@ -196,31 +205,36 @@ async fn main() -> anyhow::Result<()> {
} }
.unwrap(); .unwrap();
println!("Next Internstitial time {}", interstitial_time); println!(
"Next Internstitial time {interstitial_time}: {:?}",
next_path
);
tokio::time::sleep_until( tokio::time::sleep_until(
tokio::time::Instant::now() + (interstitial_time - now).to_std().unwrap(), tokio::time::Instant::now() + (interstitial_time - now).to_std().unwrap(),
) )
.await; .await;
println!("Internstitial time {}", interstitial_time); println!("Playing interstitial {:?}", next_path);
for v in (fade_steps_min..=fade_steps_max).rev() { if let Ok(sound) = awedio::sounds::open_file(next_path.as_path()) {
let volume = v as f32 / fade_steps as f32; let (sound, completion_notifier) = sound.with_async_completion_notifier();
announce_downmix_player_controller.set_volume(volume); for v in (fade_steps_min..=fade_steps_max).rev() {
tokio::time::sleep(fade_duration / (fade_steps_max - fade_steps_min)).await; let volume = v as f32 / fade_steps as f32;
} announce_downmix_player_controller.set_volume(volume);
tokio::time::sleep(fade_duration / (fade_steps_max - fade_steps_min)).await;
}
let (sound, completion_notifier) = awedio::sounds::open_file(next_path.as_path()) time_announce_mixer_controller.add(Box::new(sound));
.unwrap() let _ = completion_notifier.await;
.with_async_completion_notifier();
time_announce_mixer_controller.add(Box::new(sound));
let _ = completion_notifier.await;
for v in fade_steps_min..=fade_steps_max { for v in fade_steps_min..=fade_steps_max {
let volume = v as f32 / fade_steps as f32; let volume = v as f32 / fade_steps as f32;
announce_downmix_player_controller.set_volume(volume); announce_downmix_player_controller.set_volume(volume);
tokio::time::sleep(fade_duration / (fade_steps_max - fade_steps_min)).await; tokio::time::sleep(fade_duration / (fade_steps_max - fade_steps_min)).await;
}
} else {
println!("Error playing interstitial");
} }
} }
} }

View file

@ -40,25 +40,25 @@ impl StreamerBackend {
)) ))
.map(move |_| { .map(move |_| {
let mut buffer = [0_i16; BUFFER_SIZE]; let mut buffer = [0_i16; BUFFER_SIZE];
renderer.on_start_of_batch(); renderer.on_start_of_batch();
tokio::task::block_in_place(|| { tokio::task::block_in_place(|| {
buffer.fill_with(|| { buffer.fill_with(|| {
let sample = renderer let sample = renderer
.next_sample() .next_sample()
.expect("renderer should never return an Error"); .expect("renderer should never return an Error");
let sample = match sample { let sample = match sample {
awedio::NextSample::Sample(s) => s, awedio::NextSample::Sample(s) => s,
awedio::NextSample::MetadataChanged => { awedio::NextSample::MetadataChanged => {
unreachable!("we never change metadata mid-batch") unreachable!("we never change metadata mid-batch")
} }
awedio::NextSample::Paused => 0, awedio::NextSample::Paused => 0,
awedio::NextSample::Finished => 0, awedio::NextSample::Finished => 0,
}; };
sample sample
});
}); });
Box::new(buffer)
}); });
Box::new(buffer)
});
loop { loop {
s.broadcast(stream.next().await.expect("Should not end!")) s.broadcast(stream.next().await.expect("Should not end!"))