How to sync two looping videos with mplayer and upd?

1

1

I am trying to sync two instances of mplayer with -upd-master and -udp-slave, and notice that the slave staggers for about a second when the master begins the loop anew.

I am running debian 7.1 with MPlayer SVN-r36545 and here are my commands for the two videos running on the same i7 8GBram 240GB SSD machine (acting as a dhcp server):

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

denjello

Posted 2014-05-08T10:54:19.180

Reputation: 303

Answers

1

This was actually really tricky, because the problem was that the -loop 0 I had been using on the slave was actually waiting for the master to broadcast its position and sync up. In fact I talked to one of my friends who was one of the mplayer developers and he told me what I wanted to do was impossible.

So the hack that I ended up using was to constantly check the current position of the slave and just as it gets to the EOF restarting the file after a specific bit of sleep - which I had to tune by hand...

First to set up the master use this:

mplayer -udp-master -udp-ip 10.42.0.255 masterVideo.mp4 -loop 0

For the slave I used the following script:

#!/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

By the way, I am using a compiled mplayer - not mplayer2. Pause works very cleanly, as does skip... However, it is quite important that the two files have exactly the same duration and use the same codecs...

denjello

Posted 2014-05-08T10:54:19.180

Reputation: 303