我想写一个Emacs命令来使用ffmpeg截取视频的一个片段。 命令如下:
ffmpeg -i 荡寇风云.God.of.War.2017.HD720P.X264.AAC.Mandarin.CHS.mp4 -ss 01:00:40 -t 00:07:00 -codec copy output.mp4
这其中 -t
这个时间戳是截取视频的长度。是计算截取点前后的两个时间点的差值。
我想问一下,Elisp下有什么函数或者包能够计算这个的么?
我想写一个Emacs命令来使用ffmpeg截取视频的一个片段。 命令如下:
ffmpeg -i 荡寇风云.God.of.War.2017.HD720P.X264.AAC.Mandarin.CHS.mp4 -ss 01:00:40 -t 00:07:00 -codec copy output.mp4
这其中 -t
这个时间戳是截取视频的长度。是计算截取点前后的两个时间点的差值。
我想问一下,Elisp下有什么函数或者包能够计算这个的么?
先转成unix时间戳再计算
之前在reddit上看到过这个问题,calc可以直接算
Elisp里面要怎么操作转换?Emacs里我搜索 unix.*time
只找到 calc-unix-time
.
Calc看到有命令似乎可以做时间减法,但是貌似不能操作这种只有时间戳的格式。而且也没有elisp函数。只有Calc里面的命令。可能是我没有发现找到。
自己计算一下好了,split-string
分割一下,然后 string-to-number
转化成数字,最后算一下就 OK 了。
方法是对 但不是函数式呀
可以用mapc 遍历每一个字符
遇到冒号就*60
楼下还有别的方法吗
在没有找到现成好用的函数方法前,自己先写一个将就吧。
(defun ffmpeg-subtract-timestamps (start-timestamp end-timestamp)
"Subtract END-TIMESTAMP with START-TIMESTAMP."
(let* ((start-t (mapcar 'string-to-number (split-string start-timestamp ":")))
(start-hour (car start-t))
(start-minute (cadr start-t))
(start-second (caddr start-t))
(end-t (mapcar 'string-to-number (split-string end-timestamp ":")))
(end-hour (car end-t))
(end-minute (cadr end-t))
(end-second (caddr end-t))
(subtract-t (list (- end-hour start-hour)
(- end-minute start-minute)
(- end-second start-second))))
(when (< (caddr subtract-t) 0)
(set 'subtract-t (list (car subtract-t)
(1- (cadr subtract-t))
(- (caddr subtract-t)))))
(when (< (cadr subtract-t) 0)
(set 'subtract-t (list (1- (car subtract-t))
(- (cadr subtract-t))
(caddr subtract-t))))
subtract-t))
(ffmpeg-subtract-timestamps "00:11:25" "00:12:12")
先分享下现在能用的代码方案。
(defun ffmpeg-subtract-timestamps (start-timestamp end-timestamp)
"Subtract END-TIMESTAMP with START-TIMESTAMP."
(let* ((start-t (mapcar 'string-to-number (split-string start-timestamp ":")))
(start-hour (car start-t))
(start-minute (cadr start-t))
(start-second (caddr start-t))
(end-t (mapcar 'string-to-number (split-string end-timestamp ":")))
(end-hour (car end-t))
(end-minute (cadr end-t))
(end-second (caddr end-t))
(subtract-t (list (- end-hour start-hour)
(- end-minute start-minute)
(- end-second start-second))))
(when (< (caddr subtract-t) 0)
(set 'subtract-t (list (car subtract-t)
(1- (cadr subtract-t))
(- (caddr subtract-t)))))
(when (< (cadr subtract-t) 0)
(set 'subtract-t (list (1- (car subtract-t))
(- (cadr subtract-t))
(caddr subtract-t))))
subtract-t))
;; (ffmpeg-subtract-timestamps "00:11:25" "00:12:12")
(defun ffmpeg-cut-clip (input-filename start-timestamp end-timestamp output-filename)
(interactive (list
(read-file-name "FFmpeg input filename: ")
(read-string "FFmpeg start timestamp: ")
(read-string "FFmpeg end timestamp: ")
(read-file-name "FFmpeg output filename: ")))
(make-process
:name "ffmpeg cut clip"
;; "ffmpeg -i input-filename -ss start-timestamp -t time-timestamp -codec copy output-filename"
:command (list "ffmpeg"
"-i" input-filename
"-ss" start-timestamp
"-t" (ffmpeg-subtract-timestamps start-timestamp end-timestamp)
"-codec copy"
output-filename)
:buffer "*ffmpeg-cut-clip*"
:sentinel (lambda (proc event)
(message "FFmpeg cut video clip finished."))))
-t 后面应该可以直接接秒的吧,我稍微改了一点点。
(defun ffmpeg-subtract-timestamps (start-timestamp end-timestamp)
"Subtract END-TIMESTAMP with START-TIMESTAMP."
(let ((start 0)
(end 0))
(dolist (time (mapcar #'string-to-number (split-string start-timestamp ":")))
(setq start (+ time (* start 60))))
(dolist (time (mapcar #'string-to-number (split-string end-timestamp ":")))
(setq end (+ time (* end 60))))
(- end start)))
还真是,可以直接秒。能接受三种格式
The following examples are all valid time duration:
55 55 seconds
12:03:45
12 hours, 03 minutes and 45 seconds
23.189
23.189 seconds
(ffmpeg-subtract-timestamps "00:11:25" "00:12:12")
(0 0 13)
没有通过测试呦
正确的结果是 (0 0 47)
绣 代码
(let( (sum 0) (acc 0) )
(mapc
(lambda (x)
(if (and (<= (- x ?0) 9) (>= (- x ?0) 0))
(setq acc (+ (* 10 acc)(- x ?0) ))
(setq sum (+ (* sum 60) acc)
acc 0)))
"00:02:34")
(setq sum (+ (* sum 60) acc))
sum)
(let ((time "") (num 154))
(dotimes ( i 2)
(setq time (concat (format ":%02d" (% num 60)) time)
num (/ num 60)))
(setq time (concat (format "%02d" num ) time))
time)
另一个实现吧,供参考,不过不支持毫秒
(defun ffmpeg-subtract-timestamps (start-timestamp end-timestamp)
"Subtract END-TIMESTAMP with START-TIMESTAMP."
(time-subtract
(encode-time (parse-time-string
(concat "2020-01-01T" end-timestamp)))
(encode-time (parse-time-string
(concat "2020-01-01T" start-timestamp)))))
这个实现看起来比较简介直观。就这个了。
看不懂代码。。。。我还是太菜了