Screenly / Anthias

The world's most popular open source digital signage project.
https://anthias.screenly.io
Other
2.51k stars 623 forks source link

Alert `Server Error: global name 'mplayer' is not defined` appears when adding a RTSP URL asset. #1638

Open nicomiguelino opened 2 years ago

nicomiguelino commented 2 years ago

Overview of the Issue

Web UI

Alert Server Error: global name 'mplayer' is not defined appears when adding a RSTP URL asset. (See screenshot below for details.)

image

Logs

From the srly-ose-server service...

screenly-srly-ose-server-1  | Traceback (most recent call last):
screenly-srly-ose-server-1  |   File "server.py", line 672, in api_view
screenly-srly-ose-server-1  |     return view(*args, **kwargs)
screenly-srly-ose-server-1  |   File "/usr/local/lib/python2.7/dist-packages/flask_restful_swagger_2/swagger.py", line 219, in inner
screenly-srly-ose-server-1  |     return f(self, *args, **kwargs)
screenly-srly-ose-server-1  |   File "server.py", line 1002, in post
screenly-srly-ose-server-1  |     if not asset['skip_asset_check'] and url_fails(asset['uri']):
screenly-srly-ose-server-1  |   File "/usr/src/app/lib/utils.py", line 228, in url_fails
screenly-srly-ose-server-1  |     run_mplayer = mplayer('-identify', '-frames', '0', '-nosound', url)
screenly-srly-ose-server-1  | NameError: global name 'mplayer' is not defined

Reproduction Steps

Steps to reproduce this issue, eg:

Environment

vpetersson commented 2 years ago

Good filing. So I guess we have two options available:

The downside with the first option is that we would rely on a completely different software for checking that the feed works (which I presume what the server code does), versus the actual playback.

I don't have a super strong option either way, but the second option seems purest, but 'vlc' is likely more limited for these kind of programmatic tasks than 'mplayer'.

akkie70 commented 1 year ago

Hi is there an working workaround for this issue?

vpetersson commented 1 year ago

Good question. I think @nicomiguelino might have temporarily disabled RTSP while debugging video playback on pi 4. In theory it should work but clearly needs more testing.

akkie70 commented 1 year ago

Actually i have set up an new rpi3B+ with screenly master@f6311f9. And i got the same error message. So i thought it is a bug in the latest version of screenly ose

akkie70 commented 1 year ago

In mediaplayer.py found i one reference to mplayer? Is there any other reference i didnt see? i changed it to vlc but is gives me the same error as mentioned above.

Is the master version using python2.7 or python3.9?

akkie70 commented 1 year ago

@vpetersson Can you mark this as bug ?

nicomiguelino commented 1 year ago

@vpetersson, I think I didn't disable RSTP. RSTP playback isn't working beforehand, even if I add the line from sh import mplayer inside lib/utils.py. Here's what I got:

screenly-srly-ose-server-1  | Traceback (most recent call last):
screenly-srly-ose-server-1  |   File "server.py", line 672, in api_view
screenly-srly-ose-server-1  |     return view(*args, **kwargs)
screenly-srly-ose-server-1  |   File "/usr/local/lib/python2.7/dist-packages/flask_restful_swagger_2/swagger.py", line 219, in inner
screenly-srly-ose-server-1  |     return f(self, *args, **kwargs)
screenly-srly-ose-server-1  |   File "server.py", line 1002, in post
screenly-srly-ose-server-1  |     if not asset['skip_asset_check'] and url_fails(asset['uri']):
screenly-srly-ose-server-1  |   File "/usr/src/app/lib/utils.py", line 237, in url_fails
screenly-srly-ose-server-1  |     run_mplayer = sh.mplayer('-identify', '-frames', '0', '-nosound', url)
screenly-srly-ose-server-1  |   File "/usr/local/lib/python2.7/dist-packages/sh.py", line 726, in __call__
screenly-srly-ose-server-1  |     return RunningCommand(cmd, call_args, stdin, stdout, stderr)
screenly-srly-ose-server-1  |   File "/usr/local/lib/python2.7/dist-packages/sh.py", line 291, in __init__
screenly-srly-ose-server-1  |     self.wait()
screenly-srly-ose-server-1  |   File "/usr/local/lib/python2.7/dist-packages/sh.py", line 295, in wait
screenly-srly-ose-server-1  |     self._handle_exit_code(self.process.wait())
screenly-srly-ose-server-1  |   File "/usr/local/lib/python2.7/dist-packages/sh.py", line 309, in _handle_exit_code
screenly-srly-ose-server-1  |     self.process.stderr
screenly-srly-ose-server-1  | ErrorReturnCode_1:
screenly-srly-ose-server-1  |
screenly-srly-ose-server-1  |   RAN: '/usr/bin/mplayer -identify -frames 0 -nosound rtsp://wowzaec2demo.streamlock.net/vod/mp4:BigBuckBunny_115k.mp4'
screenly-srly-ose-server-1  |
screenly-srly-ose-server-1  |   STDOUT:
screenly-srly-ose-server-1  | MPlayer 1.3.0 (Debian), built with gcc-8 (C) 2000-2016 MPlayer Team
screenly-srly-ose-server-1  | Terminal type `unknown' is not defined.
screenly-srly-ose-server-1  |
screenly-srly-ose-server-1  | Playing rtsp://wowzaec2demo.streamlock.net/vod/mp4:BigBuckBunny_115k.mp4.
screenly-srly-ose-server-1  | Resolving wowzaec2demo.streamlock.net for AF_INET6...
screenly-srly-ose-server-1  | Resolving wowzaec2demo.streamlock.net for AF_INET...
screenly-srly-ose-server-1  | Connecting to server wowzaec2demo.streamlock.net[34.227.104.115]: 554...
screenly-srly-ose-server-1  | libavformat version 58.20.100 (external)
screenly-srly-ose-server-1  | libavformat file format detected.
screenly-srly-ose-server-1  | ID_AUDIO_ID=0
screenly-srly-ose-server-1  | [lavf] stream 0: audio (aac), -aid 0
screenly-srly-ose-server-1  | ID_VIDEO_ID=0
screenly-srly-ose-server-1  | [lavf] stream 1: video (h264), -vid 0
screenly-srly-ose-server-1  | VIDEO:  [H264]  240x160  0bpp  24.083 fps    0.0 kbps ( 0.0 kbyte/s)
screenly-srly-ose-server-1  |
screenly-srly-ose-server-1  |
screenly-srly-ose-server-1  |   STDERR:
screenly-srly-ose-server-1  | do_connect: could not connect to socket
screenly-srly-ose-server-1  | connect: No such file or directory
screenly-srly-ose-server-1  | Failed to open LIRC support. You will not be able to use your remote control.
screenly-srly-ose-server-1  |
screenly-srly-ose-server-1  | Couldn't resolve name for AF_INET6: wowzaec2demo.streamlock.net
screenly-srly-ose-server-1  |
screenly-srly-ose-server-1  | A single media stream only is supported atm.
screenly-srly-ose-server-1  | rtsp_session: unsupported RTSP server. Server type is 'Wowza Streaming Engine 4.8.20+1 build20220919162035'.
screenly-srly-ose-server-1  | vo: couldn't open the X11 display ()!
screenly-srly-ose-server-1  | vo: couldn't open the X11 display ()!
screenly-srly-ose-server-1  | vo: couldn't open the X11 display ()!
screenly-srly-ose-server-1  | Error opening terminal: unknown.
screenly-srly-ose-server-1  |
^Ccanceled
nicomiguelino commented 1 year ago

Haven't tried this yet, but we can make use of the VLC Python bindings, If we're to use VLC instead. I did a quick research. Here's a link for reference – https://stackoverflow.com/a/21052684/5114090.

vpetersson commented 1 year ago

Alright, it shouldn't be that much effort to reinstate RTSP support. For Pi 4, we just need to verify that it works with VLC and it should work out-of-the-box on Pi 1/2/3 with omxplayer.

Relevant code:

akkie70 commented 1 year ago

@vpetersson So to confirm that i understand it correctly. Changing mplayer to omxplayer in

Would reinstate RTSP support for PI3 ? In viewer.py is already defined that only model 4B uses VLCMediaPlayer.

vpetersson commented 1 year ago

It has been a while since I touched this so I think @nicomiguelino simply need to do an audit of all of this before we draw any conclusions.

lexalexalexa commented 1 year ago

Hi, is anybody know how to solve this issue?

lexalexalexa commented 1 year ago

how i solved the issue: viewer.py: 1) change 'media_player' definition (line 73): `try:

media_player = OMXMediaPlayer()

media_player = VLCMediaPlayer()

except sh.ErrorReturnCode_1: media_player = OMXMediaPlayer()`

2) change 'view_video' function:

def view_video(uri, duration):
    logging.debug('Displaying video %s for %s ', uri, duration)
    media_player.set_asset(uri, duration)
    media_player.play()

    view_image('null')

    timeout = 0
    try:
        while media_player.is_playing():
            watchdog()
            sleep(1)
            timeout += 1
            if timeout > int(duration):
                break
    except sh.ErrorReturnCode_1:
        logging.info('Resource URI is not correct, remote host is not responding or request was rejected.')

    media_player.stop()

lib/utils.py 1) change start of function 'url_fails' (comment out checking of file with mplayer:

def url_fails(url):
    """
    If it is streaming
    """
    if urlparse(url).scheme in ('rtsp', 'rtmp'):
        #run_mplayer = mplayer('-identify', '-frames', '0', '-nosound', url)
        #for line in run_mplayer.split('\n'):
        #    if 'Clip info:' in line:
        #        return False
        return True

    """
    Try HEAD and GET for URL availability check.
    """
    ...

Now when I adding rtsp stream in Web interface I am setting checkbox 'Skip asset check' and adding stream works succesfully.

nicomiguelino commented 1 year ago

@lexalexalexa, thank you so much for this! While I haven't tested the changes yet, I encourage you to create a pull request, so that we can review your changes. This repository can help you get started on doing open-source contributions – firstcontributions/first-contributions.

Please don't hesitate to ask questions or ask for help.

ismailakincom commented 11 months ago

rtmp://...... link, mplayer gives an error. It does not play streaming video. Could you help ![Uploading Screenshot at Dec 06 11-47-22.png…]()

nicomiguelino commented 6 months ago

@lexalexalexa, I just created a new PR (#1890) regarding this matter, but there are still bugs. There is a noticeable transition (black screen) before displaying the videos. Feel free to give comments on the PR, and thanks for your snippet posted months ago.

CRSBenson commented 6 months ago

Alright. Here's what I have so far...

Previously when running scripts on Buster using the 64-bit Lite OS, I had some specific options loaded into a python script which i will share here with details omitted. The options included were -q (for quiet mode) and --no-osd (to hide the IP address upon launch).

#!/usr/local/bin/python

from termcolor import colored
import subprocess
import time
import os

# VLC stream URL
rtsp_url = "rtsp://administrator:*******@10.xx.xxx.xxx/rtsp/defaultPrimary-1?streamType=m"
camera_ip = "10.xx.xxx.xxx"  # Camera IP address
# Function to start VLC stream
def start_vlc_stream():
    subprocess.Popen(["cvlc", "-q", "--no-osd", rtsp_url])  # Include -q flag for quiet mode

# Function to check if camera is reachable
def camera_reachable():
    cmd = ["ping", "-c", "1", "-W", "1", camera_ip]
    try:
        subprocess.check_output(cmd, stderr=subprocess.DEVNULL)
        return True
    except subprocess.CalledProcessError:
        return False

# Function to check if VLC process is running
def vlc_running():
    process_name = 'vlc'
    cmd = ["pgrep", process_name]
    try:
        subprocess.check_output(cmd, stderr=subprocess.DEVNULL)
        return True
    except subprocess.CalledProcessError:
        return False

try:
    # Main loop to continuously check camera status and VLC stream
    while True:
        if not camera_reachable():
            print(colored("Camera is not reachable. Retrying...",'light_yellow'))
            if vlc_running():
                subprocess.Popen(["pkill", "vlc"])  # Kill VLC process
                print(colored("Stopping VLC...", 'light_red'))

        if camera_reachable() and not vlc_running():
            print(colored("Camera is reachable. Starting VLC stream...", 'green'))
            start_vlc_stream()

        time.sleep(10)  # Check every 10 seconds

except KeyboardInterrupt:
    time.sleep(1)
    print(colored("\nScript terminated by user.", 'light_red'))

Now when adding those commands into the media_player.py script, I'm getting a black screen, but I am seeing that we do have a connection to the target camera (see below). I'm not sure if this is because I was using CVLC with a dummy interface in my previous script vs Anthias, which I assume is vlc_python, or if it has to do with something else. I'll work on getting Anthias to actually display the rtsp after the connection, but I'm guessing it's the HDMI group/mode, kms/fkms, or interface issues.

If anyone has any ideas or would like to point me in the right direction, I would greatly appreciate it. Thanks!

media_player.py adjusted [Lines 50-52]:

class VLCMediaPlayer(MediaPlayer):
    def __init__(self):
        MediaPlayer.__init__(self)

        options = self.__get_options()
        self.instance = vlc.Instance(options)
        self.player = self.instance.media_player_new()

        self.player.audio_output_set('alsa')

    def __get_options(self):
        options = []

        if lookup_raspberry_pi_version() == 'pi4':
            if settings['audio_output'] == 'local':
                options += [
                    '--alsa-audio-device=plughw:CARD=Headphones',
                ]

            options += [
                '-q',
                '--no-osd'
            ]

        return options