A fairly simple script that leverages more complex parsers to delete entries from playlist files after they have finished playing.
The main script only determines the type of playlist given and tries to call <filetype>-parser.lua
to handle the parsing code.
If it can't find an applicable parser, it will try to parse any playlist type the way mpv processes plaintext playlists. Notably: every line should be just an entry you can play by itself when using mpv <entry>
.
If this doesn't work, it notifies the user with an error
message and exits.
This script does not care about where it's being run from. So long as mpv can resolve the file names from the playlist, it's assumed this script can as well with no extra info
This script assumes that there is no shuffle applied. It was made with the intention of automating the entire process from acquiring anime down to watching the show without doing anything
other than pointing mpv to a playlist. I personally set up a simple script to run on download completion that automatically generates a file playlist.txt
which is just a list of file names
in the directory that don't match certain patterns. If you apply shuffle, make sure that the playlist format you use gets processed by a parser that isn't affected by shuffle.
Creating a playlist for it is as easy as redirecting the output of ls -1
(or dir
with the correct flags under Windows) to a text file,
or just aggregating all full paths for the media you want in it in a single file. One playlist entry per line, as per mpv's plaintext playlist handler.
Due to a limitation in mpv, you must pass the playlist file to --script-ops=yeetpls-playlist=<file>
. Thanks to the loadlist
internal input command, this script can replace
the need for an input file or the use of the --playlist
option. My own command is usually mpv --idle=once --script-opts=yeetpls-playlist=playlist.txt
. Setting idle=once
(or yes
) is a hard
requirement here, because mpv will NOT init any scripts if it's not allowed to idle. You could also set this option in your mpv.conf so that --idle=once
is always applied.
Optionally also pass the script-opt create_file=true
if it doesn't exist and you want it to be made. This option only works with some parsers, check the table.
If it doesn't exist and you don't pass this option, it will error and exit.
Current behavior is to bypass read check on the file and immediately open it in a+
for reading, appending and creating.
Currently, due to a limitation of mpv, the script is unable to fetch the playlist file provided with the --playlist
command line option. Because it's not good practice to gamble on how
a playlist file gets provided, the script currently requires a user to set a script-opt instead. The script-opt to be set is yeetpls-playlist
, as per the standard outlined on mpv.io to
automatically look for any script-opt named {script_name}-{opt_name}.
Yes, this means setting --idle=[once | yes]
and a script-opt. Don't complain to me about this, I'm just the messenger. I already sent in a feature request
to fix this, including all information I could get my hands on in regards to getting the playlist files.
Feel free to suggest other ways of attempting to get the file though!
A new parser for a type of playlist files should provide at least two functions:
format_pls
:- Arguments given to a parser are always the same, in the given order:
- The playlist as read from the file, as a string.
- This is the original file and entries have not yet been removed.
- The
playlist
object as returned by mpv'smp.get_property_native("playlist")
.- In Lua, this becomes an indexed table of tables:
- Top level:
ipair
s of a number and a table to determine the order; - Inner table:
pair
s of Stream Type (string) and the actual URL.
- The playlist as read from the file, as a string.
- The value returned should be a string that can be written to a playlist file, according to the playlist spec.
- Arguments given to a parser are always the same, in the given order:
test_format
:- Argument given for this function is always just the content of the file.
- The value returned should be a Boolean.
- If multiple format specs allow for the same parser to be used (m3u/m3u8 for example), an extra step is required:
- Mention this in any PR to add functionality
- Provide a list of all formats that match
- Explain why this shouldn't be a separate parser. Following m3u8 example: does mpv handle the charset internally?
- This will probably end up with a translation table of
format, parser
where there will be duplicate entries in the parser field- This is currently implemented in
main.lua
, line 36 and on. - For now, please make sure to only add parsers that work for multiple types of files, follow the m3u scheme.
- If a parser only applies to one playlist type, there's no need to add it. The proper checks are in place.
- Feel free to suggest a better fix :^)
- This is currently implemented in
- Provide an internal way of matching the spec
- Try to also match the current file content
- Examples include not adding optional fields that the file currently doesn't use
- Not dropping fields that could fairly easily be implemented
- If a file takes note of URL/local file/webstream, please try to match this in the output
- Do not throw errors if a file is a mismatch to the spec
- Use one of the
mp.msg
functions to notify the user of this. - Optionally print a single line message on the OSD
return false
makes main.lua attempt to use a fallback, if that fails it provides a clean exit.- This fallback may or may not break the entire input file, I might change this behavior later.
- Use one of the
Make sure to add these to the module's exported function list. The parser will be require
d as parser=require(type.."-parser")
, so if you don't expose parser.format_pls
, it can't be used.
Anything else you add to the module's export list will be ignored by main.lua
, but can be used by other parsers. Feel free to export any useful code.
Whatever else these parsers do internally is irrelevant, make them perform black magic for all I care. So long as it translates between mpv's internal playlist objects and the type of playlist it processes, this code is gonna be happy with it.
Parsers will never remove entries that have not been played.
- The 'Required' header informs you if a file is a hard requirement for using the script at all. The optional files extend functionality for this module.
- The 'Shuffle-safe' header denotes if shuffling in mpv affects the playlist file. If this says no, shuffle changes the order in the output.
- The 'Create' header informs you if a parser can be used to create new files. Use createFile at your own risk if it says no.
Parser | Formats | Required | Shuffle-safe | Create |
---|---|---|---|---|
txt-parser | txt, simple m3u. Basically just a list of files. | Yes | Yes | Yes |
pls-parser | pls | No | Yes | No |
m3u-parser | m3u(8), Extended m3u(8) | No | Yes | Yes (simple m3u) |