Update metadata and transcripts through end of July 2026
Refreshed episodes/hosts/comments/series from hpr.sql, and added official HPR transcripts for the 180 episodes aired since the last sync (hpr4516-hpr4695).
This commit is contained in:
@@ -0,0 +1,139 @@
|
||||
Episode: 4585
|
||||
Title: mpv util scripts
|
||||
Source: https://hub.hackerpublicradio.org/ccdn.php?filename=/eps/hpr4585/hpr4585.mp3
|
||||
Transcribed: 2026-07-31 16:14:30 (official HPR transcript)
|
||||
|
||||
---
|
||||
|
||||
This is Hacker Public Radio Episode 4585, for 2026-02-27
|
||||
Today's show is entitled, "mpv util scripts"
|
||||
The host is candycanearter and the duration is 00:11:55
|
||||
The flag is Clean, and the license is CC-BY-SA
|
||||
The summary is "a collection of hand-written scripts for mpv and explaining how the mpv api works"
|
||||
There are some programs that act as a cornerstone, a little next to meody, like Vim or Emacs,
|
||||
deserve some publicity and high levels of extendability. One of these options is really better,
|
||||
but today we're talking about a different program that I think deserves more attention for its
|
||||
flexibility. That program isn't baby-y, simply described as a media player in its documentation.
|
||||
Despite the name, it has tons of support for everything from DVDs to HLS streams to even YouTube
|
||||
support and has been fantastic for my daily use cases. I wanted it to show off some scripts
|
||||
I had written in order to display how I took advantage of the flexibility and to potentially
|
||||
provide a starting point for others who MPV the poor scripts in three different languages,
|
||||
being Lua, JavaScript, and C. Regardless of which language you're using,
|
||||
the underlying framework is similar. The cornerstone of scripting an MPV is properties.
|
||||
Nearly every feature of MPV is exposed through some property or another,
|
||||
and it can be things that first termed a video, setting, or even state flags.
|
||||
There's also a dedicated property and for you to find a global, that can be written to
|
||||
by any script, and it's liberally not touched by the player. The generalization of many different
|
||||
pieces of info to his property to them makes scripting much easier as all data can be forced through
|
||||
to think where and point. Property is probably able to be affirmed. This is done through the
|
||||
of variable property function, which calls the given function whenever the property is updated through
|
||||
any source. This can be used for anything from when the player goes into a certain state
|
||||
from when the mouse is moved thanks to the flexible property system. Register event runs the given
|
||||
function on a global event. This is for state changes that like a fouling started or stopped
|
||||
or thinking operations, and it's generally a more live away to detect such global state
|
||||
tuned over using a property. Added hook is an experimental feature, but it is required for
|
||||
certain cases. Unlike other hooks, it is blocking, which can be important for preventing
|
||||
waste conditions. Register script message, expose that a user-thread function under
|
||||
the given name and can be activated from the command line or through a key bind. Added time
|
||||
out an ad periodic timer are the most basic hooks, calling the function once or repeatedly
|
||||
for a given number of time. The other command that are important are get and set property
|
||||
native, which read and write two properties. Command, which runs the command within the MPV
|
||||
console syntax, LST method, which displays a message to the user on the top left.
|
||||
These nine functions make up the majority of the interaction with the MPV core.
|
||||
So we have the button blocks. Let's see what we can do with them.
|
||||
A and a square profit that Lua doesn't do much on the phone, but it sets up properties for
|
||||
other scripts to use. In particular, it watches for when the path and play time remaining,
|
||||
property of or being written to, parses the data out of it, and then writes the data to
|
||||
user data properties that can be used by other scripts. Getting into this script selects
|
||||
to do stuff A and a square aspect ratio at Lua. MPV by default has the geometry property,
|
||||
which may written to you to change the window size. However, did geometry either set to the
|
||||
value, whenever any fellow said it, which can be annoying if you would previously resize the window.
|
||||
Wet the script is doing its useful. First, it watches a geometry variable and make sure it
|
||||
is of a specified aspect ratio. This allows you to do things that like specify the geometry as
|
||||
the percent of the screen without having to be calculated by use manually. It also resets a geometry
|
||||
value to the current window size, whenever new fellow voted, in order to prevent random recitals.
|
||||
First, the target aspect ratio is stored in local variables. This technically should be described
|
||||
off system, but for a personal script, I didn't want to go through the treble of implementing it.
|
||||
The reset gem function is simply gets the current dimensions of the window, and writes it to
|
||||
the geometry. The dimension hop function does a heavy lifting of calculating the aspect ratio
|
||||
in writing a new geometry 5 if needed. Then the function are just registered to the corresponding
|
||||
properties and events to make it work. Next, the audiovisual. By default, MPV only displays a black screen
|
||||
when playing audio files of no associated video track, which is lame. Fortunately, MPV also supports
|
||||
assigning an arbitrary FFM pedic photographs, so we can rectify that. Due to FFM pedic limitations
|
||||
of every input having to be filled, this program actually requires a default cover file with
|
||||
the name covered up PNG to be put either in your home directory or in the MPV config directory.
|
||||
The one that I drill and made will be in the show notes. The script is split in the two different
|
||||
functions. That being one that handled adding the missing cover is needed, and one that actually
|
||||
assigns the filter graph. First, a look-up table of images to the main is put in the top of the
|
||||
function. This is the useful for network streams that do not provide a cover image, such as this
|
||||
podcast for some reason. Because the command to add the image stream returns a false value if the image
|
||||
can't be found, we can use a suit check whether the given image exists and provide a fault
|
||||
that option is not. You also try to add the FFM from the domain, but this will most likely fail.
|
||||
Since there is no way to parse HTML, we simply try to access FFM.itio into domain root.
|
||||
Finally, it just adds the cover image if all other methods have failed. Inject needed,
|
||||
it's a function that actually does most of the work. First, it scans your all the tracks in the
|
||||
track list, and if there is a video track, then it simply returns without doing anything.
|
||||
If there is no image track present, then it calls resolve within cover with the domain paths
|
||||
that we have assigned in a props.lua. Finally, it writes the filter graph.
|
||||
Now, this isn't a filter tutorial, but in essence, what is this doing is scaling the image up
|
||||
to 250 thick by 250 thick if it's smaller, using nearest neighbor, and then scaling it to a width of
|
||||
720. This width is big enough that the element on the screen do not look too blurry.
|
||||
We'll also be following us that doesn't overload the RAM. Then it calls it's a built-in audio
|
||||
visual either, and overlay it with the image. This uses ad hook since the function needs to be run
|
||||
after the tracks have been parsed, but before the videos are playing, then the F event will crash
|
||||
if it's missing a source. A and F are playing with that lua, it's just um,
|
||||
either function I defined it in order to help with playlists ordering. The full clear is simply
|
||||
clear is a playlists and resets MPV to an idle site is, and playlists next to last simply moves
|
||||
at the next element in the playlists to the end of it. A, R, C, Fill, dot lua,
|
||||
or relative cash fill. This makes the winning for cash state a little bit more dynamic.
|
||||
By default, when the network screen runs out of cash, MPV will simply wait for one second
|
||||
of the cash to be filled before playing again. In most cases, this is fine, when playing a
|
||||
flow stream, it's a constant starting and stopping and can be distracting. This script changes
|
||||
how much cash the cash waits for before playing again, based on the current cash speed,
|
||||
the bit rate, and the speed. The audio and video bit rate are thumbed and multiplied by the current
|
||||
playback speed, and then multiplied by 3 in order to give some extra room for the cash. That's
|
||||
then divided by the current download speed, and they clamped to 20 seconds maximum, and are
|
||||
supervented from rating forever. Then, erase the cash cause of the weight property and deflate
|
||||
an OSB message. Also note that it writes to a file local options instead of the default cash
|
||||
cause weight. This means that it's reset after the file is loaded. Jump to E-Cash is another
|
||||
either hub or function that sets a playback to 5 seconds before the cash is done. This is very useful
|
||||
for things like live streams. Last and thirdly not least, is a ton of art at the wall,
|
||||
which writes to the title bar. By default, MPV uses the title property in order to set what
|
||||
the title bar displays, which uses property expansion. For update expansion, define special characters
|
||||
that expand to whatever the property of fallen. By default, property expansion contains some
|
||||
logical operations that like checking if a property is set to a third value, but with scripting,
|
||||
we can go further and make it even more dynamic. When the function is first started on startup,
|
||||
it writes the current value of the title property to a special user data variable. This is
|
||||
thought that the user can still set a title bar for things like the idle state. Everything related
|
||||
to updating the title dynamically is handled by a function title update. First, the media title property
|
||||
is checked, and if it's not that, that no file is currently loaded. So, we set the title to the
|
||||
previously saved default title and return. Next, the current playlist position is retrieved,
|
||||
and if it's not negative one, the subtracted it from the current playlist count to get the number
|
||||
of files remaining in the playlist. Negative one is a special case, meaning no playlist is loaded.
|
||||
Next, the play time remaining at property if retrieved, and if it's not set,
|
||||
we assume that we're currently loading the file. So, we just display the currently loading title,
|
||||
and one left a number of files remaining in the playlist if it was set. And earlier return.
|
||||
Everything produced by on is for contracting the title bar, for a file that's currently being played.
|
||||
The progress number is the most dynamic part of the script. By default, it displays the current
|
||||
position in the file from 0 to 100%. However, after it's less than 100 seconds left of playback,
|
||||
then it instead displays the number of seconds until the file is over. It also uses the
|
||||
prepping doubts that up in a underscore props. Apparently, it's also displayed the number of seconds
|
||||
behind real time a livestream at being played, since those were by constantly updating the end
|
||||
time of the file. Finally, if the player is popular cash, then it displays the percentage of cash
|
||||
until it'll start playing again. If the the MOOC's are the network property is set, then it also
|
||||
displays the cash speed or download speed of the file. Finally, if the domain path, which we set
|
||||
in a underscore props, is set, we also display the host name of the file being played. Finally,
|
||||
we set title to the concatenation of all of the different variables, and we're done.
|
||||
Thankfully, Louis isn't as strict as, say, JavaScript, or a fee yet about 5-inch signatures. So,
|
||||
we can assign a title update function to a myriad of different properties and events,
|
||||
as well as a periodic timer, just in case. Title update only shows the template of the title,
|
||||
not how fast the values in the title are being updated. Keep that in mind if you want to extend
|
||||
this one. Hopefully, this episode aspires you to try out MPB and try your hand out the
|
||||
wascripting. Even if you're not an expert in coding, Louis is one of the easiest languages to get into.
|
||||
And crafting your own customized media player is a surprisingly easy goal to achieve for even
|
||||
for a first timer. You just have to be patient. Happy MPB-Aing and have some good.
|
||||
You have been listening to the Hacker Public Radio podcast, at hackerpublicradio.org.
|
||||
Today's show was contributed by a HPR listener like yourself.
|
||||
If you ever thought of recording a podcast, then visit the HPR site to find out how easy it really is.
|
||||
Hosting for HPR has been kindly provided by anhonesthost.com, the Internet Archive, rsync.net, and the HPR Community Content Delivery Network.
|
||||
Unless otherwise stated, today's show is released under a Creative Commons Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.
|
||||
Reference in New Issue
Block a user