marcan / blitzloop

Open source karaoke software
GNU General Public License v2.0
203 stars 31 forks source link

Enable multiple (synced) mpv windows #48

Closed jose1711 closed 3 years ago

jose1711 commented 3 years ago

Multimonitor systems are quite common these days so I wonder if something can be done to add support for multiple mpv windows (one per each monitor)

marcan commented 3 years ago

If you mean displaying the same thing on every monitor, wouldn't it make more sense to just set them all up as clones with xrandr (maybe add support to the KMS backend to do the equivalent thing too)?

Currently BlitzLoop tries to render fonts at the screen native resolution, but I don't think it makes any sense to try to duplicate the entire rendering process (plus the layout is slightly resoution-dependent, so that could be a mess). There's also vsync issues to handle, as different screens can have different refresh rates.

Multiple independent mpv instances aren't an option, because only one can be the audio sync master, and mpv does not have a way to feed it a sync source externally. It might be possible to just double render to multiple targets, but again, vsync is going to be a mess.

All in all, I think this is a big can of worms best left to output cloning, with BlitzLoop just treating things as a single screen with a single vsync.

jose1711 commented 3 years ago

Thank you - that xrandr tip really makes sense and I was able to setup a 3+1 layout really easily. obrázok

Now the question is if this is something that's worth integrating into blitzloop itself (save layout, change - defining the primary monitor only - others are to be mirrors, restore when blitzloop exists).

marcan commented 3 years ago

I think that belongs in a wrapper script a given user might use, similar to any required audio/JACK setup. BlitzLoop isn't really trying to be a self-contained system, but just the app that runs on it. It's up to the user to set things up around it, including things like song database pulling/updates/etc.

It does, however, make sense to document it in the examples about setting up dedicated systems.

jose1711 commented 3 years ago

This is not really a dedicated system - yet I kinda like 3 screens showing the same content. Here's a wrapper script I put together:

#!/bin/bash
# save current monitor layout
# mirror all monitors
# start blitzloop
# when blitzloop quits restore the original layout
#
shopt -s lastpipe

original_layout=$(
xrandr | awk 'BEGIN {printf "xrandr"
                     orientation="normal"}
             $2 != "connected" { next }
             {if ($3 == "primary") {output=$1" --primary"
                                    modepan=$4
                                    if ($5 ~ /^(left|right|inverted)/) { orientation=$5 }
                                   }
                                   else
                                   {output=$1
                                    modepan=$3
                                    if ($4 ~ /^(left|right|inverted)/) { orientation=$4 }
                                   }}
             {mode=modepan
              sub(/\+.*/, "", mode)
              # strip offset from mode
             }
             {printf " --output %s --mode %s --scale 1 --panning %s --rotate %s",
                       output, mode, modepan, orientation} 
               END {print ""}'
)

# monitor with largest number of pixels will be used as a "master"
# others will mirror it
xrandr | sed 's/ primary / /' | grep connected | \
  perl -lane 'next unless @F[1] eq "connected";
              $res=$area=@F[2];
              $area =~ s/([0-9]+)x([0-9]+)\+.*/$1*$2/e;
              $res =~ s/\+.*//;
              printf "%s %s %s\n", $area, $res, @F[0]' | \
    sort -nrk 1 | head -1 | read _ master_resolution master_output

echo "master out: ${master_output} ($master_resolution)"

blitzloop_layout=$(
xrandr | sed 's/ primary / /' | awk -v master_out="${master_output}" -v master_res="${master_resolution}" '
   BEGIN {printf "xrandr "}
   $2 != "connected" || $1 == master_out { next } 
   { output=$1
     printf " --output %s --same-as %s --scale-from %s",
               output, master_out, master_res
   }
   END {print ""}
   '
)

echo "${blitzloop_layout}" | awk 'system($0)'
blitzloop
echo "${original_layout}" | awk 'system($0)'
marcan commented 3 years ago

That sounds useful, want to throw it in a new subdirectory docs/scripts/ or something like that?

Though, what's up with the awk 'system($0)' at the end? Aren't those lines equivalent to just ${original_layout} etc?

jose1711 commented 3 years ago

Thank you, for some reason I did not realize bash is able to parse this correctly if I drop doublequotes.. silly.. Please see https://github.com/marcan/blitzloop/pull/53 for a PR.