This tidbit displays a buffer with the text of the subtitles so that I can quickly skim it. ( or data (my-caption-fix-common-errors my-caption-cache))) ( lambda (entry) (my-caption-format-as-subtitle entry)) ( defun my-caption-to-vtt ( &optional data) (subed-vtt-msecs-to-timestamp (alist-get 'start entry)) (subed-vtt-msecs-to-timestamp (alist-get 'end (car (last list)))) (subed-vtt-msecs-to-timestamp (alist-get 'start (car list))) ( setq current-length (1+ current-length))) ((string-match "^\n*$" (alist-get 'text (car list))) ( defun my-caption-make-groups (list &optional threshold) If I want to generate a VTT based on the caption data, breaking it at Unsure about a word that needs to be changed. Reformatting, but I can easily replay segments of the video if I'm That way, I can use the word-level timing information for most of the my-caption-split-and-merge-with-previous) ( defun my-caption-split-and-merge-with-previous () ( defun my-caption-split-and-merge-with-next () (subed-split-subtitle ( and data (- (alist-get 'start data) (subed-subtitle-msecs-start))))))) "Split the current subtitle based on word-level timing if available." ( let ((limit ( save-excursion ( or (subed-jump-to-subtitle-end) (point))))) ((> offset (length words)) ( setq done t)) (( and candidate (string-match (concat "\\") (alist-get 'text candidate)))
( setq candidate (elt words (+ (1- (length remaining-words)) offset))) (remaining-words (split-string (buffer-substring (point) ( or (subed-jump-to-subtitle-end) (point))))) ( let* ((end (subed-subtitle-msecs-stop)) To try to figure out the time to use when splitting the subtitle,įalling back to the proportional method if the data is not available. Match the remainder of the current caption with the word-level timing Of the captions file after point is mostly unedited. (add-hook 'subed-mode-hook 'my-caption-load-word-data-maybe))Īssuming I start editing from the beginning of the file, then the part (my-caption-load-word-data (concat (file-name-sans-extension (buffer-file-name)) ".en.srv2"))
( when ( and (buffer-file-name) (file-exists-p (concat (file-name-sans-extension (buffer-file-name)) ".en.srv2"))) ( defun my-caption-load-word-data-maybe () (replace-regexp-in-string "'" "'" (alist-get 'text entry))) ( setq data (my-caption-extract-words-from-srv2))) ( setq data (my-caption-extract-words-from-json3))) ( with-current-buffer (find-file-noselect file) (map-put! o 'text (replace-match (car ( if (listp e) e (list e))) t t (alist-get 'text o))))) ( defun my-caption-fix-common-errors (data) ( setq last-start (alist-get 'start rec)) (cons 'text (car (xml-node-children element)))))) ( let ((rec (list (cons 'start (string-to-number (alist-get 't (xml-node-attributes element)))) (string-to-number (alist-get 'd (xml-node-attributes (car text-elements))))))) (alist-get 't (xml-node-attributes (car text-elements)))) (text-elements (reverse (dom-by-tag data 'text))) ( defun my-caption-extract-words-from-srv2 () (end ,(my-caption-json-time-to-ms (alist-get 'endTime seg))) `((start ,(my-caption-json-time-to-ms (alist-get 'startTime seg))) Nconc (alist-get 'words (car (alist-get 'alternatives seg))))))) ( cl-loop for seg in (car (alist-get 'results data)) ( let* ((data ( progn (goto-char (point-min)) (json-read))) ( defun my-caption-extract-words-from-json3 () (+ (* 1000 (string-to-number (alist-get 'seconds json))) ( defun my-caption-json-time-to-ms (json) ( defvar-local my-caption-cache nil "Word-level timing in the form ((start.