Skip to content

Latest commit

 

History

48 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

VLC Timestamp Notes

VLC already takes screenshots. It does not remember when in the video each one was taken — snapshots are named by wall-clock time, so an hour later you have a folder of PNGs and no way back to the moment.

This plugin closes that gap. Press the snapshot key while watching: the video pauses, the frame is saved, and it is paired with the exact media position to the millisecond. Type a note, and playback resumes.

macOS, VLC 3.x. Tested against 3.0.23. install.sh uses defaults write, which is macOS-only.

What you get

A folder beside the video, holding a notes.md you can read in any Markdown editor:

<!-- generated by VLCNotes - edits here are overwritten on the next capture -->

# lecture01.mp4

`/Movies/lecture01.mp4`

## 00:12:34.080

![00:12:34.080](00-12-34-080.png)

the bit about eigenvalues

## 00:19:07.512

![00:19:07.512](00-19-07-512.png)

Install

Quit VLC first. VLC rewrites its preferences from memory when it quits, so installing while it runs would silently undo the setting that enables the plugin. install.sh checks and refuses if it finds VLC running.

git clone https://github.com/TsungChiCheng/VLC_snapshot_plugin
cd VLC_snapshot_plugin
./install.sh

This copies the plugin into VLC's Lua directory and enables the watcher — the background loop that detects snapshots and writes notes:

defaults write org.videolan.vlc extraintf -string "luaintf"
defaults write org.videolan.vlc lua-intf  -string "vlcnotes_watcher"

Without that, the plugin looks installed and does nothing; the panel reports "Watcher not running." To set it by hand instead: VLC → Preferences → Show All → Interface → Main interfaces, tick Lua interpreter, then under Lua set Lua interface to vlcnotes_watcher.

Start VLC afterwards — preferences only take effect on the next launch.

The installer also offers to bind a shortcut for opening the panel. It is opt-in, because it can overwrite a shortcut you already assigned to that menu item. Pass --bind-key or --no-bind-key to skip the prompt.

Use

⌘⌥S Capture. Saves the frame, records the position, pauses playback.
⌥⌘N Open the notes panel (if you accepted the shortcut at install).

Or open the panel from VLC menu → Extensions → VLC Timestamp Notes. That is the application menu at the top-left beside the Apple logo — not the View menu; extensions live under the app menu on this build.

To annotate: pick a capture in the dropdown, press Load selected, type in the note box, press Save Note. Playback resumes.

You do not have to annotate immediately. Capture as often as you like and come back later — every capture is already saved with its timestamp, with or without a note.

The panel also has Export HTML, which writes a notes.html contact sheet of every screenshot and note.

Where notes land

For /Movies/lecture01.mp4:

/Movies/lecture01.notes/
    notes.json          source of truth
    notes.md            generated — do not hand-edit, it is overwritten
    notes.html          generated by Export HTML
    00-12-34-080.png    HH-MM-SS-mmm

Move the video and take the folder with it. If the video's directory is not writable — a network share, a DVD — everything goes to ~/VLCNotes/<name>/ instead, and the real path is recorded inside notes.json.

notes.json is the source of truth. notes.md and notes.html are regenerated from it, so hand-edits to those two are lost on the next capture. Edit notes through the panel, or edit notes.json directly with VLC closed.

Limitations

Worth knowing before you rely on it:

  • The panel cannot raise itself. A VLC extension has no timer and no event loop — it runs only when you click something in it. Capturing pauses the video, but you bring the panel up yourself (⌥⌘N, or the menu). This is a VLC architecture limit, not an oversight: playing-listener and meta-listener were both measured and neither fires. See docs/spike-findings.md.
  • A note can be lost if you save it at the exact moment a capture lands. The panel and the watcher both write notes.json without locking. Writes are atomic, so the file is never corrupted, but one of two simultaneous updates can win. In practice this needs sub-second timing.
  • Changing the plugin needs a full VLC restart. Extensions and interface scripts are compiled once at launch; reopening the panel re-runs cached code.
  • macOS only. The core modules are portable Lua, but the paths, the installer and the menu locations are not.

Uninstall

Quit VLC first, same reason as install.

./uninstall.sh

Removes the plugin's files and reverts the preferences install.sh set — only if they still point at this plugin, and the keyboard shortcut is removed by subkey so any other bindings you have survive. Your notes folders, and ~/VLCNotes, are never touched.

Development

brew install luajit luarocks
luarocks --lua-version=5.1 --local install busted
luarocks --lua-version=5.1 --local install dkjson 2.1
export PATH="$HOME/.luarocks/bin:$PATH"
busted

150 tests. The versions are pinned deliberately: VLC 3.0.23 embeds Lua 5.1 and bundles dkjson 2.1, and the suite runs against both so a test cannot pass here and fail inside the player. Homebrew's default lua is 5.5, where unpack is nil — testing against it gives false confidence in the dangerous direction.

Two guards enforce this, and both fail loudly:

  • spec/environment_spec.lua — fails if Lua 5.1 or dkjson 2.1 drift.
  • spec/purity_spec.lua — fails if any of the four core modules starts calling into vlc.*.

Layout

src/lua/modules/vlcnotes/   timecode, paths, store, render   pure Lua, unit-tested
                            fs                               the VLC filesystem adapter
src/lua/intf/               vlcnotes_watcher.lua             the only loop; owns all capture
src/lua/extensions/         VLCNotes.lua                     the panel

The four pure modules take everything they need — filesystem access, home directory — as plain arguments, which is what makes them testable outside VLC at all. fs.lua is the one module allowed to touch vlc.io. The watcher and the panel cannot be unit-tested; they are verified against docs/manual-checklist.md.

Both VLC-facing scripts require "vlcnotes.<module>" directly — VLC puts lua/modules/ on the Lua package.path for interface scripts and extensions alike, so there are no vendored copies.

Documentation

docs/2026-08-13-vlc-timestamp-notes-design.html the design spec
docs/spike-findings.md measured VLC platform quirks — read before touching the VLC-facing files
docs/manual-checklist.md manual verification for the watcher and the panel

Licence

MIT.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages