summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--emacsconf-extract.el173
1 files changed, 173 insertions, 0 deletions
diff --git a/emacsconf-extract.el b/emacsconf-extract.el
index bdd5b75..77c8d0b 100644
--- a/emacsconf-extract.el
+++ b/emacsconf-extract.el
@@ -96,6 +96,179 @@
'("webcams.webm" "metadata.xml" "deskshare.webm" "deskshare.xml" "slides_new.xml" "webcams.opus"))))
(emacsconf-prepare-for-display (emacsconf-get-talk-info))))
+(defvar emacsconf-extract-dump-dir "/ssh:orga@res.emacsconf.org#46668:~/current/live0-streams/")
+(defun emacsconf-extract-dump-time-from-filename (f)
+ (when (string-match "\\([0-9][0-9][0-9][0-9]\\)-\\([0-9][0-9]\\)-\\([0-9][0-9]\\)_\\([0-9][0-9]\\)-\\([0-9][0-9]\\)-\\([0-9][0-9]\\)" f)
+ (encode-time
+ (append
+ (mapcar (lambda (i) (string-to-number (match-string i f))) (number-sequence 6 1 -1))
+ (list nil nil "UTC")))))
+(defun emacsconf-extract-dump-filename (directory input-prefix start-time)
+ (seq-find
+ (lambda (f) (time-less-p (emacsconf-extract-dump-time-from-filename f) start-time))
+ (nreverse (sort (directory-files (or directory emacsconf-extract-dump-dir)
+ nil (concat emacsconf-id "-" emacsconf-year "-"
+ input-prefix ".*\\.webm$"))
+ 'string<))))
+
+;; (emacsconf-extract-dump-filename emacsconf-extract-dump-dir "dev" (emacsconf-extract-time-or-offset-to-time "2022-12-04 11:30"))
+;; emacsconf-2021-main_2021-11-20_15-31-16.webm hmm, this might be GMT
+(defun emacsconf-extract-dump-ffmpeg-command (input-file start-time end-time output-file &optional compress-command)
+ (when (stringp start-time) (setq start-time (emacsconf-extract-time-or-offset-to-time start-time)))
+ (when (stringp end-time) (setq end-time (emacsconf-extract-time-or-offset-to-time end-time)))
+ (let* ((target-file-start (emacsconf-extract-dump-time-from-filename input-file))
+ (dump-args (emacsconf-extract-dump-ffmpeg-seek-and-filename
+ input-file
+ (- (time-to-seconds start-time)
+ (time-to-seconds target-file-start))
+ (- (time-to-seconds end-time)
+ (time-to-seconds target-file-start)))))
+ (if compress-command
+ (format "ffmpeg -y %s -c copy %s; %s %s &"
+ dump-args
+ output-file
+ compress-command
+ output-file)
+ (format "ffmpeg -y %s -c copy %s"
+ dump-args
+ output-file))))
+;; (emacsconf-extract-dump-ffmpeg-command (emacsconf-extract-dump-filename emacsconf-extract-dump-dir "dev" (emacsconf-extract-time-or-offset-to-time "2022-12-04T11:30:00")) "2022-12-04T11:30:00" "2022-12-04T13:00:00" "rms.webm")
+
+;; output-prefix
+;; (format-time-string "%Y-%m-%d_%H-%M-%S" start-time t)
+(defun emacsconf-extract-dump-get-command (input-prefix start-time end-time filename)
+ (interactive)
+ (setq start-time (emacsconf-extract-time-or-offset-to-time start-time))
+ (setq end-time (emacsconf-extract-time-or-offset-to-time end-time))
+ (format "ssh conf -- %s; scp conf:~/emacsconf-2021-stream-dumps/%s %s"
+ (shell-quote-argument
+ (format "cd %s; sudo %s"
+ "~/emacsconf-2021-stream-dumps/"
+ (emacsconf-extract-dump-ffmpeg-command
+ (emacsconf-extract-dump-filename emacsconf-extract-dump-dir input-prefix start-time)
+ start-time end-time
+ (concat "output/" filename))))
+ (concat "output/" filename)
+ filename))
+
+;; todo timezones
+(defun emacsconf-extract-time-or-offset-to-time (input)
+ (cond ((numberp input)
+ (seconds-to-time (+ (time-to-seconds (current-time))
+ (* input 60))))
+ ((listp input) input)
+ ((stringp input) (date-to-time (if (string-match "[-Z+]" input) input (concat input emacsconf-timezone-offset))))
+ ((string-match " " input)
+ (org-read-date t t input))
+ (t (seconds-to-time (+ (time-to-seconds (current-time))
+ (* (string-to-number input) 60))))))
+
+(defun emacsconf-extract-dump-ffmpeg-seek-and-filename (filename start-seconds to-seconds)
+ "Return seek and input file argument."
+ (if (> start-seconds 30)
+ (format "-ss %f -i %s -ss %f -to %f" (- start-seconds 30) filename 30 (- to-seconds start-seconds -30))
+ (format "-i %s -ss %f -to %f" filename start-seconds to-seconds)))
+
+(defun emacsconf-extract-dump-get (track start-time end-time output-prefix)
+ (interactive (list (emacsconf-complete-track)
+ (read-string "Start: ")
+ (read-string "End: ")
+ (read-string "Output prefix: ")))
+ (let ((result
+ (emacsconf-extract-dump-get-command
+ (concat emacsconf-id "-" emacsconf-year "-" (plist-get track :id))
+ (emacsconf-extract-time-or-offset-to-time start-time)
+ (emacsconf-extract-time-or-offset-to-time end-time)
+ (concat output-prefix (format-time-string "%Y-%m-%d_%H-%M-%S" (emacsconf-extract-time-or-offset-to-time start-time) t) ".webm"))))
+ (when (called-interactively-p 'any)
+ (kill-new result))
+ result))
+
+(defun emacsconf-extract-dump-refine (filename starting-ts ending-ts)
+ (interactive
+ (list (read-file-name "Input: " nil (conf-latest-file ".") t)
+ (read-string "Start timestamp: ")
+ (read-string "End timestamp: ")))
+ (let ((result
+ (format "ffmpeg -y %s -c copy %s"
+ ()
+ starting-ts filename
+ starting-ts ending-ts (expand-file-name (concat "trimmed-" (file-name-nondirectory filename))
+ (file-name-directory filename)))))
+ (when (called-interactively-p 'any)
+ (kill-new result))
+ result))
+
+(defvar emacsconf-extract-qa-caption-length 50)
+
+(defun emacsconf-extract-qa-from-assemblyai-sentences (file)
+ (let ((data
+ (with-temp-buffer
+ (insert-file-contents file)
+ (json-parse-buffer)))
+ last-speaker)
+ (subed-create-file
+ (concat (file-name-sans-extension file) ".vtt")
+ (mapcar
+ (lambda (sent)
+ (let* ((words (mapconcat
+ (lambda (w)
+ (propertize (gethash "text" w)
+ 'start (gethash "start" w)
+ 'end (gethash "end" w)
+ 'confidence (gethash "confidence" w)))
+ (get-hash "words" sent)
+ " "))
+ (reflowed (emacsconf-split-text-based-on-heuristics
+ words
+ emacsconf-extract-qa-caption-length)))
+ (seq-map-indexed
+ (lambda (line index)
+ (list
+
+ )
+ )
+ )
+ (list
+ nil
+ (gethash "start" sent)
+ (gethash "end" sent)
+ (if (string= (or last-speaker "") (gethash "speaker" sent))
+ words
+ (format "[Speaker %s]: %s" (gethash "speaker" sent) (gethash "text" sent)))
+ (if (string= (or last-speaker "") (gethash "speaker" sent))
+ nil
+ (setq last-speaker (gethash "speaker" sent))
+ (emacsconf-surround "NOTE Speaker " (gethash "speaker" sent) "\n\n" nil)))))
+ (gethash "sentences" data)))))
+;; (emacsconf-extract-qa-from-assemblyai-sentences "~/proj/emacsconf/rms/sentences")
+
+(defun emacsconf-extract-copy-pad ()
+ (interactive)
+ (let ((slug (emacsconf-get-slug-from-string (file-name-base (buffer-file-name))))
+ (delimiter "\\\\-\\\\-\\\\-\\\\-\\\\-")
+ notes
+ questions)
+ (goto-char (point-min))
+ (when (re-search-forward "Notes, discussions, links, feedback:" nil t)
+ (forward-line 1)
+ (setq notes (string-trim (buffer-substring (point) (if (re-search-forward delimiter nil t) (match-beginning 0) (point-max))))))
+ (when (re-search-forward "Questions and answers go here:" nil t)
+ (forward-line 1)
+ (setq questions (string-trim (buffer-substring (point) (if (re-search-forward delimiter nil t) (match-beginning 0) (point-max))))))
+ (find-file (expand-file-name (concat slug ".md") (expand-file-name "talks" (expand-file-name emacsconf-year emacsconf-directory))))
+ (goto-char (point-min))
+ (if (re-search-forward "^# Discussion\n\n" nil t)
+ nil
+ (re-search-forward "-after)" nil t)
+ (forward-line -1)
+ (insert "# Discussion\n\n"))
+ (save-excursion
+ (unless (string= (or notes "") "")
+ (insert "## Notes\n\n" notes "\n\n"))
+ (unless (string= (or questions "") "")
+ (insert "## Questions and answers\n\n" questions "\n\n"))
+ )))
(provide 'emacsconf-extract)
;;; emacsconf-extract.el ends here