balena-labs-projects / xserver

A simple X11 server block
Apache License 2.0
15 stars 13 forks source link

Issue showing 4K videos on Electron app #19

Open iKK001 opened 1 year ago

iKK001 commented 1 year ago

Running an Electron App, I try to display a 4K video in kiosk mode.

Everything works for Full-HD videos, but unfortunately not for 4K video ! (i..e there is violett flickering all over when running the 4K video)

Here is what I tried within my Electron App:

start.sh File looks like this (with the Chromium flags set):

#!/bin/bash
value="./node_modules/.bin/electron dist/src/main.js --ignore-gpu-blacklist --enable-native-gpu-memory-buffers --enable-gpu-rasterization --no-sandbox"

echo "STARTING ELECTRON"
exec $value

I also tried the --disable-gpu flag but without any change.

My Dockerfile.template looks as follows:

(please note the libraries 1mesa-utilsandmesa-utils-extra` - without them no video is playing at all.... So I assume the two libraries are needed but could also be limited at 4K ????? Any hint appreciated !)

(and please also note that I set the ENV-variable DISPLAY to :0 at the very bottom)

ARG NODEJS_VERSION="16"

# If we specify BALENA_MACHINE_NAME, when we do a 'balena push', it will automatically substitute the machine type into our variable, so that you can build it for more than one architecture.
FROM balenalib/%%BALENA_MACHINE_NAME%%-node:${NODEJS_VERSION}-run

RUN install_packages \
    curl \
    libasound2 \
    libdrm2 \
    libgbm1 \
    libgdk-pixbuf2.0-0 \
    libglib2.0-0 \
    libgtk-3-0 \
    libnss3 \
    libx11-xcb1 \
    libxss1 \
    libxtst6 \
    libgles2-mesa \
    libxshmfence1 \
    mesa-utils \
    mesa-utils-extra

WORKDIR /opt

RUN curl -skL https://raw.githubusercontent.com/balenablocks/audio/master/scripts/alsa-bridge/debian-setup.sh | sh

# Copy package files
COPY package.json yarn.lock /opt/
# Install node dependencies
RUN JOBS=MAX yarn install --unsafe-perm --production && yarn cache clean --force && rm -rf /root/.cache/*

# Now that we are done NPM installing, copy everything else
COPY . /opt/

COPY ./src /opt/

RUN yarn build

COPY ./dist /opt/

# We are running our entrypoint commands through the start.sh script, because we need to do a couple more things outside of just run electron
CMD ["bash", "/opt/start.sh"]

ENV NODE_ENV=production \
    # this is specific for balena, to let the startup script know we want to use all udev devices (mouse, keyboard, etc)
    UDEV=1 \
    # this is very important, we need to tell our environment that we are going to talk to display 0, which is hosted by the xserver block
    DISPLAY=:0

Inside my Electron App I use an index.html file that shows the video as follows:

<body style="overflow-y: hidden; overflow-x: hidden">
        <video autoplay loop id="video">
            <source id="video-src" />
        </video>
    <script src="./dist/src/renderer.js"></script>
</body>

My docker-compose.yml file looks as follows:

version: "2.1"
volumes:
    # we create a shared volume so that the xserver can mount its socket file, and our application container will be able to use it to display
    xserver-volume:
services:
    audio:
        image: bh.cr/my_images/trihow-audio
        privileged: true
        ports:
            - 4317:4317 # Only required if using PA over TCP socket
        labels:
            io.balena.features.dbus: "1"
            io.balena.features.kernel-modules: "1"
        environment:
            - DBUS_SYSTEM_BUS_ADDRESS=unix:path=/host/run/dbus/system_bus_socket
            - AUDIO_OUTPUT=alsa_output.hda-intel.hdmi-stereo
    wifi-connect:
        image: balenablocks/wifi-connect:amd64
        restart: always
        network_mode: host
        privileged: true
        labels:
            io.balena.features.dbus: "1"
            io.balena.features.firmware: "1"
        # environment:
            # - DBUS_SYSTEM_BUS_ADDRESS=unix:path=/host/run/dbus/system_bus_socket
            # somehow you can't connect with a custom name
            # - PORTAL_SSID=Trihow Player
    xserver:
        image: balenablocks/xserver
        restart: always
        privileged: true
        volumes:
            # when we start, a UNIX socket is mounted in this directory, for communication to the X server
            - xserver-volume:/tmp/.X11-unix
    sensor-box:
        build: trimini_sensorbox
        restart: always
        privileged: true
    custom-player:
        depends_on:
            # - audio
            - xserver
        build: .
        labels:
            io.balena.features.dbus: "1"
        restart: always
        privileged: true
        volumes:
            # We will have access to the UNIX socket shared by xserver after it has started up.
            - xserver-volume:/tmp/.X11-unix
        environment:
            # We need to specify which display we want to use for the X server. :0 is the first display that we have plugged in. This because there is no default display specified.
            - DISPLAY=:0
            - CURSOR=false
            - PULSE_SERVER=tcp:audio:4317
            - PULSE_SINK=alsa_output.hda-intel.hdmi-stereo
iKK001 commented 1 year ago

Looks like adding shm size did help !

Simply add the following to your main service inside the docker-compose.yml File:

shm_size: "1gb"

My 4K videos now play perfectly. This ticket can be closed. Thank you.