Add more player API methods
This commit is contained in:
parent
788ac6ba6d
commit
85d6d263e1
|
|
@ -179,6 +179,7 @@ dependencies = [
|
||||||
"rodio",
|
"rodio",
|
||||||
"stream-download",
|
"stream-download",
|
||||||
"symphonia",
|
"symphonia",
|
||||||
|
"thiserror",
|
||||||
"url",
|
"url",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -10,3 +10,4 @@ stream-download = { git = "https://github.com/aschey/stream-download-rs.git" }
|
||||||
anyhow = "1.0.71"
|
anyhow = "1.0.71"
|
||||||
url = "2.4.0"
|
url = "2.4.0"
|
||||||
flume = "0.10.14"
|
flume = "0.10.14"
|
||||||
|
thiserror = "1.0.40"
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,8 @@ use player_engine::{PlayerEngine, PlayerEngineCommand};
|
||||||
// * Emit buffering
|
// * Emit buffering
|
||||||
// * Emit errors
|
// * Emit errors
|
||||||
|
|
||||||
|
pub enum PlayerError {}
|
||||||
|
|
||||||
pub struct Player {
|
pub struct Player {
|
||||||
pub messages: Receiver<PlayerMessage>,
|
pub messages: Receiver<PlayerMessage>,
|
||||||
tx_engine: Sender<PlayerEngineCommand>,
|
tx_engine: Sender<PlayerEngineCommand>,
|
||||||
|
|
@ -32,8 +34,9 @@ impl Default for Player {
|
||||||
let mut player = PlayerEngine::new(tx_decoder, tx_player);
|
let mut player = PlayerEngine::new(tx_decoder, tx_player);
|
||||||
loop {
|
loop {
|
||||||
match rx_engine.recv() {
|
match rx_engine.recv() {
|
||||||
Ok(PlayerEngineCommand::Play(source_str)) => {
|
Ok(PlayerEngineCommand::Play(source_str, tx)) => {
|
||||||
player.play(&source_str);
|
let res = player.play(&source_str);
|
||||||
|
tx.send(res);
|
||||||
}
|
}
|
||||||
Ok(PlayerEngineCommand::Pause) => {
|
Ok(PlayerEngineCommand::Pause) => {
|
||||||
player.pause();
|
player.pause();
|
||||||
|
|
@ -67,9 +70,34 @@ impl Default for Player {
|
||||||
impl Player {
|
impl Player {
|
||||||
// FIXME: this could check if the player started playing using a channel
|
// FIXME: this could check if the player started playing using a channel
|
||||||
// Then it would be async (wait for Playing for example)
|
// Then it would be async (wait for Playing for example)
|
||||||
pub async fn play(&self, source_str: &str) -> Result<()> {
|
pub async fn play(&self, source_str: &str) -> Result<MediaInfo> {
|
||||||
|
let (tx, rx) = flume::bounded(1);
|
||||||
self.tx_engine
|
self.tx_engine
|
||||||
.send(PlayerEngineCommand::Play(source_str.to_string()));
|
.send(PlayerEngineCommand::Play(source_str.to_string(), tx));
|
||||||
|
if let Ok(res) = rx.recv_async().await {
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
// FIXME: add error type
|
||||||
|
Err(anyhow!("Player channel error"))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn elpased(&self) -> Duration {
|
||||||
|
// FIXME: implement
|
||||||
|
Duration::default()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn duration(&self) -> Duration {
|
||||||
|
// FIXME: implement
|
||||||
|
Duration::default()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn volume(&self) -> f32 {
|
||||||
|
// FIXME: implement
|
||||||
|
0.0
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn set_volume(&self) -> Result<()> {
|
||||||
|
// FIXME: implement
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -92,4 +120,9 @@ impl Player {
|
||||||
self.tx_engine.send(PlayerEngineCommand::Stop);
|
self.tx_engine.send(PlayerEngineCommand::Stop);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn restart(&self) -> Result<()> {
|
||||||
|
// FIXME: implement
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@ use symphonia::core::io::{
|
||||||
};
|
};
|
||||||
|
|
||||||
pub enum PlayerEngineCommand {
|
pub enum PlayerEngineCommand {
|
||||||
Play(String),
|
Play(String, Sender<Result<MediaInfo>>),
|
||||||
Pause,
|
Pause,
|
||||||
Unpause,
|
Unpause,
|
||||||
TogglePlay,
|
TogglePlay,
|
||||||
|
|
@ -56,26 +56,23 @@ impl PlayerEngine {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn play(&mut self, source_str: &str) -> Result<()> {
|
pub fn play(&mut self, source_str: &str) -> Result<MediaInfo> {
|
||||||
|
let tx_player = self.tx_player.clone();
|
||||||
|
|
||||||
let (stream, handle) = OutputStream::try_default()?;
|
let (stream, handle) = OutputStream::try_default()?;
|
||||||
let mut sink = Sink::try_new(&handle)?;
|
let mut sink = Sink::try_new(&handle)?;
|
||||||
let (source, hint) = self.get_source(source_str)?;
|
let (source, hint) = self.get_source(source_str)?;
|
||||||
let mss = MediaSourceStream::new(source, MediaSourceStreamOptions::default());
|
let mss = MediaSourceStream::new(source, MediaSourceStreamOptions::default());
|
||||||
|
|
||||||
let tx_player = self.tx_player.clone();
|
|
||||||
|
|
||||||
let decoder = SymphoniaDecoder::new(mss, hint, self.tx_engine.clone())?;
|
let decoder = SymphoniaDecoder::new(mss, hint, self.tx_engine.clone())?;
|
||||||
|
|
||||||
let media_info = decoder.media_info();
|
let media_info = decoder.media_info();
|
||||||
|
|
||||||
tx_player.send(PlayerMessage::Duration(
|
tx_player.send(PlayerMessage::Duration(
|
||||||
media_info.duration.unwrap_or_default(),
|
media_info.duration.unwrap_or_default(),
|
||||||
));
|
));
|
||||||
// tx_player.send(PlayerEngineMessage::MediaInfo(media_info));
|
|
||||||
|
|
||||||
let decoder = decoder.periodic_access(Duration::from_millis(250), move |src| {
|
let decoder = decoder.periodic_access(Duration::from_millis(250), move |src| {
|
||||||
tx_player.send(PlayerMessage::Elapsed(src.elapsed()));
|
tx_player.send(PlayerMessage::Elapsed(src.elapsed()));
|
||||||
});
|
});
|
||||||
|
|
||||||
sink.append(decoder);
|
sink.append(decoder);
|
||||||
|
|
||||||
// We need to keep the stream around, otherwise it gets dropped outside of this scope
|
// We need to keep the stream around, otherwise it gets dropped outside of this scope
|
||||||
|
|
@ -85,7 +82,7 @@ impl PlayerEngine {
|
||||||
|
|
||||||
self.tx_player.send(PlayerMessage::Playing);
|
self.tx_player.send(PlayerMessage::Playing);
|
||||||
|
|
||||||
Ok(())
|
Ok(media_info)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn pause(&mut self) {
|
pub fn pause(&mut self) {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue