- Вопрос или проблема
- Проблема
- Что я попробовал
- Вопросы
- Используйте директиву M3U для смещения времени в вашем плейлист-файле
- Вставьте смещение времени в ваш плейлист
- Ответ или решение
- 1. Использование сокета для взаимодействия с mpv
- 2. Ожидание создания сокета
- 3. Получение длины текущего трека
- 4. Генерация случайного момента
- 5. Переход к случайному моменту
- 6. Возобновление воспроизведения
- 7. Автоматизация через скрипт
- 8. Использование в м3у плейлистах
- Заключение
Вопрос или проблема
В mpv
есть параметр --start
, который позволяет мне указать количество секунд для пропуска. Таким образом, я могу начать воспроизведение с произвольного момента в одном файле.
Также есть --shuffle
, который позволяет начать воспроизведение с произвольного файла в заданном плейлисте.
Я совмещаю оба параметра, чтобы:
- выбрать случайный файл и
- начать воспроизведение с произвольного момента в этом файле
с помощью следующей команды:
mpv --shuffle --start $POSITION --playlist=/tmp/list.m3u
Проблема
Однако параметр --start
будет применяться ко всем файлам, которые идут позже в списке, и они также будут пропускать первые X секунд. Я этого не хочу.
Что я попробовал
На данный момент я вызываю mpv
дважды, последовательно, но это некрасиво.
Вопросы
Существует ли способ сделать так, чтобы --start
влиял только на самый первый воспроизводимый файл?
Или, что еще лучше, запустить mpv с совершенно случайного момента в случайном плейлисте. Так что, если список длится 123 минуты, он начнется на 31 минуте 13 секунде, независимо от того, насколько далеко это будет в файле.
Используя сокет, вы можете запустить плеер в приостановленном состоянии в фоновом режиме:
# с плейлистом
mpv --shuffle --pause --input-ipc-server=/tmp/mpvsocket test.m3u &
# без плейлиста, загрузить плейлист
mpv --shuffle --pause --idle=yes --input-ipc-server=/tmp/mpvsocket &
echo '{ "command": [ "loadfile", "test.m3u" ] }' | socat - /tmp/mpvsocket
Затем перейдите к начальной позиции текущего титула (перейдите к началу следующего титула, если больше длины)
# перемотка на 100 секунд вперед (относительно)
echo '{ "command": [ "seek", "+100" ] }' | socat - /tmp/mpvsocket
# перемотка на 1:30 (абсолютно)
echo '{ "command": [ "seek", "1:30", "absolute" ] }' | socat - /tmp/mpvsocket
и разбудите плеер
echo '{ "command": [ "set_property", "pause", false ] }' | socat - /tmp/mpvsocket
Вот небольшой bash-скрипт mpvplay.sh
, который перематывает к случайной позиции первого титула и включает в себя приведенные выше команды. Вам понадобятся socat
, jq
и shuf
:
# запуск плеера в фоновом режиме
mpv --shuffle --pause --input-ipc-server=/tmp/mpvsocket "$@" &
# ждем пока сокет не появится
while [ ! -S /tmp/mpvsocket ]; do :; done
sleep 0.5 # хак: подождите немного дольше
# получите продолжительность текущего титула в секундах с дробной частью, сохраните как целое число
duration=$(echo '{ "command": ["get_property", "duration"] }' | socat - /tmp/mpvsocket |
jq -r '.data | floor')
echo "длительность титула: $duration"
# получите случайную начальную позицию титула
duration=$(shuf -n1 -i0-"$duration")
echo "случайная перемотка: $duration"
# перемотка на позицию
echo '{ "command": [ "seek", "+'"$duration"'" ] }' | socat - /tmp/mpvsocket
# разбудите плеер
echo '{ "command": [ "set_property", "pause", false ] }' | socat - /tmp/mpvsocket
# плеер на передний план
fg
Загрузите скрипт с вашими плейлистами в качестве аргументов:
. ./mpvplay.sh playlist.m3u
Существует ли способ сделать так, чтобы –start влиял только на самый первый воспроизводимый файл?
Вы можете привязать нажатие клавиши для перемотки к случайной точке в файле на основе длительности или relative-percent
-- scripts/misc.lua
mp.add_key_binding("m", "random-seek-duration", function()
local duration = mp.get_property_number("duration")
mp.commandv("seek", math.random() * duration, "absolute")
end)
mp.add_key_binding("o", "random-seek", function()
mp.commandv("seek", math.random() * 10, "relative-percent")
end)
Согласно документации mpv, должно быть возможно сделать что-то, что будет автоматически запускаться: https://mpv.io/manual/master/#command-interface-start-file
function my_fn(event)
if event.playlist_entry_id == 1 then
mp.commandv("seek", math.random() * 100, "relative-percent")
end
end
mp.register_event("start-file", my_fn)
Чтобы запустить это условно, вы можете сохранить его вне папки скриптов и затем запустить с --script
, когда вам это нужно: https://mpv.io/manual/master/#options-scripts
Используйте директиву M3U для смещения времени в вашем плейлист-файле
Предположим, ваш плейлист находится в M3U-формате и содержит несколько аудиофайлов, как в примере M3U 1 на Википедии:
#EXTM3U
#EXTINF:123, Примерный артист - Примерный заголовок
C:\Documents and Settings\I\My Music\Sample.mp3
#EXTINF:321, Примерный артист - Примерный заголовок
C:\Documents and Settings\I\My Music\Greatest Hits\Example.ogg
Тогда вы можете добавить смещение начала, примененное один раз для плейлиста (не для каждого файла), добавив расширенную директиву M3U для смещения времени #EXT-X-START: TIME-OFFSET=0
, где
Значение TIME-OFFSET – это знаковое число с плавающей запятой в секундах.
Вставьте смещение времени в ваш плейлист
Чтобы вставить директиву смещения с вашей переменной окружения $POSITION
на строку 2, вы можете использовать sed в командной строке:
sed "2 i #EXT-X-START: TIME-OFFSET=$POSITION" /tmp/list.m3u
В результате получится измененный плейлист с примененным вашим пользовательским смещением времени, как, например, со смещением времени 1873
секунды:
#EXTM3U
#EXT-X-START: TIME-OFFSET=1873
#EXTINF:123, Примерный артист - Примерный заголовок
C:\Documents and Settings\I\My Music\Sample.mp3
#EXTINF:321, Примерный артист - Примерный заголовок
C:\Documents and Settings\I\My Music\Greatest Hits\Example.ogg
При запуске плейлиста с аудиоплеером, таким как mpv, это должно перемотать непосредственно к вашему желаемому смещению 1873
секунды:
Таким образом, если список длится 123 минуты, он начнется на 31 минуте 13 секунде
Ответ или решение
В mpv действительно можно начать воспроизведение с произвольного момента в плейлисте, используя комбинацию опций. Давайте рассмотрим, как это сделать, чтобы ваш плейлист начинался с случайного момента в случайно выбранном файле.
Для этого подхода вам понадобятся следующие шаги:
1. Использование сокета для взаимодействия с mpv
Сначала мы начнём с того, что запустим mpv с опцией --shuffle
для случайного выбора файла и --pause
для приостановки воспроизведения. Используем сокет для управления mpv:
# Запуск mpv с плейлистом в фоновом режиме
mpv --shuffle --pause --input-ipc-server=/tmp/mpvsocket ваш_плейлист.m3u &
2. Ожидание создания сокета
Далее, необходимо подождать, пока сокет будет создан:
while [ ! -S /tmp/mpvsocket ]; do :; done
sleep 0.5 # Дополнительная пауза
3. Получение длины текущего трека
Теперь давайте получим длительность текущего трека:
duration=$(echo '{ "command": ["get_property", "duration"] }' | socat - /tmp/mpvsocket | jq -r '.data | floor')
4. Генерация случайного момента
Генерируем случайный момент, до длительности трека, используя shuf
:
random_position=$(shuf -n1 -i0-"$duration")
5. Переход к случайному моменту
Далее, мы можем использовать команду seek
для перехода к генерированному моменту:
echo '{ "command": [ "seek", "'"$random_position"'" ] }' | socat - /tmp/mpvsocket
6. Возобновление воспроизведения
В конце, мы просто снимаем паузу:
echo '{ "command": [ "set_property", "pause", false ] }' | socat - /tmp/mpvsocket
7. Автоматизация через скрипт
Вы также можете создать скрипт mpvplay.sh
, который будет выполнять все эти шаги автоматически. Вот пример такого скрипта:
#!/bin/bash
# Запуск mpv
mpv --shuffle --pause --input-ipc-server=/tmp/mpvsocket "$@" &
# Ждем, пока сокет доступен
while [ ! -S /tmp/mpvsocket ]; do :; done
sleep 0.5
# Получение длительности текущего файла
duration=$(echo '{ "command": ["get_property", "duration"] }' | socat - /tmp/mpvsocket | jq -r '.data | floor')
# Генерация случайного времени
random_position=$(shuf -n1 -i0-"$duration")
# Перейти к случайному моменту
echo '{ "command": [ "seek", "'"$random_position"'" ] }' | socat - /tmp/mpvsocket
# Возобновление воспроизведения
echo '{ "command": [ "set_property", "pause", false ] }' | socat - /tmp/mpvsocket
# Перемещение на передний план
fg
8. Использование в м3у плейлистах
Если вы используете плейлисты в формате M3U, вы также можете вручную вставить директиву для тайм-офсета, добавив строку:
#EXT-X-START: TIME-OFFSET=0
Эта директива применяется к первому файлу в плейлисте, но для достижения большей гибкости мы рекомендуем всё же использовать подход с сокетом, описанный выше.
Заключение
Теперь вы знаете, как запускать mpv с воспроизведением с случайного момента в случайном файле плейлиста, используя комбинацию команд и скриптов. Это решение позволяет управлять воспроизведением более адаптивно и интересно. Если у вас есть дополнительные вопросы или нужен более сложный сценарий, пожалуйста, дайте знать!