summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKostya Shishkov <kostya.shishkov@gmail.com>2020-10-16 10:11:36 +0200
committerKostya Shishkov <kostya.shishkov@gmail.com>2020-10-16 10:11:36 +0200
commit0a727e0528c2b26c5cefb9bbf13f6b356e6fb3db (patch)
tree407028b430adf1c60bcc7066b4c69ad90b611c0d
parentb043bd0a14b04ddc4cf69b4701c2e1e6fe8e0111 (diff)
downloadnihav-player-0a727e0528c2b26c5cefb9bbf13f6b356e6fb3db.tar.gz
add a command to jump to an arbitrary time
-rw-r--r--sndplay/src/command.rs36
-rw-r--r--sndplay/src/main.rs31
2 files changed, 60 insertions, 7 deletions
diff --git a/sndplay/src/command.rs b/sndplay/src/command.rs
index 802908b..3f5ecde 100644
--- a/sndplay/src/command.rs
+++ b/sndplay/src/command.rs
@@ -1,7 +1,8 @@
use libc::{termios, tcgetattr, tcsetattr};
use std::sync::mpsc;
-use std::io::Read;
+use std::io::{Read, BufRead};
use std::thread;
+use nihav_core::frame::NATimePoint;
#[derive(Clone,Copy,Debug,PartialEq)]
pub enum Command {
@@ -12,8 +13,11 @@ pub enum Command {
Pause,
Back(u8),
Forward(u8),
+ Seek(u64),
Repeat,
Next,
+ PauseDisplay,
+ ResumeDisplay,
Quit,
}
@@ -29,6 +33,14 @@ impl CmdLineState {
unsafe { tcsetattr(0, 0, &new_state); }
Self { orig_state }
}
+ pub fn new_normal() -> Self {
+ let mut orig_state: termios = unsafe { std::mem::uninitialized() };
+ unsafe { tcgetattr(0, &mut orig_state); }
+ let mut new_state = orig_state;
+ new_state.c_lflag |= libc::ECHO | libc::ICANON;
+ unsafe { tcsetattr(0, 0, &new_state); }
+ Self { orig_state }
+ }
pub fn restore(&self) {
unsafe { tcsetattr(0, 0, &self.orig_state); }
}
@@ -60,6 +72,26 @@ pub fn start_reader() -> (thread::JoinHandle<()>, mpsc::Receiver<Command>) {
b'-' => { sender.send(Command::VolumeDown).unwrap(); },
b'd' | b'D' => { sender.send(Command::Debug).unwrap(); },
b'm' | b'M' => { sender.send(Command::Mute).unwrap(); },
+ b'j' | b'J' => {
+ sender.send(Command::PauseDisplay).unwrap();
+ let cstate = CmdLineState::new_normal();
+ // wait so that the main thread stops displaying
+ thread::sleep(std::time::Duration::from_millis(500));
+ print!("\nJump to: ");
+ let mut str = String::new();
+ let ret = file.read_line(&mut str);
+ cstate.restore();
+ sender.send(Command::ResumeDisplay).unwrap();
+
+ if ret.is_ok() && str.len() > 1 {
+ str.pop(); // newline
+ if let Ok(NATimePoint::Milliseconds(time)) = str.parse::<NATimePoint>() {
+ sender.send(Command::Seek(time)).unwrap();
+ } else {
+ println!("wrong time");
+ }
+ }
+ },
_ => {},
};
},
@@ -98,4 +130,4 @@ pub fn start_reader() -> (thread::JoinHandle<()>, mpsc::Receiver<Command>) {
}
}
}), cmd_receiver)
-} \ No newline at end of file
+}
diff --git a/sndplay/src/main.rs b/sndplay/src/main.rs
index 66def2b..377c2d1 100644
--- a/sndplay/src/main.rs
+++ b/sndplay/src/main.rs
@@ -335,15 +335,18 @@ impl Player {
if !self.paused {
device.resume();
}
+ let mut no_display = false;
'main: loop {
let cur_time = decoder.samplepos.saturating_sub(u64::from(device.size() / 2 / u32::from(dst_info.channels)));
let full_ms = cur_time * 1000 / u64::from(arate);
let timestr = format_time(full_ms);
let disp_vol = if self.mute { 0 } else { self.volume };
- if !self.debug {
- print!("> {} / {} {}% \r", timestr, duration_str, disp_vol);
- } else {
- print!("> {} / {} |{}| {}% \r", timestr, duration_str, device.size(), disp_vol);
+ if !no_display {
+ if !self.debug {
+ print!("> {} / {} {}% \r", timestr, duration_str, disp_vol);
+ } else {
+ print!("> {} / {} |{}| {}% \r", timestr, duration_str, device.size(), disp_vol);
+ }
}
std::io::stdout().flush().unwrap();
if device.size() < underfill_limit && !self.paused && refill_limit < (1 << 20) {
@@ -403,6 +406,20 @@ impl Player {
device.resume();
}
},
+ Command::Seek(seek_time) => {
+ device.pause();
+ device.clear();
+ let _ret = decoder.seek(seek_time);
+ while !eof && device.size() < refill_limit {
+ eof = decoder.refill(&device);
+ }
+ if eof {
+ break 'main;
+ }
+ if !self.paused {
+ device.resume();
+ }
+ },
Command::Quit => {
device.pause();
self.ended = true;
@@ -449,8 +466,12 @@ impl Player {
Command::Debug => {
self.debug = !self.debug;
},
+ Command::PauseDisplay => { no_display = true; },
+ Command::ResumeDisplay => { no_display = false; },
};
- print!("\r{:60}\r", ' ');
+ if !no_display {
+ print!("\r{:60}\r", ' ');
+ }
}
thread::sleep(Duration::from_millis(200));
}