Как синхронизировать два зацикленных видео с mplayer и upd?
Я пытаюсь синхронизировать два экземпляра mplayer с -upd-master и -udp-slave и замечаю, что slave колеблется около секунды, когда master заново начинает цикл.
Я использую Debian 7.1 с MPlayer SVN-r36545, и вот мои команды для двух видео, запущенных на одной машине SSD i7 8 ГБ 240 ГБ (действующей как dhcp сервер):
mplayer -vo xv -udp-master -udp-ip 10.42.0.255 -loop 0 Videos/HDV_0537.MP4
mplayer -vo xv -udp-slave -loop 0 Videos/HDV_0538.MP4
2 ответа
Это было на самом деле очень сложно, потому что проблема заключалась в том, что -loop 0
Я использовал на ведомом устройстве, фактически ожидал, что мастер передаст свою позицию и синхронизируется. На самом деле я разговаривал с одним из моих друзей, который был одним из разработчиков mplayer, и он сказал мне, что то, что я хотел сделать, было невозможно.
Таким образом, хак, который я использовал в итоге, состоял в том, чтобы постоянно проверять текущее положение ведомого устройства и так же, как это происходит, когда EOF перезапускает файл после определенного периода сна - который я должен был настроить вручную...
Сначала, чтобы настроить мастер, используйте это:
mplayer -udp-master -udp-ip 10.42.0.255 masterVideo.mp4 -loop 0
Для раба я использовал следующий скрипт:
#!/bin/bash
fifo="/tmp/fifo"
rm -rf $fifo
mkfifo $fifo
mplayer -nocache -slave -fixed-vo -idle -udp-ip 10.42.0.255 -udp-slave -udp-seek-threshold 0.5 -osdlevel 0 -input file=$fifo >$fifo.answer "slaveVideo.mp4" &
somepid=$!
echo $somepid
function getpos() {
local newpos=none
while ! [[ "$newpos" =~ ANS_TIME ]]; do
echo "get_time_pos" > $fifo
newpos=$(tail -n 1 $fifo.answer)
[[ "$newpos" =~ "EOF code: 1" ]] && { pos=-1; echo > $fifo.answer; return; }
pos=${newpos#ANS_TIME_POSITION=}
done
pos=${pos#0}
pos2=$(echo "$pos + 0.14" | bc )
printf "%.2f" "$pos2"
}
function getlen() {
local newlen=none
while ! [[ "$newlen" =~ ANS_LENGTH ]]; do
echo "get_time_length" > $fifo
newlen=$(tail -n 1 $fifo.answer)
len=${newlen#ANS_LENGTH=}
sleep 0.1
done
len=${len#0}
echo ${len}
}
len=$(getlen)
while true; do
pos=$(getpos)
if [[ $pos == $len ]]
then
# YOU MUST TWEAK THE FOLLOWING
# SLEEP TIME FOR YOUR MACHINE
sleep 0.5
echo "loadfile /media/media/1.mp4" > $fifo
fi
done
Кстати, я использую скомпилированный mplayer, а не mplayer2. Пауза работает очень чисто, как и пропустить... Однако очень важно, чтобы два файла имели одинаковую длительность и использовали одинаковые кодеки...
Сначала позволь мне поблагодарить тебя, чувак. Я использую mplayer на нескольких мониторах уже почти 15 лет. Мне просто так и не удалось заставить его работать, и я не нашел в Интернете ничего, что работало бы. Это было так смешно: почему никто никогда об этом не подумал?
Чувак, твой сценарий сработал, и я не мог в это поверить спустя столько времени! Большое спасибо, чувак! Я записал его в файлы masterVideo и подчиненное видео, добавил в файл аргументы командной строки, чтобы я мог также вызывать masterVideo и подчиненное видео с названием фильма. Я также добавил -volume 0 в подчиненный скрипт, потому что звук эхом разносился. Это грубо и хакерски, но работает!
На том же компьютере работает нормально... Сейчас пытаюсь использовать этот скрипт по сети, но он пока работает только на том же компьютере. Есть ли способ запустить подчиненное видео по сети, используя IP-адрес? Когда я пытаюсь, это работает, только если главный и подчиненный устройства находятся на одной машине. Вот точная ошибка
armel@shiva:~/tmp$ ../bin/slavedVideo movie.avi
76666
do_connect: could not connect to socket
connect: No such file or directory
Failed to open LIRC support. You will not be able to use your remote
control.
[mpeg4 @ 0x7f63c469c380]Requested frame threading with a custom
get_buffer2() implementation which is not marked as thread safe. This is
not supported anymore, make your callback thread-safe.
(standard_in) 1: illegal character: _
(standard_in) 1: syntax error
^C
MPlayer interrupted by signal 2 in module: sleep_timer
Я поискал его и в итоге поместил lirc=no в свой файл .mplayer/config, тогда фильм начинался с паузы, но не синхронизировался, и я получал эту ошибку. Фильмы представляют собой один и тот же файл.
armel@shiva:~/tmp$ ~/bin/slavedVideo movie.avi
936655
[mpeg4 @ 0x7fdb253d7380]Requested frame threading with a custom
get_buffer2() implementation which is not marked as thread safe. This is
not supported anymore, make your callback thread-safe.
^C
MPlayer interrupted by signal 2 in module: calc_sleep_time
Итак, я добавил к решению, но сеть не работает... Требуется ли какая-то дополнительная настройка, чтобы это работало по сети? Обе машины нормально подключены по ssh. Я понимаю, что этот пост был давным-давно, но все равно решил связаться и попробовать. То, что вы уже сделали, было чрезвычайно полезно, спасибо. :)