To install this package from Emacs, use package-install
or list-packages
.
subed is an Emacs major mode for editing subtitles while playing the corresponding media file with mpv. At the moment, the only supported formats are:
.srt
).vtt
).ass
, experimental ).tsv
, experimental ) - as exported by
Audacity for labels. TSVs are not recognized automatically because
it's a common data format, but you can use subed-tsv-mode
to turn
it on in a buffer.
M-n
) and previous (M-p
) subtitle text.C-M-a
) and end (C-M-e
) of the current
subtitle's text.M-m
(subed-merge-dwim
) and split them with
M-.
(subed-split-subtitle
). If the media file is playing in MPV,
use the current playback position. If not, use the relative position
in the subtitle text, or other functions listed in
subed-split-subtitle-timestamp-functions
.M-i
) or
right next to the current subtitle (C-M-i
). A prefix argument controls how
many subtitles to insert and whether they are inserted before or after the
current subtitle.M-k
).M-[
/ M-]
) and stop (M-{
/ M-}
) time. A
prefix argument sets the number of milliseconds for the current session
(e.g. C-u 1000 M-[ M-[ M-[
decreases start time by 3 seconds).subed-move-subtitles
) forward (C-M-n
) or backward (C-M-p
) in
time without changing subtitle duration. A prefix argument sets the
number of milliseconds for the current session (e.g. C-u 500 C-M-n
C-M-n
moves the current subtitle 1 second forward).C-M-f
) or backward (C-M-b
) together
with all following subtitles. This is basically a convenience shortcut for
C-SPC M-> C-M-n/p
.C-M-x
) or backward
(C-M-S-x
) in time without changing subtitle duration. A prefix argument
sets the number of milliseconds for the current session (e.g. C-u 500
C-M-x
moves the last [or last marked] subtitle forward 500ms and
proportionally scales all [or all marked] subtitles based on this time
extension. Similarly, C-u 500 C-M-S-x
moves the last [or last marked]
subtitle backward 500ms and proportionally scales all [or all marked]
subtitles based on this time contraction). This can be extremely useful to
correct synchronization issues in existing subtitle files. First, adjust
the starting time if necessary (e.g. C-M-f
), then adjust the ending and
scale constituent subtitles (e.g. C-M-x
).C-c C-t C-t
, with an optional attribute
when prefixed by C-u
), in particular italics (C-c C-t C-i
) or
boldface (C-c C-t C-b
).M-s
). This is done automatically every time the buffer
is saved.M-x subed-trim-overlaps
. By
default, this adjusts the stop time of overlapping subtitles to
subed-subtitle-spacing
milliseconds before the next subtitle
starts. Use M-x customize-group
subed
to configure trimming
to happen automatically when buffers are loaded or saved, which
time is adjusted, and how much time to leave between subtitles.M-x subed-convert
.M-x subed-waveform-minor-mode
, off by default)
extracted from the media file using ffmpeg
with the start/stop
positions of the current subtitle and the current position in MPV
marked along with the subtitle. Change the "volume" of the waveform
(i.e., the visible amplitude) with C-c C--
and C-c C-=
.
Redisplay the waveform with C-c |
. Left/right-click on the
waveform to set the start/stop timestamps. If you would like to display the waveform automatically when you open a file, you can add (add-hook 'subed-mode-hook 'subed-waveform-minor-mode)
to your configuration.M-x
subed-word-data-load-from-file
. This will be used for splitting
words at timestamps when available.M-x subed-align
and aeneas to align your text or subtitles
with an audio file in order to get timestamps.Using network sockets to control MPV works on Linux and on Mac OS X, but not on Microsoft Windows due to the lack of Unix-style sockets. On Microsoft Windows, you will not be able to synchronize with MPV.
C-c C-v
(subed-mpv-play-from-file
), or play media directly from a URL with C-c C-u
(subed-mpv-play-from-url
) . You can customize the automatic detection of files by changing subed-video-extensions
and subed-audio-extensions
.M-SPC
).M-j
(subed-mpv-jump-to-current-subtitle
). Toggle looping over the
current subtitle with C-c C-l
(subed-toggle-loop-over-current-subtitle
). Control how many seconds
to loop before or after the current subtitles by customizing
subed-loop-seconds-before
and subed-loop-seconds-after
.C-c .
(subed-toggle-sync-point-to-player
) to toggle whether the point should move to the currently playing subtitle.C-c ,
(subed-toggle-sync-player-to-point
) to toggle whether mpv should seek to the position of the current subtitle when the point moves between subtitles.C-c [
) or stop (C-c ]
)
time of the current subtitle.C-c
C-p
, subed-toggle-pause-while-typing
).C-c C-l
).C-c C-r
, subed-toggle-replay-adjusted-subtitle
).C-c C-f .
and C-c C-f ,
;
pressing ,
or .
afterwards moves by frames until any other
key is pressed).
subed
is now on NonGNU ELPA. On Emacs 28 and later, you can install it with M-x package-install
subed
.
To install it on Emacs 27 or earlier, add the following to your Emacs configuration file:
(with-eval-after-load 'package (add-to-list 'package-archives '("nongnu" . "https://elpa.nongnu.org/nongnu/")))
Use M-x eval-buffer
to run the code, use M-x package-refresh-contents
to load the package archives, and then use M-x package-install
subed
.
Sample configuration:
(with-eval-after-load 'subed-mode ;; Remember cursor position between sessions (add-hook 'subed-mode-hook 'save-place-local-mode) ;; Break lines automatically while typing (add-hook 'subed-mode-hook 'turn-on-auto-fill) ;; Break lines at 40 characters (add-hook 'subed-mode-hook (lambda () (setq-local fill-column 40))) ;; Some reasonable defaults (add-hook 'subed-mode-hook 'subed-enable-pause-while-typing) ;; As the player moves, update the point to show the current subtitle (add-hook 'subed-mode-hook 'subed-enable-sync-point-to-player) ;; As your point moves in Emacs, update the player to start at the current subtitle (add-hook 'subed-mode-hook 'subed-enable-sync-player-to-point) ;; Replay subtitles as you adjust their start or stop time with M-[, M-], M-{, or M-} (add-hook 'subed-mode-hook 'subed-enable-replay-adjusted-subtitle) ;; Loop over subtitles (add-hook 'subed-mode-hook 'subed-enable-loop-over-current-subtitle) ;; Show characters per second (add-hook 'subed-mode-hook 'subed-enable-show-cps))
If that doesn't work, you can install it manually. To install from the main branch:
git clone https://github.com/sachac/subed.git
This will create a subed
directory with the code.
If you have the make
utility, you can regenerate the autoload definitions with
make autoloads
If you don't have make
installed, you can generate the autoloads
with:
emacs --quick --batch --eval "(progn (setq generated-autoload-file (expand-file-name \"subed-autoloads.el\" \"subed\") backup-inhibited t) \ (update-directory-autoloads \"./subed\"))"
Then you can add
the following to your Emacs configuration (typically
~/.config/emacs/init.el
, ~/.emacs.d/init.el
, or ~/.emacs
; you
can create this file if it doesn't exist yet). Here's a configuration example:
;; Note the reference to the subed subdirectory, instead of the one at the root of the checkout (add-to-list 'load-path "/path/to/subed/subed") (require 'subed-autoloads) (with-eval-after-load 'subed-mode ;; Remember cursor position between sessions (add-hook 'subed-mode-hook 'save-place-local-mode) ;; Break lines automatically while typing (add-hook 'subed-mode-hook 'turn-on-auto-fill) ;; Break lines at 40 characters (add-hook 'subed-mode-hook (lambda () (setq-local fill-column 40))) ;; Some reasonable defaults (add-hook 'subed-mode-hook 'subed-enable-pause-while-typing) ;; As the player moves, update the point to show the current subtitle (add-hook 'subed-mode-hook 'subed-enable-sync-point-to-player) ;; As your point moves in Emacs, update the player to start at the current subtitle (add-hook 'subed-mode-hook 'subed-enable-sync-player-to-point) ;; Replay subtitles as you adjust their start or stop time with M-[, M-], M-{, or M-} (add-hook 'subed-mode-hook 'subed-enable-replay-adjusted-subtitle) ;; Loop over subtitles (add-hook 'subed-mode-hook 'subed-enable-loop-over-current-subtitle) ;; Show characters per second (add-hook 'subed-mode-hook 'subed-enable-show-cps))
You can reload your configuration with M-x eval-buffer
or restart Emacs.
If you want to try a branch (ex: derived-mode
), you can use the
following command inside the subed
directory:
git checkout branchname
Here's an example setup if you use use-package:
(use-package subed :ensure t :config ;; Remember cursor position between sessions (add-hook 'subed-mode-hook 'save-place-local-mode) ;; Break lines automatically while typing (add-hook 'subed-mode-hook 'turn-on-auto-fill) ;; Break lines at 40 characters (add-hook 'subed-mode-hook (lambda () (setq-local fill-column 40))) ;; Some reasonable defaults (add-hook 'subed-mode-hook 'subed-enable-pause-while-typing) ;; As the player moves, update the point to show the current subtitle (add-hook 'subed-mode-hook 'subed-enable-sync-point-to-player) ;; As your point moves in Emacs, update the player to start at the current subtitle (add-hook 'subed-mode-hook 'subed-enable-sync-player-to-point) ;; Replay subtitles as you adjust their start or stop time with M-[, M-], M-{, or M-} (add-hook 'subed-mode-hook 'subed-enable-replay-adjusted-subtitle) ;; Loop over subtitles (add-hook 'subed-mode-hook 'subed-enable-loop-over-current-subtitle) ;; Show characters per second (add-hook 'subed-mode-hook 'subed-enable-show-cps) )
If you use straight.el, you can install subed with the following recipe:
(straight-use-package '(subed :type git :host github :repo "sachac/subed" :files ("subed/*.el")))
C-h f subed-mode
should get you started. This is the parent mode for
subed-srt-mode
, subed-vtt-mode
, and subed-ass-mode
. When
manually loading a mode, use those specific format modes instead of
subed-mode
.
If subed-mpv-client
reports (error "Service name too long")
, this
is probably because the path to the socket used to communicate with
MPV is too long for your operating system. You can use M-x customize
to set subed-mpv-socket-dir
to a shorter path.
subed
now uses subed-srt-mode
, subed-vtt-mode
, and
subed-ass-mode
instead of directly using subed-mode
. These modes
should be automatically associated with the .vtt
, .srt
, and .ass
extensions. If the generic subed-mode
is loaded instead of the format-specific mode,
you may get an error such as:
Error in post-command-hook (subed--post-command-handler): (cl-no-applicable-method subed--subtitle-id)
If you set auto-mode-alist
manually in your config, please make sure
you associate extensions the appropriate format-specific mode instead
of subed-mode
. The specific backend functions (ex:
subed-srt--jump-to-subtitle-id
) are also deprecated in favor of
using generic functions such as subed-jump-to-subtitle-id
.
Contributions would be really appreciated! subed conforms to the REUSE
Specification; this means that every file has copyright and license
information. If you modify a file, please update the year shown after
SPDX-FileCopyrightText
. Thank you!
There's a list of authors in the file AUTHORS.org
. If you have at any point
contributed to subed, you are most welcome to add your name (and email
address if you like) to the list.
subed is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
subed-1.2.3.tar.lz | 2023-Jun-18 | 180 KiB |
subed-1.2.2.tar.lz | 2023-Apr-10 | 176 KiB |
subed-1.2.1.tar.lz | 2023-Mar-21 | 176 KiB |
subed-1.2.0.tar.lz | 2023-Mar-10 | 175 KiB |
subed-1.1.0.tar.lz | 2023-Mar-08 | 175 KiB |
subed-1.0.29.tar.lz | 2022-Dec-30 | 171 KiB |
subed-1.0.19.tar.lz | 2022-Nov-12 | 168 KiB |
subed-1.0.9.tar.lz | 2022-Sep-15 | 160 KiB |
subed-1.0.8.tar.lz | 2022-Sep-08 | 160 KiB |
subed-1.0.7.tar.lz | 2022-Jul-25 | 159 KiB |
subed-1.0.6.tar.lz | 2022-Jul-22 | 159 KiB |
subed-1.0.5.tar.lz | 2022-Apr-17 | 158 KiB |
subed-1.0.4.tar.lz | 2022-Apr-16 | 158 KiB |
subed-1.0.3.tar.lz | 2022-Feb-07 | 158 KiB |
subed-1.0.2.tar.lz | 2022-Feb-02 | 157 KiB |
subed-1.0.1.tar.lz | 2022-Feb-01 | 157 KiB |
subed-0.0.4.tar.lz | 2022-Jan-24 | 156 KiB |
subed-0.0.3.tar.lz | 2021-Dec-30 | 156 KiB |
subed-0.0.2.tar.lz | 2021-Dec-07 | 154 KiB |
subed-0.0.1.tar.lz | 2021-Dec-03 | 139 KiB |
Guess the format when the generic subed-mode is loaded. Also, require svg when subed-waveform is loaded.
Added subed-waveform, which you can enable with subed-waveform-minor-mode. This makes it easier to review the waveform for the current subtitle so that you can use it to adjust the start or stop time. It requires the ffmpeg executable. Thanks, mbork!
subed should not autoplay media over TRAMP.
Adjusting the starting or stopping timestamp (including via merges) should now also update the looping start and stop times.
I changed subed-mode
so that it doesn't add functions to local
hooks, because that seems to mess up configuring hooks from your Emacs
init file. Please see README.org for recommended code to add to your
subed-mode-hook
. I decided to suggest each line separately so that
it's easier for people to disable specific behaviors instead of hiding
it in subed-setup-defaults
.
There are new customizable values for subed-enforce-time-boundaries that affect setting or adjusting the start or stop times if a subtitle will end up overlapping with the previous or next subtitle (based on subed-subtitle-spacing), or if a subtitle will have negative duration.
'adjust
: the new default. If a subtitle will have invalid times,
adjust the other time to resolve the conflict.'clip
: set the current time to at most (or at least) the other time, taking spacing into account.'error
: report an error when trying to set an invalid time.nil
: don't perform any checks, just set the time.
By default, you can adjust times with M-[
(decrease-start-time
), M-]
(increase-start-time
), M-{
(decrease-stop-time
), and M-}
(increase-stop-time
).
I've been writing more tests to cover the behavior, but I might've missed stuff, so please let me know if things turn up!
subed-toggle-sync-point-to-player should not confuse subed when it is already looping over a subtitle. Also, subed-loop-seconds-before and subed-loop-seconds-after now default to 0 for less confusion.
subed-parse-file should handle nil filenames now. Also, it should not try to autoplay media.
Bugfix: Actually include VTT comments when inserting subtitles programmatically.
subed-align now keeps VTT comments. It also doesn't remove silences by default now, since aeneas turned out to be a little too aggressive about silence detection.
subed-move-subtitles and subed-scale-subtitles are now interactive commands. The documentation for subed-scale-subtitles now mentions subed-move-subtitles, and I've updated the README to mention them.
subed should compile without checkdoc warnings or obsolete functions now.
You can now use subed-copy-region-text
to copy the text from
subtitles in a region. Call it with a prefix argument (C-u M-x
subed-copy-region-text
) to include comments.
Calling C-u M-x subed-convert
will retain comments in the TXT
output.
VTT comments are now parsed and returned as part of subed-subtitle
and subed-subtitle-list
. This makes it easier to build workflows
that use the comment information, such as adding NOTE lines for
chapters and then creating a new file based on those lines and the
subtitles following them.
A new function subed-create-file
helps create a file with a list of
subtitles.
Sanitizing VTT files with subed-sanitize
should retain comments now.
subed-convert
should now create a buffer instead of a file if the
…
…