aboutsummaryrefslogtreecommitdiffstats
path: root/src/audio_player.rs
diff options
context:
space:
mode:
authorFelix Kaaman <tmtu@tmtu.ee>2020-02-22 23:27:01 +0100
committerGitHub <noreply@github.com>2020-02-22 23:27:01 +0100
commit763b8c6579f3ae571f7287c72b9fb4f8b6e89349 (patch)
treebc55a0e79107a93bc3e605a0cae32926dc4c52fc /src/audio_player.rs
parent2792ba9c8a7120a91b3bd2c6075e737690e73405 (diff)
parent326cfa543c6263818aad7dec4a869bc8139ec14c (diff)
downloadpokebot-763b8c6579f3ae571f7287c72b9fb4f8b6e89349.tar.gz
pokebot-763b8c6579f3ae571f7287c72b9fb4f8b6e89349.zip
Merge pull request #33 from Mavulp/webserver
Webserver
Diffstat (limited to 'src/audio_player.rs')
-rw-r--r--src/audio_player.rs57
1 files changed, 48 insertions, 9 deletions
diff --git a/src/audio_player.rs b/src/audio_player.rs
index 9ed645d..d231c72 100644
--- a/src/audio_player.rs
+++ b/src/audio_player.rs
@@ -10,9 +10,11 @@ use gstreamer_audio::{StreamVolume, StreamVolumeFormat};
use crate::bot::{MusicBotMessage, State};
use glib::BoolError;
use log::{debug, error, info, warn};
-use std::sync::{Arc, Mutex};
+use std::sync::{Arc, RwLock};
use tokio02::sync::mpsc::UnboundedSender;
+use crate::youtube_dl::AudioMetadata;
+
static GST_INIT: Once = Once::new();
#[derive(Copy, Clone, Debug)]
@@ -33,8 +35,10 @@ pub struct AudioPlayer {
bus: gst::Bus,
http_src: gst::Element,
+ volume_f64: RwLock<f64>,
volume: gst::Element,
- sender: Arc<Mutex<UnboundedSender<MusicBotMessage>>>,
+ sender: Arc<RwLock<UnboundedSender<MusicBotMessage>>>,
+ currently_playing: RwLock<Option<AudioMetadata>>,
}
fn make_element(factoryname: &str, display_name: &str) -> Result<gst::Element, AudioPlayerError> {
@@ -83,7 +87,7 @@ fn add_decode_bin_new_pad_callback(
impl AudioPlayer {
pub fn new(
- sender: Arc<Mutex<UnboundedSender<MusicBotMessage>>>,
+ sender: Arc<RwLock<UnboundedSender<MusicBotMessage>>>,
callback: Option<Box<dyn FnMut(&[u8]) + Send>>,
) -> Result<Self, AudioPlayerError> {
GST_INIT.call_once(|| gst::init().unwrap());
@@ -104,6 +108,12 @@ impl AudioPlayer {
pipeline.add(&audio_bin)?;
+ // The documentation says that we have to make sure to handle
+ // all messages if auto flushing is deactivated.
+ // I hope our way of reading messages is good enough.
+ //
+ // https://gstreamer.freedesktop.org/documentation/gstreamer/gstpipeline.html#gst_pipeline_set_auto_flush_bus
+ pipeline.set_auto_flush_bus(false);
pipeline.set_state(gst::State::Ready)?;
Ok(AudioPlayer {
@@ -111,8 +121,10 @@ impl AudioPlayer {
bus,
http_src,
+ volume_f64: RwLock::new(0.0),
volume,
sender,
+ currently_playing: RwLock::new(None),
})
}
@@ -173,7 +185,16 @@ impl AudioPlayer {
Ok((audio_bin, volume, ghost_pad))
}
- pub fn set_source_url(&self, location: String) -> Result<(), AudioPlayerError> {
+ pub fn set_metadata(&self, data: AudioMetadata) -> Result<(), AudioPlayerError> {
+ self.set_source_url(data.url.clone())?;
+
+ let mut currently_playing = self.currently_playing.write().unwrap();
+ *currently_playing = Some(data);
+
+ Ok(())
+ }
+
+ fn set_source_url(&self, location: String) -> Result<(), AudioPlayerError> {
info!("Setting location URI: {}", location);
self.http_src.set_property("location", &location)?;
@@ -181,6 +202,7 @@ impl AudioPlayer {
}
pub fn set_volume(&self, volume: f64) -> Result<(), AudioPlayerError> {
+ *self.volume_f64.write().unwrap() = volume;
let db = 50.0 * volume.log10();
info!("Setting volume: {} -> {} dB", volume, db);
@@ -203,9 +225,26 @@ impl AudioPlayer {
}
}
+ pub fn volume(&self) -> f64 {
+ *self.volume_f64.read().unwrap()
+ }
+
+ pub fn position(&self) -> Option<Duration> {
+ self.pipeline
+ .query_position::<gst::ClockTime>()
+ .and_then(|t| t.0.map(|v| Duration::from_nanos(v)))
+ }
+
+ pub fn currently_playing(&self) -> Option<AudioMetadata> {
+ self.currently_playing.read().unwrap().clone()
+ }
+
pub fn reset(&self) -> Result<(), AudioPlayerError> {
info!("Setting pipeline state to null");
+ let mut currently_playing = self.currently_playing.write().unwrap();
+ *currently_playing = None;
+
self.pipeline.set_state(gst::State::Null)?;
Ok(())
@@ -273,20 +312,20 @@ impl AudioPlayer {
pub fn quit(&self, reason: String) {
info!("Quitting audio player");
- if let Err(e) = self
+ if let Err(_) = self
.bus
.post(&gst::Message::new_application(gst::Structure::new_empty("quit")).build())
{
- warn!("Failed to send \"quit\" app event: {}", e);
+ warn!("Tried to send \"quit\" app event on flushing bus.");
}
- let sender = self.sender.lock().unwrap();
+ let sender = self.sender.read().unwrap();
sender.send(MusicBotMessage::Quit(reason)).unwrap();
}
fn send_state(&self, state: State) {
info!("Sending state {:?} to application", state);
- let sender = self.sender.lock().unwrap();
+ let sender = self.sender.read().unwrap();
sender.send(MusicBotMessage::StateChange(state)).unwrap();
}
@@ -362,7 +401,7 @@ impl AudioPlayer {
}
}
_ => {
- //debug!("{:?}", msg)
+ //debug!("Unhandled message on bus: {:?}", msg)
}
};
}