mpv-ytpb is an mpv hook to play and rewind YouTube live streams
interactively. The script detects ytpb://<STREAM>
links passed to the mpv
player, and launches the
ytpb-mpv socket listener
to handle the rewind functionality. A set of script key bindings allows to play,
mark, and export (TODO) past moments of live streams.
A screenshot of the script user interface. https://www.youtube.com/live/aofZxPM0l58.
mpv-ytpb requires ytpb to be
installed in your PATH
. Also, playing needs a custom mpv build with patched
FFmpeg (see xymaxim/ytpb#4 for details).
- Build a custom mpv: follow this compile instruction or use this container image
- Install ytpb:
$ pipx install ytpb
- Install ytpb-mpv:
$ pipx inject ytpb ytpb-mpv --include-apps
- Copy
ytpb.lua
to your mpv~~/scripts
directory
To update to the newer version of the script, do:
- Replace
ytpb.lua
with the new one - Upgrade the installed packages:
$ pipx upgrade --include-injected ytpb
$ mpv ytpb://<STREAM>,
where <STREAM>
is the YouTube video URL or ID of a live stream.
It will open a player with a stream playing and bind Ctrl+p
key to activate
the script main menu.
Rewinding to a moment in a stream is bound to r
key. It opens the date and
time picker with dynamically bound keys: select (LEFT
, RIGHT
) and change
(UP
, DOWN
) input parts, close (ESC
).
If cache=yes
is set in mpv.conf
(recommended), seeking works smoothly
within cached ranges as well as the mpv's A-B loop functionality with the
default keys.
Seeking backward and forward outside of cached ranges is possible with <
and
>
keys. The seeking by rewinding is a quick form of rewinding, with no need to
enter a target date. A user-defined, arbitrary offset is used instead. The
offset value can be changed with F
key.
The format of the input offset value (after F
pressed) is
[<days>d][<hours>h][<minutes>m][<seconds>s]
, where each part is optional, but
order must be preserved. For example: 1h
, 1h30m
, 120m
.
Taking screenshots is bound to s
key. The captured screenshot is saved in the
current directory to a file named <STREAM-ID>-<DATE>-<TIME>.jpg
, where times
are in UTC.
Mark mode can be enabled by marking a point with m
key. Points are labeled A
and B. Marking works in a cycle manner. The current point can be edited by
changing a position (after seeking or rewinding) with e
key. After points
selected, you can jump back to them with a
and b
keys.
By default, there is only one key available—it toggles the script main menu:
Ctrl-p
— activate and deactivate the main menu
After activation, the following key bindings are dynamically added:
r
— rewind to a date<
/>
— seek back and forward to a relative offsetF
— change a seek offset
m
— mark a new point labeled A or Be
— edit current pointa
/b
— go to point A or B
s
— take a screenshot and save to a fileC
— toggle clockT
— change global timezoneq
— quit
Rewinding and seeking actions are associated with sending the yp:rewind
script
message to ytpb-mpv and listening back to a yp:rewind-completed
message to
run a complete callback. At the same time, ytpb-mpv composes a new MPEG-DASH
MPD starting with a target media segment and executes the loadfile
command. The paused first segment is appeared on a screen, and the script seeks
to a start position. It would be nice to avoid
that short quirk and seek straight to the start position in the future.
The clock showing the date and time is not guaranteed to display the actual
time. Going into details, we rely on the Ingestion-Walltime-Us
metadata values
of the MPEG-DASH media segments. While the streaming latency can be specified
(TODO), there is another issue, more significant. In fact, the clock shows a
current playing offset relative to the MPEG-DASH MPD start time (the
Ingestion-Walltime-Us
value of the first media segment). If playing encounters
a gap, the playing timeline does not update according to new perturbed
timestamps after a gap. A workaround solution would be to add a key to sync a
clock (create and load a new manifest at the current time and continue playing).
The script is written in Fennel, a Lisp-like language that compiles to Lua.
The hook uses the python-mpv-jsonipc package to communicate with mpv via JSON-IPC.
The date and time picker was inspired by the seek-to.lua script.
The project is licensed under the MIT license. See LICENSE for details.