Mirror (extend) desktop to KODI over LAN (xrandr / ffmpeg exercise)

I have a Raspberry 3B+ in my living room, which serves a bunch of functions.
One of its purpose is to be my media player (attached to TV via HDMI), so it runs KODI on Raspbian Buster.
Now another purpose for it: display something “projected” from a computer directly.
I intended it for looking at family photos on the TV.
So my solution which involves xrandr and ffmpeg as Lego bricks to play with…
First I create a virtual monitor on the computer, then set it to a desired resolution (FullHD):

xrandr --setmonitor VIRTUAL1 1920/508x1080/286+1920+0 VIRTUAL1;
xrandr --addmode VIRTUAL1 1920x1080; xrandr --output VIRTUAL1 --mode 1920x1080 --right-of eDP1

This works on my laptop, which has it’s main display with 1920x1080, called eDP1. The virtual monitor is placed beside the main display, on the right side.

Now the virtual monitor is there, but nowhere to see it :wink:
Here comes the ffmpeg part:

ffmpeg -f x11grab -s 1920x1080 -r 10 -i :0.0+1920,0 -vcodec libx264 -b:v 5600K -pix_fmt yuv420p -preset ultrafast -tune zerolatency -g 1 -f mpegts udp://192.168.1.8:5004?pkt_size=1016?buffer_size=65535

ffmpeg captures the content of the virtual monitor with a framerate of 10 (the higher the framerate, the less the choppyness on the “monitor”; also the less the delay; but the higher the cpu load on the computer), encodes to x264 only using I frames, the resulting bitrate is about 5.5Mbps, and streams it to the IP of the raspberry on udp port 5004.
The resulting latency is about 0.7s which is acceptable for me to project still images, it’s even OK for browsing the web. Definitely wasn’t good for a movie (NO youtube :smiley: ; low framerate) nor gaming (for that too high latency).
On the raspberry I created a .strm file containing:

udp://@192.168.1.8:5004

Opening that with KODI results playing the stream on TV, which is so basically showing my virtual monitor.

There’s room to fiddle with ffmpeg parameters to have bigger framerate or better image quality (at cost of CPU power on the streaming side, bandwidth on the (W)LAN ).

I have put the above into a script, called it screenmirror. Then another script, also possible to start using a desktop entry or shortcut:

#!/bin/sh
pkill screenmirror
xrandr --output VIRTUAL1 --off

that stops the mirroring/streaming.
I find this very pleasing; another proof of Linux being extremely flexible…
I forgot to mention, XnviewMP has dual monitor support, so having the browser on the built-in display of the laptop, while seening the picture fullscreen on the TV is very comfortable. Kind of ‘presenter mode’ … :slight_smile:

5 Likes