rpi-rgb-led-matrix icon indicating copy to clipboard operation
rpi-rgb-led-matrix copied to clipboard

MPV player conflicting with LED matrix

Open creating-worlds opened this issue 3 years ago • 1 comments

Hi there,

first of all thank you for this amazing library. It works like a charm!

My setup:

    options.rows = 32
    options.cols = 704
    options.chain_length = 1
    options.hardware_mapping = 'adafruit-hat-pwm'
    options.gpio_slowdown = 3
    options.brightness = 100
    options.pwm_lsb_nanoseconds=100
    options.pwm_bits = 7
    options.pwm_dither_bits = 0

Hardware:

Raspberry Pi 4
Raspberry Pi OS Bullseye (Headless)
Adafruit Bonnet with PWM fix

I am trying to play a video on an additional screen via HDMI (I am NOT trying to output a video on the Matrix). I am using the MPV Player (python-mpv) to output the video.

Here is my code (at least the important bits)

import mpv
import time
import threading
import socketio
import json
from rgbmatrix import RGBMatrix, RGBMatrixOptions, graphics

class SIO_Wrapper():
    current_channel = 0
    sio = socketio.Client()
   .......
    [MY SOCKETIO FUNCTIONS]
   .......

class VideoPlayer():

    def start_video_in_thread(self, video_name):
        thread = threading.Thread(target=self.play_video(video_name))
        thread.start()

    def play_video(self, video_name):
        print("start video")
        player = mpv.MPV(vo="gpu", gpu_context="drm", hwdec="rkmpp")  
        player.play("/path/to/vid/{}.mp4".format(video_name))
        player.wait_for_playback()
        print("stop video")

class MatrixManager():
    
    options = RGBMatrixOptions()
    options.rows = 32
    options.cols = 64
    options.chain_length = 1
    options.hardware_mapping = 'adafruit-hat-pwm'
    options.gpio_slowdown = 3
    options.brightness = 100
    options.pwm_lsb_nanoseconds=100
    options.pwm_bits = 7
    options.pwm_dither_bits = 0

    def __init__(self, *args, **kwargs):
        super(MatrixManager, self).__init__(*args, **kwargs)

    def initialize(self):      
        matrix = RGBMatrix(options = self.options)
        return matrix

if __name__ == "__main__":
    video_player=VideoPlayer()
    socket = SIO_Wrapper()
    socket.run()
    led_matrix = MatrixManager()
    matrix = led_matrix.initialize()

    while True:
        channel = socket.get_current_channel()
        if channel == 1:
            video_player.start_video_in_thread("TESTVIDEO")
            socket.set_current_channel(0)
            print("channel 0")   

First I thought this might be a threading issue with my socketio client but it turns out that there is a conflict with the matrix library. If I comment out matrix = led_matrix.initialize() the video plays perfectly. However, when the matrix was initialized before I try to play the video, it prints "start video" and without any output it prints "stop video" immediately after.

Do you have any idea why this is happening?

creating-worlds avatar Jan 27 '22 10:01 creating-worlds

I suspect you probably run into permission issues: when the matrix starts, it changes the permissions from root to an unprivileged user to minimize attack surface. However, if you then open files (such as, say, a movie file), that file needs to be able to be read by the new user (which is daemon).

So either make the file chmod a+r videofile.mp4 or set the runtime options of the matrix to not drop_privileges.

hzeller avatar Jan 28 '22 17:01 hzeller