aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJesse Luehrs <doy@tozt.net>2019-11-04 10:48:25 -0500
committerJesse Luehrs <doy@tozt.net>2019-11-04 10:48:25 -0500
commit736d401cf6a2b1f4d7f4261dad7c3b379f725df6 (patch)
tree5c6b87a7adc0d6f2cb6ade21973e7a98f9efbad4
parent7597ae2b4b646b8fd32113b75a53f3c7d925432b (diff)
downloadteleterm-736d401cf6a2b1f4d7f4261dad7c3b379f725df6.tar.gz
teleterm-736d401cf6a2b1f4d7f4261dad7c3b379f725df6.zip
allow adjusting the playback speed of ttyrecs
-rw-r--r--src/cmd/play.rs24
-rw-r--r--src/config.rs50
-rw-r--r--src/error.rs6
3 files changed, 75 insertions, 5 deletions
diff --git a/src/cmd/play.rs b/src/cmd/play.rs
index 6efcc74..8925701 100644
--- a/src/cmd/play.rs
+++ b/src/cmd/play.rs
@@ -5,6 +5,9 @@ use std::io::Write as _;
pub struct Config {
#[serde(default)]
ttyrec: crate::config::Ttyrec,
+
+ #[serde(default)]
+ play: crate::config::Play,
}
impl crate::config::Config for Config {
@@ -12,19 +15,26 @@ impl crate::config::Config for Config {
&mut self,
matches: &clap::ArgMatches<'a>,
) -> Result<()> {
- self.ttyrec.merge_args(matches)
+ self.ttyrec.merge_args(matches)?;
+ self.play.merge_args(matches)?;
+ Ok(())
}
fn run(
&self,
) -> Box<dyn futures::future::Future<Item = (), Error = Error> + Send>
{
- Box::new(PlaySession::new(&self.ttyrec.filename))
+ Box::new(PlaySession::new(
+ &self.ttyrec.filename,
+ self.play.playback_ratio,
+ ))
}
}
pub fn cmd<'a, 'b>(app: clap::App<'a, 'b>) -> clap::App<'a, 'b> {
- crate::config::Ttyrec::cmd(app.about("Play recorded terminal sessions"))
+ crate::config::Ttyrec::cmd(crate::config::Play::cmd(
+ app.about("Play recorded terminal sessions"),
+ ))
}
pub fn config(
@@ -60,10 +70,11 @@ struct PlaySession {
to_write: DumbDelayQueue<Vec<u8>>,
// to_write: tokio::timer::delay_queue::DelayQueue<Vec<u8>>,
base_time: std::time::Instant,
+ playback_ratio: f32,
}
impl PlaySession {
- fn new(filename: &str) -> Self {
+ fn new(filename: &str, playback_ratio: f32) -> Self {
Self {
file: FileState::Closed {
filename: filename.to_string(),
@@ -71,6 +82,7 @@ impl PlaySession {
to_write: DumbDelayQueue::new(),
// to_write: tokio::timer::delay_queue::DelayQueue::new(),
base_time: std::time::Instant::now(),
+ playback_ratio,
}
}
}
@@ -122,7 +134,9 @@ impl PlaySession {
{
self.to_write.insert_at(
frame.data,
- self.base_time + frame.time - reader.offset().unwrap(),
+ self.base_time
+ + (frame.time - reader.offset().unwrap())
+ .div_f32(self.playback_ratio),
);
} else {
self.file = FileState::Eof;
diff --git a/src/config.rs b/src/config.rs
index 6a9c2c0..85daf27 100644
--- a/src/config.rs
+++ b/src/config.rs
@@ -16,6 +16,7 @@ const FILENAME_OPTION: &str = "filename";
const LISTEN_ADDRESS_OPTION: &str = "listen-address";
const LOGIN_PLAIN_OPTION: &str = "login-plain";
const LOGIN_RECURSE_CENTER_OPTION: &str = "login-recurse-center";
+const PLAYBACK_RATIO_OPTION: &str = "playback-ratio";
const READ_TIMEOUT_OPTION: &str = "read-timeout-secs";
const TLS_IDENTITY_FILE_OPTION: &str = "tls-identity-file";
const TLS_OPTION: &str = "tls";
@@ -695,6 +696,55 @@ fn default_ttyrec_filename() -> String {
DEFAULT_TTYREC_FILENAME.to_string()
}
+#[derive(serde::Deserialize, Debug)]
+pub struct Play {
+ #[serde(default = "default_playback_ratio")]
+ pub playback_ratio: f32,
+}
+
+impl Play {
+ pub fn cmd<'a, 'b>(app: clap::App<'a, 'b>) -> clap::App<'a, 'b> {
+ let playback_ratio_help =
+ "Speed to play back the ttyrec at (defaults to 1.0)";
+ app.arg(
+ clap::Arg::with_name(PLAYBACK_RATIO_OPTION)
+ .long(PLAYBACK_RATIO_OPTION)
+ .takes_value(true)
+ .value_name("RATIO")
+ .help(playback_ratio_help),
+ )
+ }
+
+ pub fn merge_args<'a>(
+ &mut self,
+ matches: &clap::ArgMatches<'a>,
+ ) -> Result<()> {
+ if matches.is_present(PLAYBACK_RATIO_OPTION) {
+ self.playback_ratio = matches
+ .value_of(PLAYBACK_RATIO_OPTION)
+ .unwrap()
+ .to_string()
+ .parse()
+ .context(crate::error::ParseFloat {
+ name: PLAYBACK_RATIO_OPTION,
+ })?;
+ }
+ Ok(())
+ }
+}
+
+impl Default for Play {
+ fn default() -> Self {
+ Self {
+ playback_ratio: default_playback_ratio(),
+ }
+ }
+}
+
+fn default_playback_ratio() -> f32 {
+ 1.0
+}
+
pub fn oauth_configs<'a, D>(
deserializer: D,
) -> std::result::Result<
diff --git a/src/error.rs b/src/error.rs
index e6e4530..3c3d663 100644
--- a/src/error.rs
+++ b/src/error.rs
@@ -217,6 +217,12 @@ pub enum Error {
source: std::array::TryFromSliceError,
},
+ #[snafu(display("failed to parse float option {}: {}", name, source))]
+ ParseFloat {
+ name: String,
+ source: std::num::ParseFloatError,
+ },
+
#[snafu(display("failed to parse response json: {}", source))]
ParseJson { source: reqwest::Error },