2

In mpv, there's the --start switch, which allows me to provide a number of seconds to skip. This way I can start playback at a random moment in a single file.

And there's --shuffle which allows me to start playback at a random file within a given playlist.

I combine both to:

  1. choose a random file and
  2. start playback at a random moment in that file

with this command line:

mpv --shuffle --start $POSITION --playlist=/tmp/list.m3u

Issue

However, the --start parameter will be considered for each and every file that follows later on in the list as well and those will also have their first X seconds skipped. I don't want that.

What I tried

Currently I invoke mpv twice, in sequence, but that's ugly.

Questions

Is there a way to have --start only affect the very first file played?

Or, even better, get mpv at a completely random moment in the random playlist. So, if the list is 123 minutes, it would start at 31 minutes 13 seconds, regardless of how far or not that would be into the file.

hc_dev
  • 131

2 Answers2

2

Using a socket, you could start the player in a paused state in the background:

# with playlist
mpv --shuffle --pause --input-ipc-server=/tmp/mpvsocket test.m3u &

without playlist, load a playlist

mpv --shuffle --pause --idle=yes --input-ipc-server=/tmp/mpvsocket & echo '{ "command": [ "loadfile", "test.m3u" ] }' | socat - /tmp/mpvsocket

Then seek to the start position of the current title (jumps to the start of the next title if greater than length)

# seek 100s forward (relative)
echo '{ "command": [ "seek", "+100" ] }' | socat - /tmp/mpvsocket

seek to 1:30 (absolute)

echo '{ "command": [ "seek", "1:30", "absolute" ] }' | socat - /tmp/mpvsocket

and unpause the player

echo '{ "command": [ "set_property", "pause", false ] }' | socat - /tmp/mpvsocket

Here is a little bash script mpvplay.sh that seeks to a random position of the first title and incorporates the above commands. You need socat, jq and shuf:

# start player in background
mpv --shuffle --pause --input-ipc-server=/tmp/mpvsocket "$@" &

wait until socket exists

while [ ! -S /tmp/mpvsocket ]; do :; done

sleep 0.5 # hack: wait a little longer

get duration of current title in seconds with fractional part, save as integer

duration=$(echo '{ "command": ["get_property", "duration"] }' | socat - /tmp/mpvsocket | jq -r '.data | floor') echo "title duration: $duration"

get random start position of title

duration=$(shuf -n1 -i0-"$duration") echo "random seek: $duration"

seek to position

echo '{ "command": [ "seek", "+'"$duration"'" ] }' | socat - /tmp/mpvsocket

unpause player

echo '{ "command": [ "set_property", "pause", false ] }' | socat - /tmp/mpvsocket

player to foreground

fg

Source the script with your playlist(s) as argument(s):

. ./mpvplay.sh playlist.m3u
Freddy
  • 25,565
0

Use the M3U directive for time-offset in your playlist file

Suppose your playlist is in M3U-format and contains multiple audio-files like the M3U Example 1 on Wikipedia:

#EXTM3U

#EXTINF:123, Sample artist - Sample title C:\Documents and Settings\I\My Music\Sample.mp3

#EXTINF:321,Example Artist - Example title C:\Documents and Settings\I\My Music\Greatest Hits\Example.ogg

Then you could add the start-offset, applied once for the playlist (not for each file), by adding the extended M3U directive for time-offset #EXT-X-START: TIME-OFFSET=0, where

The value of TIME-OFFSET is a signed-decimal-floating-point number of seconds.

Insert the time-offset into your playlist

To insert the offset-directive with your given environment-variable $POSITION at line 2, you could use sed on the command-line:

sed "2 i #EXT-X-START: TIME-OFFSET=$POSITION" /tmp/list.m3u

This results in the modified playlist with your custom time-offset position applied, like for example with time-offset of 1873 seconds:

#EXTM3U
#EXT-X-START: TIME-OFFSET=1873

#EXTINF:123, Sample artist - Sample title C:\Documents and Settings\I\My Music\Sample.mp3

#EXTINF:321,Example Artist - Example title C:\Documents and Settings\I\My Music\Greatest Hits\Example.ogg

When starting the playlist with an audio-player like mpv this should jump directly to your desired offset 1873 seconds:

So, if the list is 123 minutes, it would start at 31 minutes 13 seconds

hc_dev
  • 131