Skip to content

feat: add mpv playlist support#1755

Open
mbpowers wants to merge 1 commit into
pystardust:masterfrom
mbpowers:master
Open

feat: add mpv playlist support#1755
mbpowers wants to merge 1 commit into
pystardust:masterfrom
mbpowers:master

Conversation

@mbpowers

Copy link
Copy Markdown

Pull Request Template

Type of change

  • Bug fix
  • Feature
  • Documentation update

Description

Added an option -p or --playlist which adds episodes to a single mpv instance's playlist instead of spawning a new instance each episode. A new episode is only added to the mpv playlist when you have reached the last playlist entry and you haven't reached the end of the range i.e. get_episode_url will only run as needed to avoid spamming.

I neglected to update the README/Manpage yet because I am wondering about the implications of me adding the dependency socat for listening to the mpv IPC unix socket. Is this dependency justified? I am not familiar with how ani-cli works Windows and it seems like won't support this unix socket approach. In that case using netcat or something for tcp sockets could be best? Or would this be fine as unix only for now? And if no dependencies are justified for this then it could be possibly reworked with fifos and an mpv lua script, but since they block I think that would be more complicated with the current code structure, and that would still be unix only.

Anyways, I wanted to ask before messing with it more as I am happy with where this is at for my own purposes. Let me know if there are any suggestions or required changes

Checklist

  • any anime playing
  • bumped version

  • next, prev and replay work
  • -c history and continue work
  • -d downloads work
  • -s syncplay works
  • -q quality works
  • -v vlc works
  • -e (select episode) aka -r (range selection) works
  • -S select index works
  • --skip ani-skip works
  • --skip-title ani-skip title argument works
  • --no-detach no detach works
  • --exit-after-play auto exit after playing works
  • --nextep-countdown countdown to next ep works
  • --dub and regular (sub) mode both work
  • all providers return links (not necessarily on a single anime, use debug mode to confirm)

  • -h help info is up to date
  • Readme is up to date
  • Man page is up to date

Additional Testcases

  • The safe bet: One Piece
  • Episode 0: Saenai Heroine no Sodatekata ♭
  • Unicode: Saenai Heroine no Sodatekata ♭
  • Non-whole episodes: Tensei shitara slime datta ken (ep. 24.5, ep. 24.9)
  • All Providers: Youkoso Jitsuryoku Shijou Shugi no Kyoushitsu e (TV) (3 m3u8, 3 mp4, 1 fast4speed, 1 sharepoint)
  • The examples of the help text

@mbpowers mbpowers requested a review from Derisis13 as a code owner June 26, 2026 04:54
@port19x

port19x commented Jul 7, 2026

Copy link
Copy Markdown
Collaborator

This has been a desired feature for multi-ep handling in the past, but I can tell you right now that we're not merging a +89-15 diff

@port19x

port19x commented Jul 7, 2026

Copy link
Copy Markdown
Collaborator

If you're willing, playlist support for syncplay would also be valuable

@mbpowers

mbpowers commented Jul 7, 2026

Copy link
Copy Markdown
Author

So the size alone would be disqualifying? What size would be suitable?

A decent bit of the diff comes from extracting the title into "$media_title" and extracting the play_episode mpv case into play_mpv(). The actual added code is closer to ~60 lines and is mostly contained inside mpv_playlist_init() and mpv_playlist_wait() which only ever get called when -p is set.

The changes outside of extracting $media_title into a variable, mpv_playlist_init() and mpv_playlist_wait() include:

in cleanup()

[ -n "$playlist" ] && rm -f "$MPV_SOCKET"

only affects -p

in get_episode_url()

pids=""
for provider in $providers; do
    generate_link "$provider" >"$cache_dir"/"$provider" &
    pids="$pids $!"
done
if [ -n "$playlist" ]; then
    for pid in $pids; do
        wait "$pid"
    done
else
    wait
fi

previously

for provider in $providers; do
    generate_link "$provider" >"$cache_dir"/"$provider" &
done
wait

which now filters wait to wait for just the pids of generate_link so that the function does not wait on mpv to exit to generate links. Only affects -p.

in the play_episode() mpv case becomes

mpv*)
	if [ -n "$playlist" ]; then
	    if [ -z "$mpv_playlist_pid" ] || ! kill -0 "$mpv_playlist_pid"; then
	        mpv_playlist_init
	    else
	        [ -z "$episode" ] && return
	        send_mpv_ipc "{\"command\":[\"loadfile\",\"$episode\",\"append-play\",-1,{\"force-media-title\":\"$media_title\"}]}" >/dev/null 2>&1
	        mpv_playlist_wait
	    fi
	else
	    play_mpv
	fi
	;;

where the previous code was extracted into play_mpv. Only affects -p.

at the end of play_episode()

[ -n "$mpv_playlist_quit" ] && ep_no=$(( ep_no - 1 )) && return

because with -p we always fetch one episode ahead, if you quit early it must be adjusted back. $mpv_playlist_quit is only set with -p.

in the episode range loop in play() to quit early

if [ -n "$mpv_playlist_quit" ]; then [ -n "$exit_after_play" ] && exit || return; fi

again, $mpv_playlist_quit is only set with -p.


So I don't think any of my changes affect anything outside this feature, although a bit of code was moved around.

Also the shellcheck errors were in the previous commit I believe and rely on variable splitting to work.

Let me know if there is a path forward. If so I will take a look at syncplay

@port19x

port19x commented Jul 7, 2026

Copy link
Copy Markdown
Collaborator

We have a strong preference for brevity and consistently apply this priority to choose what feature requests to accept or reject.
Code size is a more important factor than feature utility in this way.

This is because ani-cli is a finished product and well into the maintenance phase from a lifecycle standpoint, so if we never add another feature again it's still a success.
Shorter features or very valuable features do get considered, but you'd have to propose something extraordinary to warrant the 10% increase in code size that you propose.

It should be noted that modifications to the readme and the man page don't count towards this limit

@mbpowers

mbpowers commented Jul 7, 2026

Copy link
Copy Markdown
Author

To explain why I think this feature is very desirable:

  • It allows you to maintain mpv settings that are changed while watching (volume, playback speed etc.)
  • Maintains a single mpv window so you do not need to mess with window positioning/swallowing behavior
  • Next episode url is prefetched and queued so no delay
  • Allows skipping forward/back episodes from within mpv and all episode urls stay cached in mpv

But either way, I understand the concern. Just let me know if there is something I can do to make it meet the requirements, like how much more concise it would need to be etc. cause I do think people would appreciate this feature, otherwise I am happy just using my personal fork.

@Derisis13

Copy link
Copy Markdown
Collaborator

I don't want to completely say no to this feature, I beleive it could be rather useful; as a refactor. Making it another bolt-on feature would be coutraproductive in my opinion too.

The way I would've approached it would have been to spawn a player process at startup, and only terminate it on shutdown. Next, previous, replay and list would be handled by socket commands to this player process.
The obvious problem to this approach is that mpv (and variants) and vlc are completely different, it'd require lots of code to test for both.

The issue was downloading. Implementing socket control for download would be ridiculous, but since downloanding was modified to quit after the requested episodes were downloaded, it can separate early in the control flow, and maybe not require too much extra code.

The other issue is android, @CoolnsX probably has the best idea if it'd work there or not. iSH is broken anyway, so I wouldn't sweat that.

So my personal approach would be to get rid of the old way of playing in favor of the new, make it so that it works with VLC, see if it works out or not, and then merge after a ton of testing.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants