mirror of
https://github.com/jhbruhn/jellyfin-radio.git
synced 2025-03-15 03:55:49 +00:00
Less error prone interstitial playback
This commit is contained in:
parent
1d4c93b4da
commit
b962a1882b
2 changed files with 53 additions and 39 deletions
58
src/main.rs
58
src/main.rs
|
@ -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");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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!"))
|
||||||
|
|
Loading…
Reference in a new issue