diff options
-rw-r--r-- | durand-bongo.el (renamed from bongo.el) | 181 |
1 files changed, 140 insertions, 41 deletions
diff --git a/bongo.el b/durand-bongo.el index 7ea7347..a93053a 100644 --- a/bongo.el +++ b/durand-bongo.el @@ -1,4 +1,4 @@ -;;; bongo.el --- My configurations of Bongo -*- lexical-binding: t; -*- +;;; durand-bongo.el --- My configurations of Bongo -*- lexical-binding: t; -*- ;; Copyright (C) 2022 Jean Sévère Durand @@ -704,12 +704,37 @@ will do the right renaming." ;; Sometimes I want to play the subtitles as the song plays. +;;;; Subtitle buffer + (defvar durand-bongo-sub-buffer-name "*Subtitles*" "The name of the buffer for playing subtitles.") (defvar durand-bongo-sub-buffer nil "The buffer for playing subtitles.") +;;;; Start timer + +(defun durand-bongo-sub-start-timer (player) + "Start ticking when playing subtitles." + (durand-bongo-sub-stop-timer player) + (let ((timer (run-with-timer bongo-mpv-initialization-period + (bongo-player-get + player 'time-update-delay-after-seek) + 'durand-bongo-sub-tick + player))) + (bongo-player-put player 'sub-timer timer))) + +;;;; Start the timer when appropriate + +(defun durand-bongo-sub-start-timer-maybe (&rest _args) + "Start the subtitle timer for the mpv backend." + (with-bongo-playlist-buffer + (cond + ((and bongo-player (eq (car bongo-player) 'mpv)) + (durand-bongo-sub-start-timer bongo-player))))) + +;;;; Stop timer + (defun durand-bongo-sub-stop-timer (player) "Stop subtitle timer for the PLAYER." (let ((timer (bongo-player-get player 'sub-timer))) @@ -718,6 +743,8 @@ will do the right renaming." (cancel-timer timer) (bongo-player-put player 'sub-timer nil))))) +;;;; Tick timer + (defun durand-bongo-sub-tick (player) "Tick when playing subtitles." (if (or (null durand-bongo-sub-buffer) @@ -732,22 +759,7 @@ will do the right renaming." player "sub-pos" "get_property" "time-pos") (bongo-sub-redisplay))) -(defun durand-bongo-sub-start-timer (player) - "Start ticking when playing subtitles." - (durand-bongo-sub-stop-timer player) - (let ((timer (run-with-timer bongo-mpv-initialization-period - (bongo-player-get - player 'time-update-delay-after-seek) - 'durand-bongo-sub-tick - player))) - (bongo-player-put player 'sub-timer timer))) - -(defun durand-bongo-sub-start-timer-maybe (&rest _args) - "Start the subtitle timer for the mpv backend." - (with-bongo-playlist-buffer - (cond - ((and bongo-player (eq (car bongo-player) 'mpv)) - (durand-bongo-sub-start-timer bongo-player))))) +;;;; Mode for displaying subtitles (define-derived-mode durand-bongo-sub-mode special-mode "Bongo Sub" "Major mode for displaying subtitles in accordance with Bongo." @@ -757,23 +769,29 @@ will do the right renaming." (define-key durand-bongo-sub-mode-map (vector ?s) #'durand-bongo-sub-stop) +;;;; Clean up after exiting + (defun durand-bongo-sub-stop () "Stop everything related to displaying subtitles." (interactive) - (durand-bongo-sub-stop-timer) + (durand-bongo-sub-stop-timer bongo-player) (with-bongo-playlist-buffer (bongo-player-put bongo-player 'sub-time nil) (cond ((buffer-live-p - (bongo-player-get bongo-player 'sub-file-buffer nil)) + (bongo-player-get bongo-player 'sub-file-buffer)) (kill-buffer - (bongo-player-get bongo-player 'sub-file-buffer nil)) + (bongo-player-get bongo-player 'sub-file-buffer)) (bongo-player-put bongo-player 'sub-file-buffer nil))) (cond ((buffer-live-p durand-bongo-sub-buffer) (kill-buffer durand-bongo-sub-buffer) (setq durand-bongo-sub-buffer nil))))) +;;;; Find the subtitles file and load into a buffer + +(require 'rx) + (defun durand-bongo-sub-prepare-file-buffer () "Prepare the subtitles file buffer for the currently playing song." (let* ((file-name (or (bongo-player-get bongo-player 'file-name) @@ -797,30 +815,11 @@ will do the right renaming." (cond ((not (looking-at-p (rx-to-string (list 'seq file-name 'eol) t))) + (erase-buffer) (insert file-name ?\n) (insert-file-contents sub-file-name)))) sub-file-buffer)) -(defun durand-bongo-sub () - "Display subtitles in a separate buffer." - (setq durand-bongo-sub-buffer - (get-buffer-create durand-bongo-sub-buffer-name)) - (cond - ((null (get-buffer-window durand-bongo-sub-buffer)) - (let ((durand-window-max-height 0.01)) - (display-buffer - durand-bongo-sub-buffer - (list (list #'display-buffer-reuse-window - #'display-buffer-in-side-window) - (cons 'side 'bottom) - (cons 'window-height - #'durand-fit-window-to-buffer-with-max)))))) - (with-bongo-playlist-buffer (durand-bongo-sub-prepare-file-buffer)) - (set-buffer durand-bongo-sub-buffer) - (durand-bongo-sub-mode) - (bongo-sub-redisplay) - (durand-bongo-sub-start-timer-maybe)) - ;;;; My custom filter ;; To handle subtitle events @@ -1047,7 +1046,107 @@ TIME must be a list of two to four elements." ;;;; Subtitle command -;; TODO +(defun durand-bongo-sub () + "Display subtitles in a separate buffer." + (setq durand-bongo-sub-buffer + (get-buffer-create durand-bongo-sub-buffer-name)) + (cond + ((null (get-buffer-window durand-bongo-sub-buffer)) + (let ((durand-window-max-height 0.01)) + (display-buffer + durand-bongo-sub-buffer + (list (list #'display-buffer-reuse-window + #'display-buffer-in-side-window) + (cons 'side 'bottom) + (cons 'window-height + #'durand-fit-window-to-buffer-with-max)))))) + (with-bongo-playlist-buffer (durand-bongo-sub-prepare-file-buffer)) + (set-buffer durand-bongo-sub-buffer) + (durand-bongo-sub-mode) + (bongo-sub-redisplay) + (durand-bongo-sub-start-timer-maybe)) + +;;; Edit subtitles + +;; It would be too cumbersome if I cannot edit subtitles with Bongo. + +;; On a second thought, I think the library 'subed' is good enough. + +;;;; Major mode + +(define-derived-mode durand-bongo-sub-edit-mode text-mode "BOSE" + "BOngo Subtitles Edit mode + +The subtitles are assumed to be for the song that Bongo is +currently playing. To change the audio or the video, change it +in Bongo. + +Moreover, the audio and video playing is completely handled by +Bongo, and this mode only acts as a frontend of some sort. + +\\{durand-bongo-sub-edit-mode-map}" + ) + +;;;; Regular expression for time specification + +(defvar durand-bongo-sub-time-regex + (rx (group + (= 2 digit) ?: + (= 2 digit) ?: + (= 2 digit) ?, + (= 3 digit)) + (zero-or-more space) + "-->" + (zero-or-more space) + (group + (= 2 digit) ?: + (= 2 digit) ?: + (= 2 digit) ?, + (= 3 digit)) + (zero-or-more space)) + "A regular expression that matches the time specification in a +subtitle file, in the SubRip format.") + +;;;; Regular expression for file extensions + +(defvar durand-bongo-sub-exts + (rx-to-string + (cons + 'or + (append + bongo-audio-file-name-extensions + bongo-video-file-name-extensions))) + "A regular expression that matches the file extensions recognized +by Bongo.") + +;;;; Key bindings + +;; (let ((map durand-bongo-sub-edit-mode-map)) +;; (define-key map (vector 3 ))) + +;;;; Insert subtitle + +(defun durand-bongo-sub-insert () + "Insert a section of subtitles." + (interactive) + (let ((end (point)) + (num 0)) + (search-forward "\n\n" nil 'go) + (save-excursion + (goto-char (point-min)) + (while (re-search-forward + (concat + (rx-to-string + '(seq bol + (one-or-more digit) ?\n) + t) + durand-bongo-sub-time-regex) + end t) + (setq num (1+ num)))) + (newline) + (newline) + (insert (format "%d" (1+ num)) + ?\n))) ;;; Volume package |