Awesome
| rCut >
- a wonderful writeup by zerwuerfnis, and social media discussions 1 2
- Youtube Demo
- FOSDEM 2024 Talk
- A brief metion by podcasters from postmarketOS
Q: What if I don't use Vim?
Just grab srt2tsv.py and tsv2roughcut.py and you are good to go. Only FFmpeg is needed. (a static build is good enough)
Syntax
* Title
Any line without EDL in the beginning is a comment.
## Including this SubSection
EDL 00:00:01,000 00:00:05,000 | image | subtitles….
EDL 00:00:01,000 00:10:01,422 | clipname | [B]this is B-Roll
EDL 00:00:01,000 00:10:01,422 | clipname | subtitles….
EDL 00:00:01,000 00:10:01,422 | clipname | subtitles and\Nnewline
NOTE: Detail of tab and space described as follow
EDL⇥00:00:01,000⇥00:10:01,422⇥|⎵clipname without extension⎵|⇥subtitles and\Nnewline
*** SubSubSection
Asterisk and sharp sign are equally treated.
Even sed
is enough to do the transformation from srt
to tsv
. (However, sed doesn't stitch the gap of srt files. You still may want to use srt2tsv.py
)
cat some.srt | sed -n -r '1{/^$/n;};/^[0-9]+$/{n; s/ --> /\t/; s/$/\t| _CLIPNAME_ |\t/; N; s/\n//; h; d;}; /^$/! { H; $!d;}; x; s/\n/\\N/g; s/^/EDL\t/;p' > some.tsv
# you may remember this dig TXT srt2tsv.scateu.me
sed -i "" 's/_CLIPNAME_/some/' some.tsv
Key-bindings
PREVIEW
Key | Function |
---|---|
⇥ (tab) | [mpv] play this line (guessing start pos at cursor), stop at end |
⇧⇥ | [mpv] play this line from start (no guessing pos), stop at end |
\ ⇥ | [mpv] play this line (from cursor), don't stop |
\ ⎵ | [mpv] play line by line from this one till EOF |
TIMECODE EDITING
Key | Function |
---|---|
J | Join (timecode) with the next line; If on the first of two http lines with timestamp, will made an EDL line. |
| | [split] this line into two, guessing a new timecode |
mm | mark/unmark word break point, then [split] will use this and cursor together. |
useful when cut time not predicted well. | |
⇧← ⇧→ | Roll timecode with the previous line for 1 sec |
g0 | go to the start of subtitle |
g8 | go to record_out timecode in prev line |
g9 | go to record_in timecode |
gO | append a gap for 5 secs below current line |
gN | append a line for 10 minutes below current line, place cursor to input clipname |
gB | toggle a line between '[B]' or not. |
gb | the same as gB |
gc | calculate duration of this line based on record_in and record_out , append to the end of line. |
ge | calculate and update record_out to media file end . useful with Voice Over or gN |
\ c | toggle conceallevel=0, 1 ; :set nowrap may help you. |
gr | record Voice Over, filename generated based on sys time. preserve multi takes, old ones marked with 'xxx' |
EDITORIAL DECISION / BBC Paper Edit
Key | Function |
---|---|
\ p | Enter cherry-pick mode. tabnew on the left, map ⏎ |
⏎ (enter) | pick this line to Vim tab 1, then mark used --- |
\ P | Enter cherry-pick mode (split horizontally), map ⏎ |
⏎ | pick this line to next window, then mark used --- |
⌫ (BS) | reject this line, mark xxx , then go to next line |
⌦ (DEL, fn⌫) | toggle between EDL and xxx ; toggle --- to EDL |
V (region) ⎵ | render those highlighted lines with tsv2roughcut |
V x | export those highlighted lines with tsv2fcpxml |
MPV IPC CONTROL MODE
Key | Function |
---|---|
\ \ | init. mpv --input-ipc-server=/tmp/mpvsocket --pause clipname.mp4 |
and enter IPC Control mode. s ← → ↑ ↓ ⎵ ⏎ are redefined, and restored at quit | |
\ \ (again) | send quit signal via ipc socket to mpv |
⎵ | [mpv ipc] toggle play |
← → | move, then [mpv ipc] seek to cursor |
↑ ↓ | move, then [mpv ipc] seek; reload when clip changed |
\ ⎵ | [mpv ipc] play from this line till EOF |
⏎ or s | [mpv ipc] seek to cursor |
ns | [mpv ipc] search next (n ), and seek |
S | [mpv ipc] sync playhead: seek vim cursor to nearest of mpv timecode, wrap end |
\ S | backwards of sync playhead |
gS | playhead sync periodically, every 1s. call again to dismiss. ⎵ will pause and restore status |
⇥ | seek to cursor, [mpv ipc] always play. if in comment region, jump to next 'EDL' |
⇧⇥ | seek to line head, then ⇥ |
gi | [mpv ipc] get current timecode, write record_in. overwrite existing. |
go | [mpv ipc] get current timecode, write record_out and clipname. overwrite existing |
- | get current timecode from mpv, write to the 'out' of this line. move down, write the same as 'in' |
very useful when adding timecode to a plain text transcription. |
Orgmode/Markdown Folding
Key | Function |
---|---|
⇥ | When not on a EDL/---/xxx line. do za on ## Header or * Org head |
⇧⇥ | cycle foldlevel=0,1,2 |
if on a EDL line, you have to use za zm zr zo zO zM zR | |
]] | go to next heading |
[[ | go to previous heading |
g] | go to next comment line (not start with EDL) |
g[ | go to previous comment line (not start with EDL) |
Screenshots
Install
on macOS with homebrew
mkdir -p ~/.vim/pack/plugins/start; cd ~/.vim/pack/plugins/start
git clone https://github.com/scateu/tsv_edl.vim
git clone https://github.com/vim-airline/vim-airline
git clone https://github.com/pR0Ps/molokai-dark
cd ~/.vim/pack/plugins/start/tsv_edl.vim
make install-utils
brew install mpv ffmpeg jq socat dos2unix sox
#sudo apt install mpv ffmpeg jq socat sox
#brew install macvim
then, put the following lines to ~/.vimrc
"set fencs=utf-8,gbk
filetype plugin indent on "especially this line.
syntax on
set laststatus=2
set number
set anti "macOS anti alias
let g:airline#extensions#tabline#enabled = 1
colorscheme molokai-dark
on macOS without homebrew
<details markdown="1"><summary>Click here to see full instructions</summary>#sudo mkdir /usr/local/bin
#echo 'PATH=$PATH:/usr/local/bin' >> .zshrc
#echo 'PATH=$PATH:/usr/local/bin' >> .bashrc
mkdir -p ~/.vim/pack/plugins/start; cd ~/.vim/pack/plugins/start
git clone https://github.com/scateu/tsv_edl.vim
git clone https://github.com/vim-airline/vim-airline
git clone https://github.com/pR0Ps/molokai-dark
cd tsv_edl.vim; make install-utils
echo 'filetype plugin indent on' >> ~/.vimrc
echo 'syntax on' >> ~/.vimrc
echo 'set laststatus=2' >> ~/.vimrc
echo 'let g:airline#extensions#tabline#enabled = 1' >> ~/.vimrc
echo 'colorscheme molokai-dark' >> ~/.vimrc
make install-depends-on-mac-no-homebrew
</details>
#test
srt2tsv -a
vim -p example.tsv example_never.tsv
# you may want macvim for GUI https://github.com/macvim-dev/macvim/releases/tag/snapshot-172
macOS: Finder Integration with Shortcuts.app
- <del> see utils/apple_automator/README.md </del>
- see README.macOS.shortcuts.md
1. Utils
1.1 srt2tsv
cd /path/to/srt/; srt2tsv -a
srt2tsv a.srt #generates a.tsv
-
or: in vim,
:!srt2tsv -a
-
or: in vim,
V
to mark a region, and press:
then type%!srt2tsv
, to filter this region through the corresponding util. -
.tsv format is defined as: (see
utils/srt2tsv.sh
) -
TIPS for European subtitles:
for i in *.srt; do iconv -f CP1251 -t UTF-8 "$i" > converted/"$i";done
-
TIPS to count lines:
cat *.srt | dos2unix |grep . |sed -r '/^[0-9]+$/{N;d;}' | grep -v Downloaded |wc -l
-
See also: VideoSubFinder, roybaer/burnt-in-subtitle-extractor: Set of basic extraction tools for burnt-in subtitles, i.e. subtitles that are part of the picture itself, SubRip, ocr 1, ocr 2
1.2 tsv2srt
tsv2srt
tsv2srt_all
tips: you may s/,/, /g
, to make Chinese lines wrap. Otherwise ,mpv
treat those as a bloody long line.
1.3 tsv2roughcut: Assemble a rough cut with ffmpeg
cat selection.tsv | tsv2roughcut #will generate roughtcut.mp3/mp4, srt. auto increase filename
cat selection.tsv | tsv2roughcut --user-input-newname
# will ask in the end. do not input ext name. dirname/clipname is supported
# e.g. clips/a good one
cat selection.tsv | head -n 30 | tsv2roughcut test/"good one"
cat selection.tsv | tail -n 30 | tsv2roughcut test/good\ two
cat selection.tsv | grep good | tsv2roughcut "test/good three"
cat *.tsv | grep -C3 -i beep | tsv2roughcut #context 3 lines, ignore case
1.4 tsv2fcpxml
NOTE: tsv2edl
is not well-maintained.
cat selection.tsv | tsv2edl > sel.edl #then import in DaVinci Resolve
cat selection.tsv | tsv2fcpxml > sel.fcpxml #24FPS, 48000Hz, change it accordingly
1.5 auto2srtvideo: Convert MP3/Audio to a dummy video from .srt
Due to the limitation of Davinci Resolve that EDL file cannot be reconstructed into a timeline refering to pure audio file,
a helper bash script is prepared in utils/audio2srtvideo.sh
audio2srtvideo "Some podcast E01.mp3"
will yield a Some podcast E01.mkv
NOTE: You may want to move those mkv files into a subdirectory named, for example, mkvs
, so that Tab
key ffplay
will not be confused.
2. Modes / Use cases
2.1 Cherrypick
vim -p selection1.tsv movie1.tsv podcast1.tsv podcast2.tsv movie2.tsv #target has to be the first tab
NOTE: :mksession
to save a Session.vim
to the current folder may be very useful before reloading this session with vim -S
.
2.2 preview / IPC control
TIPS tsv file can be place separatedly from media file. 1) You can do ln -s
soft link. 2) You may change working directory inside vim
by :cd /Volumes/usbshare2-2/nas/TVSeries/Yes.Prime.Minister
Press \\
twice to init mpv ipc control and bring up mpv. Will try best to reuse existing mpv ipc control channel /tmp/mpvsocket
2.3 mark in/out style
EDL 00:24:00,000 00:30:00,000 | clipname | ......;
Tips: 神笔马良(Magic Pen). for 60 minutes, 6 + 1 chars are needed.
EDL 00:00:00,000 01:00:00,000 | clipname | ......;
For example, use ←/→ on the dots, to seek by 10 minutes. You can draw a progress bar on the fly. Isn't that cool?
Then gi
, go
.
2.4 \c Vim Conceal: Hide the first 4 columns
... to stay more focused when listening to tape.
:set conceallevel=1 (or 2. For short, :set cole=1)
It's mapped to \ c
for your convenience.
See Also
- sc-im: spreadsheet in terminal
- a firefox podcast addon, useful to download mp3 files
- REFERENCE
- Python vs Vimscript gist
- Vimscript cheatsheet: https://devhints.io/vimscript
- BBC Paper Edit: Slides | github | bbcnewslab
- AVID Media Composer - PhraseFind Option
- https://podcast.adobe.com
- Steve Audette, ACE | Walter Murch
- https://github.com/bugbakery/audapolis
DEMO
- Never, never. Bilibili Youtube
cat V Dont.Look.Up Inglourious No.Country.for.Old.Men The.Bourne.Supremacy 谍影重重3 Notting.Hill | grep -e god -e love -e beep -e shit | sort
B
中文项目名
- 糙音速剪辑