subed
═════

  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:

  • SubRip ( `.srt')
  • WebVTT ( `.vtt' )
  • Advanced SubStation Alpha ( `.ass', experimental )
  • Tab-separated values ( `.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.

  <file:https://raw.githubusercontent.com/sachac/subed/master/screenshot.jpg>


[mpv] <https://mpv.io/>

Features
────────

  • Jump to next (`M-n') and previous (`M-p') subtitle text.
  • Jump to the beginning (`C-M-a') and end (`C-M-e') of the current
    subtitle's text.
  • Merge subtitles with `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'.
  • Insert subtitles evenly spaced throughout the available space
    (`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.
  • Kill subtitles (`M-k').
  • Adjust subtitle start (`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).
  • Move the current subtitle or all marked subtitles
    (`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).
  • Shift the current subtitle 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'.
  • Scale all subtitles or all marked subtitles forward (`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').
  • Show CPS (characters per second) for the current subtitle.
  • Insert HTML-like tags (`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').
  • SRT: Sort and re-number subtitles and remove any extra spaces and
    newlines (`M-s'). This is done automatically every time the buffer
    is saved.
  • Trim subtitle overlaps with `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.
  • Convert between formats with `M-x subed-convert'.
  • Load word timing data (ex: SRV2) using `M-x
      subed-word-data-load-from-file'.
  • Use `M-x subed-align' and [aeneas] to align your text or subtitles
    with an audio file in order to get timestamps.


[aeneas] <https://www.readbeyond.it/aeneas/>

mpv integration (optional)
╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌

  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.

  • Automatically open the associated media file in MPV based on the
    filename, open a media file manually with `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'.
  • Pause and resume playback without leaving Emacs (`M-SPC').
  • Jump to the current subtitle in the MPV player with `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'.
  • Use `C-c .' (`subed-toggle-sync-point-to-player') to toggle whether
    the point should move to the currently playing subtitle.
  • Use `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.
  • Subtitles are automatically reloaded in mpv when the buffer is
    saved.
  • Copy the current playback position as start (`C-c [') or stop (`C-c
    ]') time of the current subtitle.
  • Playback is paused or slowed down when a subtitle's text is edited
      (`C-c C-p', `subed-toggle-pause-while-typing').
  • Loop over the current subtitle in mpv (`C-c C-l').
  • When a subtitle's start or stop time changes, mpv seeks to the
    subtitle's start time (`C-c C-r',
    `subed-toggle-replay-adjusted-subtitle').
  • Move one frame forward or backward (`C-c C-f .' and `C-c C-f ,';
    pressing `,' or `.' afterwards moves by frames until any other key
    is pressed).


Installation
────────────

Installing the subed package from NonGNU Elpa
╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌

  `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, and then use `M-x
  package-install' `subed'.


[NonGNU ELPA] <https://elpa.nongnu.org/nongnu/subed.html>


Manual installation
╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌

  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):

  ┌────
  │ ;; Note the reference to the subed subdirectory
  │ (add-to-list 'load-path "/path/to/subed/subed")
  │ (require 'subed-autoloads)
  └────

  and 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
  └────


use-package configuration
╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌

  Here's an example setup if you use use-package:

  ┌────
  │ (use-package subed
  │   :ensure t
  │   :config
  │   ;; Disable automatic movement of point by default
  │   (add-hook 'subed-mode-hook 'subed-disable-sync-point-to-player)
  │   ;; 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))))
  └────


straight configuration
╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌

  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")))
  └────


[straight.el] <https://github.com/radian-software/straight.el>


Getting started
───────────────

  `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'.


Troubleshooting
───────────────

subed-mpv: Service name too long
╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌

  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.


Important change in v1.0.0
──────────────────────────

  `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
─────────────

  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.


[REUSE Specification] <https://reuse.software/spec/>


License
───────

  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.


[GNU General Public License] <https://www.gnu.org/licenses/gpl-3.0.txt>
