diff options
| author | Felix Kaaman <tmtu@tmtu.ee> | 2020-02-21 23:24:55 +0200 |
|---|---|---|
| committer | Felix Kaaman <tmtu@tmtu.ee> | 2020-02-21 23:29:22 +0200 |
| commit | d9bfc97b599af4e4e96ae403df8287a533223e32 (patch) | |
| tree | fc2102295e2b3f0fd5db6f4d2ed811a6a0e87ffd /src/audio_player.rs | |
| parent | 8e708b65365aeb0591aee39d2ffb7c59239ffc3f (diff) | |
| download | pokebot-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.rs | 44 |
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 { |
