extern crate sdl2_sys;
extern crate nihav_core;
extern crate nihav_registry;
-extern crate nihav_allstuff;
use std::fs::File;
use std::io::prelude::*;
use nihav_core::demuxers::*;
use nihav_core::soundcvt::*;
use nihav_registry::detect;
-use nihav_allstuff::*;
+mod allreg;
mod command;
use command::*;
}
}
+impl Drop for AudioDevice {
+ fn drop(&mut self) {
+ unsafe { sdl2_sys::SDL_CloseAudioDevice(self.device_id); }
+ }
+}
+
struct Decoder<'a> {
demuxer: Demuxer<'a>,
decoder: Box<dyn NADecoder>,
let s = ms / 1000;
let ds = (ms % 1000) / 100;
let (min, s) = (s / 60, s % 60);
- if min == 0 {
- format!("{}.{}", s, ds)
+ let (h, min) = (min / 60, min % 60);
+ if h == 0 {
+ if min == 0 {
+ format!("{}.{}", s, ds)
+ } else {
+ format!("{}:{:02}.{}", min, s, ds)
+ }
} else {
- format!("{}:{:02}.{}", min, s, ds)
+ format!("{}:{:02}:{:02}.{}", h, min, s, ds)
}
}
impl Player {
fn new() -> Self {
let mut dmx_reg = RegisteredDemuxers::new();
- nihav_register_all_demuxers(&mut dmx_reg);
+ allreg::register_all_demuxers(&mut dmx_reg);
let mut dec_reg = RegisteredDecoders::new();
- nihav_register_all_decoders(&mut dec_reg);
+ allreg::register_all_decoders(&mut dec_reg);
unsafe {
if sdl2_sys::SDL_Init(sdl2_sys::SDL_INIT_AUDIO) != 0 {
buf: Vec::new(),
}
}
- fn play_file(&mut self, name: &str, cmd_receiver: &mpsc::Receiver<Command>) {
+ fn play_file(&mut self, name: &str, cmd_receiver: &mpsc::Receiver<Command>, start_time: NATimePoint) {
let ret = File::open(name);
if ret.is_err() {
println!("error opening {}", name);
let ch = ainfo.channels;
println!("Playing {} [{}Hz {}ch]", name, arate, ch);
- let ret = AudioDevice::open(arate, ch.max(2));
+ let ret = AudioDevice::open(arate, ch.min(2));
if ret.is_none() {
println!("cannot open output");
return;
let mut refill_limit = arate * u32::from(dspec.channels);
let underfill_limit = (arate * u32::from(dspec.channels) / 4).max(block_limit);
+ if start_time != NATimePoint::None {
+ let _ret = decoder.demuxer.seek(start_time);
+ }
+
let mut eof = decoder.refill(&device);
while !eof && device.size() < refill_limit {
eof = decoder.refill(&device);
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) {
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;
Command::Debug => {
self.debug = !self.debug;
},
+ Command::PauseDisplay => {
+ no_display = true;
+ if !self.paused {
+ device.pause();
+ }
+ },
+ Command::ResumeDisplay => {
+ no_display = false;
+ if !self.paused {
+ device.resume();
+ }
+ },
};
- print!("\r{:60}\r", ' ');
+ if !no_display {
+ print!("\r{:60}\r", ' ');
+ }
}
thread::sleep(Duration::from_millis(200));
}
return;
}
- for arg in args[1..].iter() {
- player.play_file(arg, &cmd_receiver);
- if player.ended {
- break;
- }
+ let mut aiter = args[1..].iter();
+ let mut start_time = NATimePoint::None;
+ while let Some(arg) = aiter.next() {
+ match arg.as_str() {
+ "-start" => {
+ if let Some(arg) = aiter.next() {
+ if let Ok(val) = arg.parse() {
+ start_time = val;
+ } else {
+ println!("invalid time");
+ }
+ } else {
+ println!("argument is required");
+ }
+ },
+ _ => {
+ player.play_file(arg, &cmd_receiver, start_time);
+ if player.ended {
+ break;
+ }
+ start_time = NATimePoint::None;
+ },
+ };
}
cmd_state.restore();