Refactoring, improve code structure
This commit is contained in:
@@ -0,0 +1,86 @@
|
||||
use super::App;
|
||||
use crate::radio::station::StationInfo;
|
||||
use std::io;
|
||||
use tokio::process::Child;
|
||||
use tokio::sync::mpsc;
|
||||
|
||||
#[allow(clippy::type_complexity)]
|
||||
pub(super) struct SpawnFn(Box<dyn Fn(&str) -> io::Result<Child> + Send + Sync>);
|
||||
|
||||
impl std::fmt::Debug for SpawnFn {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
f.write_str("SpawnFn")
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) fn new_mpv_spawn() -> SpawnFn {
|
||||
SpawnFn(Box::new(mpv_spawn))
|
||||
}
|
||||
|
||||
fn mpv_spawn(url: &str) -> io::Result<Child> {
|
||||
tokio::process::Command::new("mpv")
|
||||
.arg(url)
|
||||
.arg("--no-video")
|
||||
.arg("--quiet")
|
||||
.arg("--term-playing-msg=${media-title}")
|
||||
.stdout(std::process::Stdio::piped())
|
||||
.stderr(std::process::Stdio::null())
|
||||
.spawn()
|
||||
}
|
||||
|
||||
impl App {
|
||||
pub(super) async fn play_station(&mut self, station: StationInfo) {
|
||||
if let Some(mut child) = self.player.take() {
|
||||
let _ = child.kill().await;
|
||||
}
|
||||
|
||||
self.error_message = None;
|
||||
self.current_song = None;
|
||||
self.current_station = Some(station.clone());
|
||||
|
||||
let Some(SpawnFn(ref spawn)) = self.spawn_player else {
|
||||
return;
|
||||
};
|
||||
|
||||
let (tx, rx) = mpsc::unbounded_channel();
|
||||
self.song_rx = Some(rx);
|
||||
|
||||
match spawn(&station.url) {
|
||||
Err(e) => {
|
||||
self.error_message = Some(format!("Failed to start mpv: {e}"));
|
||||
self.current_station = None;
|
||||
}
|
||||
Ok(mut child) => {
|
||||
let mut stdout = child.stdout.take().expect("mpv stdout");
|
||||
tokio::spawn(async move {
|
||||
use tokio::io::{AsyncBufReadExt, BufReader};
|
||||
let mut reader = BufReader::new(&mut stdout).lines();
|
||||
while let Ok(Some(line)) = reader.next_line().await {
|
||||
let title = line.trim().to_string();
|
||||
if !title.is_empty() {
|
||||
let _ = tx.send(title);
|
||||
}
|
||||
}
|
||||
});
|
||||
self.player = Some(child);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) async fn stop_playback(&mut self) {
|
||||
if let Some(mut child) = self.player.take() {
|
||||
let _ = child.kill().await;
|
||||
}
|
||||
self.current_station = None;
|
||||
self.current_song = None;
|
||||
self.song_rx = None;
|
||||
self.error_message = None;
|
||||
}
|
||||
|
||||
pub(super) async fn exit(&mut self) {
|
||||
if let Some(mut child) = self.player.take() {
|
||||
let _ = child.kill().await;
|
||||
}
|
||||
self.exit = true;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user