aboutsummaryrefslogtreecommitdiffstats
path: root/src/audio_player.rs
diff options
context:
space:
mode:
authorFelix Kaaman <tmtu@tmtu.ee>2020-02-21 23:24:55 +0200
committerFelix Kaaman <tmtu@tmtu.ee>2020-02-21 23:29:22 +0200
commitd9bfc97b599af4e4e96ae403df8287a533223e32 (patch)
treefc2102295e2b3f0fd5db6f4d2ed811a6a0e87ffd /src/audio_player.rs
parent8e708b65365aeb0591aee39d2ffb7c59239ffc3f (diff)
downloadpokebot-d9bfc97b599af4e4e96ae403df8287a533223e32.tar.gz
pokebot-d9bfc97b599af4e4e96ae403df8287a533223e32.zip
Add seeking to audio player
Adds a new "!seek" command which takes in a string that will be parsed by humantime in addition to a '+' or '-' character that can be prefixed to determine if it is a relative seek. Without any prefix characters the seek will be absolute.
Diffstat (limited to 'src/audio_player.rs')
-rw-r--r--src/audio_player.rs44
1 files changed, 44 insertions, 0 deletions
diff --git a/src/audio_player.rs b/src/audio_player.rs
index 97ecfbf..9ed645d 100644
--- a/src/audio_player.rs
+++ b/src/audio_player.rs
@@ -1,4 +1,5 @@
use std::sync::Once;
+use std::time::Duration;
use gst::prelude::*;
use gst::GhostPad;
@@ -14,6 +15,13 @@ use tokio02::sync::mpsc::UnboundedSender;
static GST_INIT: Once = Once::new();
+#[derive(Copy, Clone, Debug)]
+pub enum Seek {
+ Positive(Duration),
+ Negative(Duration),
+ Absolute(Duration),
+}
+
#[derive(PartialEq, Eq, Debug, Clone, Copy)]
pub enum PollResult {
Continue,
@@ -219,6 +227,41 @@ impl AudioPlayer {
Ok(())
}
+ pub fn seek(&self, seek: Seek) -> Result<humantime::FormattedDuration, AudioPlayerError> {
+ let base = match seek {
+ Seek::Positive(_) | Seek::Negative(_) => {
+ let pos = self
+ .pipeline
+ .query_position::<gst::ClockTime>()
+ .ok_or(AudioPlayerError::SeekError)?;
+ Duration::from_nanos(pos.nanoseconds().ok_or(AudioPlayerError::SeekError)?)
+ }
+ _ => Duration::new(0, 0),
+ };
+
+ let absolute = match seek {
+ Seek::Positive(duration) => base + duration,
+ Seek::Negative(duration) => {
+ if duration > base {
+ Duration::new(0, 0)
+ } else {
+ base - duration
+ }
+ }
+ Seek::Absolute(duration) => duration,
+ };
+
+ let time = humantime::format_duration(absolute);
+ info!("Seeking to {}", time);
+
+ self.pipeline.seek_simple(
+ gst::SeekFlags::FLUSH,
+ gst::ClockTime::from_nseconds(absolute.as_nanos() as _),
+ )?;
+
+ Ok(time)
+ }
+
pub fn stop_current(&self) -> Result<(), AudioPlayerError> {
info!("Stopping pipeline, sending EOS");
@@ -334,6 +377,7 @@ impl AudioPlayer {
pub enum AudioPlayerError {
GStreamerError(glib::error::BoolError),
StateChangeFailed,
+ SeekError,
}
impl From<glib::error::BoolError> for AudioPlayerError {