emms-help
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH] emms-seek and emms-seek-to


From: Petteri Hintsanen
Subject: [PATCH] emms-seek and emms-seek-to
Date: Sat, 03 Sep 2022 15:10:42 +0300
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/28.1 (gnu/linux)

Hello Emms people,

While playing longer recordings I found out that emms seeking could be
improved.  So please find attached a patch that modifies emms-seek and
emms-seek-to functions to accept timestamps in addition to seconds (as
they do now).  Timespec format follows ffmpeg (see ffmpeg-utils(5) and
Time Duration there):

- Single number is interpreted as seconds to seek.  This is equivalent
  to the current behavior.

- Timestamp format is "hh:mm:ss" where hh part is optional.  It is
  either relative (emms-seek) or absolute (emms-seek-to).  Relative
  timestamp can be negative, e.g.:
  . "-1:14:22" means "seek 1 hour 14 minutes and 22 seconds backwards"
  .  "23:12.5" means "seek 23 minutes and 12.5 seconds forwards"

The implementation is lax: it does not do any error checking and relies
on string-to-number to handle nonsensical inputs (in which case
string-to-number returns zero).  So one can specify meaningless
timestamps like "1+:xz:-22" which is interpreted as "1:00:22" => 3622
seconds.  I'm not sure if this is what we want, but OTOH I think we
shouldn't be too strict either.

What do you think, does this make sense?

thanks,
Petteri

>From cf1222e8c106272109a681fd51dea45f5e3a1fca Mon Sep 17 00:00:00 2001
From: Petteri Hintsanen <petterih@iki.fi>
Date: Fri, 2 Sep 2022 16:48:59 +0300
Subject: [PATCH] dev

---
 emms.el | 53 +++++++++++++++++++++++++++++++++++++++++------------
 1 file changed, 41 insertions(+), 12 deletions(-)

diff --git a/emms.el b/emms.el
index fccecb9..e6b7783 100644
--- a/emms.el
+++ b/emms.el
@@ -455,21 +455,50 @@ If player hasn't started, then start it now."
       (emms-player-pause)
     (emms-start)))
 
-(defun emms-seek (seconds)
-  "Seek the current player SECONDS seconds.
-This can be a floating point number for sub-second fractions.
-It can also be negative to seek backwards."
-  (interactive "nSeconds to seek: ")
+(defun emms-seek (duration)
+  "Seek the current player by DURATION from its current position.
+DURATION can be:
+
+- A single number, in which case it is interpreted as seconds.
+
+- A string of form [-][HH:]MM:SS.m, where HH is hours, MM is
+  minutes, and SS is seconds.
+
+In both forms seconds can be a floating point number.  A negative
+value seeks backwards."
+  (interactive "sDuration to seek: ")
   (emms-ensure-player-playing-p)
-  (emms-player-seek seconds))
+  (emms-player-seek (emms-timespec-to-secs duration)))
 
-(defun emms-seek-to (seconds)
-  "Seek the current player to SECONDS seconds.
-This can be a floating point number for sub-second fractions.
-It can also be negative to seek backwards."
-  (interactive "nSeconds to seek to: ")
+(defun emms-seek-to (timestamp)
+  "Seek the current player to TIMESTAMP.
+TIMESTAMP can be:
+
+- A single number, in which case it is interpreted as seconds.
+
+- A string of form [HH:]MM:SS.m, where HH is hours, MM is
+  minutes, and SS is seconds.
+
+In both forms seconds can be a floating point number."
+  (interactive "sTimestamp to seek to: ")
   (emms-ensure-player-playing-p)
-  (emms-player-seek-to seconds))
+  (emms-player-seek-to (emms-timespec-to-secs timestamp t)))
+
+(defun emms-timespec-to-secs (timespec &optional absolute)
+  "TODO: docstring"
+  (let ((tokens (split-string timespec ":")))
+    (if (= (length tokens) 1)
+        ;; seconds only
+        (let ((secs (string-to-number (car tokens))))
+          (if absolute (abs secs) secs))
+      ;; HH:MM:SS
+      (let* ((sign (if (< (string-to-number (car tokens)) 0) -1 1))
+             (revtokens (reverse tokens))
+             (seconds (abs (string-to-number (or (pop revtokens) "0"))))
+             (minutes (abs (string-to-number (or (pop revtokens) "0"))))
+             (hours (abs (string-to-number (or (pop revtokens) "0"))))
+             (seekpos (* sign (+ (* 60 60 hours) (* 60 minutes) seconds))))
+        (if absolute (abs seekpos) seekpos)))))
 
 (defun emms-seek-forward ()
   "Seek ten seconds forward."
-- 
2.30.2


reply via email to

[Prev in Thread] Current Thread [Next in Thread]