183 lines
6.4 KiB
Rust
183 lines
6.4 KiB
Rust
use std::thread;
|
|
use std::time::Duration;
|
|
|
|
use anyhow::Result;
|
|
use flume::{Receiver, Sender};
|
|
use tracing::{error, warn};
|
|
|
|
use crate::decoder::MediaInfo;
|
|
use crate::player_engine::{PlayerEngine, PlayerEngineCommand, PlayerMessage};
|
|
|
|
// TODO:
|
|
// * Emit buffering
|
|
|
|
pub enum PlayerError {}
|
|
|
|
pub struct Player {
|
|
pub messages: Receiver<PlayerMessage>,
|
|
tx_engine: Sender<PlayerEngineCommand>,
|
|
}
|
|
|
|
impl Default for Player {
|
|
fn default() -> Self {
|
|
let (tx_engine, rx_engine) = flume::bounded(10);
|
|
let (tx_player, messages): (Sender<PlayerMessage>, Receiver<PlayerMessage>) =
|
|
flume::bounded(10);
|
|
|
|
let tx_decoder = tx_engine.clone();
|
|
|
|
thread::spawn(move || {
|
|
let mut player = match PlayerEngine::init(tx_decoder, tx_player) {
|
|
Err(e) => {
|
|
error!("Could not initialize player: {}", e);
|
|
return;
|
|
}
|
|
Ok(engine) => engine,
|
|
};
|
|
|
|
loop {
|
|
match rx_engine.recv() {
|
|
Ok(PlayerEngineCommand::Play(source_str, tx)) => {
|
|
tx.send(player.play(&source_str))
|
|
.unwrap_or_else(|e| warn!("Send error {}", e));
|
|
}
|
|
Ok(PlayerEngineCommand::Pause(tx)) => {
|
|
tx.send(player.pause())
|
|
.unwrap_or_else(|e| warn!("Send error {}", e));
|
|
}
|
|
Ok(PlayerEngineCommand::Unpause(tx)) => {
|
|
tx.send(player.unpause())
|
|
.unwrap_or_else(|e| warn!("Send error {}", e));
|
|
}
|
|
Ok(PlayerEngineCommand::Stop(tx)) => {
|
|
tx.send(player.stop())
|
|
.unwrap_or_else(|e| warn!("Send error {}", e));
|
|
}
|
|
Ok(PlayerEngineCommand::TogglePlay(tx)) => {
|
|
tx.send(player.toggle_play())
|
|
.unwrap_or_else(|e| warn!("Send error {}", e));
|
|
}
|
|
Ok(PlayerEngineCommand::Restart(tx)) => {
|
|
tx.send(player.restart())
|
|
.unwrap_or_else(|e| warn!("Send error {}", e));
|
|
}
|
|
Ok(PlayerEngineCommand::GetDuration(tx)) => {
|
|
tx.send(player.duration())
|
|
.unwrap_or_else(|e| warn!("Send error {}", e));
|
|
}
|
|
Ok(PlayerEngineCommand::GetElapsed(tx)) => {
|
|
tx.send(player.elapsed())
|
|
.unwrap_or_else(|e| warn!("Send error {}", e));
|
|
}
|
|
Ok(PlayerEngineCommand::SeekTo(time, tx)) => {
|
|
tx.send(player.seek_to(time))
|
|
.unwrap_or_else(|e| warn!("Send error {}", e));
|
|
}
|
|
Ok(PlayerEngineCommand::GetVolume(tx)) => {
|
|
tx.send(player.volume())
|
|
.unwrap_or_else(|e| warn!("Send error {}", e));
|
|
}
|
|
Ok(PlayerEngineCommand::GetPaused(tx)) => {
|
|
tx.send(player.is_paused())
|
|
.unwrap_or_else(|e| warn!("Send error {}", e));
|
|
}
|
|
Ok(PlayerEngineCommand::SetVolume(volume, tx)) => {
|
|
tx.send(player.set_volume(volume))
|
|
.unwrap_or_else(|e| warn!("Send error {}", e));
|
|
}
|
|
Ok(PlayerEngineCommand::SetElapsed(elapsed)) => {
|
|
player.handle_elapsed(elapsed);
|
|
}
|
|
Ok(PlayerEngineCommand::Eos) => {
|
|
player.handle_eos();
|
|
}
|
|
Err(e) => {
|
|
warn!("Recv error {}", e);
|
|
}
|
|
}
|
|
}
|
|
});
|
|
|
|
Self {
|
|
messages,
|
|
tx_engine,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl Player {
|
|
pub async fn play(&self, source_str: &str) -> Result<MediaInfo> {
|
|
let (tx, rx) = flume::bounded(1);
|
|
self.tx_engine
|
|
.send(PlayerEngineCommand::Play(source_str.to_string(), tx))?;
|
|
rx.recv_async().await?
|
|
}
|
|
|
|
pub async fn restart(&self) -> Result<MediaInfo> {
|
|
let (tx, rx) = flume::bounded(1);
|
|
self.tx_engine.send(PlayerEngineCommand::Restart(tx))?;
|
|
rx.recv_async().await?
|
|
}
|
|
|
|
pub async fn elpased(&self) -> Result<Duration> {
|
|
let (tx, rx) = flume::bounded(1);
|
|
self.tx_engine.send(PlayerEngineCommand::GetElapsed(tx))?;
|
|
rx.recv_async().await?
|
|
}
|
|
|
|
pub async fn duration(&self) -> Result<Duration> {
|
|
let (tx, rx) = flume::bounded(1);
|
|
self.tx_engine.send(PlayerEngineCommand::GetDuration(tx))?;
|
|
rx.recv_async().await?
|
|
}
|
|
|
|
pub async fn seek_to(&self, time: Duration) -> Result<Duration> {
|
|
let (tx, rx) = flume::bounded(1);
|
|
self.tx_engine.send(PlayerEngineCommand::SeekTo(time, tx))?;
|
|
rx.recv_async().await?
|
|
}
|
|
|
|
pub async fn volume(&self) -> Result<f32> {
|
|
let (tx, rx) = flume::bounded(1);
|
|
self.tx_engine.send(PlayerEngineCommand::GetVolume(tx))?;
|
|
Ok(rx.recv_async().await?)
|
|
}
|
|
|
|
pub async fn is_paused(&self) -> Result<bool> {
|
|
let (tx, rx) = flume::bounded(1);
|
|
self.tx_engine.send(PlayerEngineCommand::GetPaused(tx))?;
|
|
rx.recv_async().await?
|
|
}
|
|
|
|
pub async fn set_volume(&self, volume: f32) -> Result<f32> {
|
|
let (tx, rx) = flume::bounded(1);
|
|
self.tx_engine
|
|
.send(PlayerEngineCommand::SetVolume(volume, tx))?;
|
|
Ok(rx.recv_async().await?)
|
|
}
|
|
|
|
pub async fn pause(&self) -> Result<()> {
|
|
let (tx, rx) = flume::bounded(1);
|
|
self.tx_engine.send(PlayerEngineCommand::Pause(tx))?;
|
|
rx.recv_async().await?
|
|
}
|
|
|
|
pub async fn unpause(&self) -> Result<()> {
|
|
let (tx, rx) = flume::bounded(1);
|
|
self.tx_engine.send(PlayerEngineCommand::Unpause(tx))?;
|
|
rx.recv_async().await?
|
|
}
|
|
|
|
pub async fn toggle_play(&self) -> Result<bool> {
|
|
let (tx, rx) = flume::bounded(1);
|
|
self.tx_engine.send(PlayerEngineCommand::TogglePlay(tx))?;
|
|
rx.recv_async().await?
|
|
}
|
|
|
|
pub async fn stop(&self) -> Result<()> {
|
|
let (tx, rx) = flume::bounded(1);
|
|
self.tx_engine.send(PlayerEngineCommand::Stop(tx))?;
|
|
rx.recv_async().await?
|
|
}
|
|
}
|