Raspberry Pi / Debian use of GStreamer

This forum can be used to talk about general design strategies, new ideas and questions in general related to wxWidgets. If you feel your questions doesn't fit anywhere, put it here.
Post Reply
arghvark
In need of some credit
In need of some credit
Posts: 4
Joined: Thu Aug 12, 2021 11:08 pm

Raspberry Pi / Debian use of GStreamer

Post by arghvark »

My ultimate goal is to use the wxPython component MediaCtrl to play video on a Raspberry Pi (3+ B).

It first told me that MediaCtrl was not supported; some error message or another indicated I needed a GStrreamer 0.10 library; I got it installed, and then it would tell me invalid playbin. I ended up installing a number of GStreamer packages, and now it just tells me that there is no demux for my quicktime (MP4) file.

First of all, can someone point me to a demux for QuickTime on Raspberry Pi (Raspbian / Debian)?

I'm also wondering why the wxpython bindings, if not the wx widgets themselves, use the outdated 0.10 GStreamer library? Are there any plans to update that? Or is there another library that is usable on Unix? I'm puzzled about why there is no standard, up-to-date library for media play on wxWidgets/wxPython. Does anyone have any light to shed on this?
User avatar
doublemax
Moderator
Moderator
Posts: 19116
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: Raspberry Pi / Debian use of GStreamer

Post by doublemax »

I don't use wxPython, but Google found this: https://www.daniweb.com/programming/tut ... n-wxpython

Maybe it helps.
Use the source, Luke!
arghvark
In need of some credit
In need of some credit
Posts: 4
Joined: Thu Aug 12, 2021 11:08 pm

Re: Raspberry Pi / Debian use of GStreamer

Post by arghvark »

No, sorry, not the same thing. The quoted player starts and stops the VLC program which is playing the video in a different window. I need the window to be part of my application, not a separate application.
User avatar
doublemax
Moderator
Moderator
Posts: 19116
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: Raspberry Pi / Debian use of GStreamer

Post by doublemax »

arghvark wrote: Fri Aug 13, 2021 12:26 am No, sorry, not the same thing. The quoted player starts and stops the VLC program which is playing the video in a different window. I need the window to be part of my application, not a separate application.
Ok, sorry then. But technically it should be possible, i do the same in a wxWidgets C++ application using libvlc.
Use the source, Luke!
arghvark
In need of some credit
In need of some credit
Posts: 4
Joined: Thu Aug 12, 2021 11:08 pm

Re: Raspberry Pi / Debian use of GStreamer

Post by arghvark »

I do most abjectly beg your pardon. I scanned the page you linked and assumed it was the same as a similar post that I found earlier.

Yours does do what I want, if only I can make it work. The python 3.7.3 that I'm using doesn't recognize some of the syntax in this one, so I assume it's a later python version. I will investigate this while I wait to see if someone can answer the wxPython MediaCtrl problem.

Thanks, and I apologize again for jumping the gun.
arghvark
In need of some credit
In need of some credit
Posts: 4
Joined: Thu Aug 12, 2021 11:08 pm

Re: Raspberry Pi / Debian use of GStreamer

Post by arghvark »

Well, it looks really good, but has a windows-specific call in it, "os.add_dll_directory(r'C:\Program Files\VideoLAN\VLC')" - need to find out how to do an equivalent thing for the unix system on which I want to run this. Any suggestions welcome.
New Pagodi
Super wx Problem Solver
Super wx Problem Solver
Posts: 466
Joined: Tue Jun 20, 2006 6:47 pm
Contact:

Re: Raspberry Pi / Debian use of GStreamer

Post by New Pagodi »

This should work if your using the x11 backend. I'm not sure what to do if your using wayland instead.

Code: Select all

TITLE = "Python vlc front end"
DEBUG = True

import os
#os.add_dll_directory(r'C:\Program Files\VideoLAN\VLC')

import sys
import wx
import vlc

if DEBUG: import wx.lib.mixins.inspection

ROOT  = os.path.expanduser("~")

class MyApp(wx.App):

    def OnInit(self):

        self.frame = MyFrame()
        self.SetTopWindow(self.frame)
        self.frame.Show()
        return True

class MyFrame(wx.Frame):

    def __init__(self):

        super().__init__(None, wx.ID_ANY)

        self.SetSize((500, 500))

        #Create display elements
        self.pnlVideo    = wx.Panel (self, wx.ID_ANY)
        self.sldPosition = wx.Slider(self, wx.ID_ANY, value=0, minValue=0, maxValue=1000)
        self.btnOpen     = wx.Button(self, wx.ID_ANY, "Open")
        self.btnPlay     = wx.Button(self, wx.ID_ANY, "Play")
        self.btnStop     = wx.Button(self, wx.ID_ANY, "Stop")
        self.btnMute     = wx.Button(self, wx.ID_ANY, "Mute")
        self.sldVolume   = wx.Slider(self, wx.ID_ANY, value=50, minValue=0, maxValue=200)
        self.timer       = wx.Timer (self)

        #Set display element properties and layout
        self.__set_properties()
        self.__do_layout()

        #Create event handlers
        self.Bind(wx.EVT_BUTTON, self.btnOpen_OnClick,   self.btnOpen)
        self.Bind(wx.EVT_BUTTON, self.btnPlay_OnClick,   self.btnPlay)
        self.Bind(wx.EVT_BUTTON, self.btnStop_OnClick,   self.btnStop)
        self.Bind(wx.EVT_BUTTON, self.btnMute_OnClick,   self.btnMute)
        self.Bind(wx.EVT_SLIDER, self.sldVolume_OnSet,   self.sldVolume)
        self.Bind(wx.EVT_SLIDER, self.sldPosition_OnSet, self.sldPosition)
        self.Bind(wx.EVT_TIMER , self.OnTimer,           self.timer) 
        self.pnlVideo.Bind(wx.EVT_WINDOW_CREATE, self.pnlVideo_OnCreate)

        self.Bind(wx.EVT_CLOSE , self.OnClose)

        #Create vlc objects and link the player to the display panel
        self.instance = vlc.Instance()
        self.player = self.instance.media_player_new()
        #self.player.set_hwnd(self.pnlVideo.GetHandle())

        if DEBUG: wx.lib.inspection.InspectionTool().Show()

    def __set_properties(self):
        if DEBUG: print("__set_properties")
        self.SetTitle(TITLE)
        self.pnlVideo.SetBackgroundColour(wx.BLACK)

    def __do_layout(self):
        if DEBUG: print("__do_layout")

        sizer_1 = wx.BoxSizer(wx.VERTICAL)
        sizer_2 = wx.BoxSizer(wx.HORIZONTAL)

        sizer_1.Add(self.pnlVideo, 1, wx.EXPAND, 0)
        sizer_1.Add(self.sldPosition, 0, wx.EXPAND, 0)
        sizer_1.Add(sizer_2, 0, wx.EXPAND, 0)
        sizer_2.Add(self.btnOpen, 0, 0, 0)
        sizer_2.Add(self.btnPlay, 0, 0, 0)
        sizer_2.Add(self.btnStop, 0, 0, 0)
        sizer_2.Add(80,23) #spacer
        sizer_2.Add(self.btnMute, 0, 0, 0)
        sizer_2.Add(self.sldVolume, 1, wx.EXPAND, 0)
        self.SetSizer(sizer_1)

        self.Layout()

    def OnClose(self, event):
        """Clean up, exit"""
        if DEBUG: print(f'OnClose {event=}')
        sys.exit()

    def pnlVideo_OnCreate(self, event):
        self.player.set_xwindow(self.pnlVideo.GetHandle())

    def btnOpen_OnClick(self, event):
        """Prompt for, load, and play a video file"""
        if DEBUG: print(f'btnOpen_OnClick {event=}')

        #Stop any currently playing video
        self.btnStop_OnClick(None)

        #Display file dialog
        dlg = wx.FileDialog(self, "Select a file", ROOT, "", "*.*", 0)

        if dlg.ShowModal() == wx.ID_OK:
            dir  = dlg.GetDirectory()
            file = dlg.GetFilename()

            self.media = self.instance.media_new(os.path.join(dir, file))
            self.player.set_media(self.media)

            if (title := self.player.get_title()) == -1:
                title = file
            self.SetTitle(title)

            #Play the video
            self.btnPlay_OnClick(None)

    def btnPlay_OnClick(self, event): 
        """Play/Pause the video if media present"""
        if DEBUG: print(f'btnPlay_OnClick {event=}')

        if self.player.get_media():            
            if self.player.get_state() == vlc.State.Playing:
                #Pause the video
                self.player.pause()
                self.btnPlay.Label = "Play"
            else:
                #Start or resume playing
                self.player.play()
                self.timer.Start()
                self.btnPlay.Label = "Pause"

    def btnStop_OnClick(self, event):
        """Stop playback"""
        if DEBUG: print(f'btnStop_OnClick {event=}')
        self.timer.Stop()
        self.player.stop()
        self.btnPlay.Label = "Play"

    def btnMute_OnClick(self, event):
        """Mute/Unmute the audio"""
        if DEBUG: print(f'btnMute_OnClick {event=}')

    def sldVolume_OnSet(self, event):
        """Adjust volume"""
        if DEBUG: print(f'sldVolume_OnSet {event=}')

    def sldPosition_OnSet(self, event):
        """Select a new position for playback"""
        if DEBUG: print(f'sldPosition_OnSet {event=}')

    def OnTimer(self, event):
        """Update the position slider"""

        if self.player.get_state() == vlc.State.Playing:
            length = self.player.get_length()
            self.sldPosition.SetRange(0, length)
            time = self.player.get_time()
            self.sldPosition.SetValue(time)
            #Force volume to slider volume
            self.player.audio_set_volume(self.sldVolume.GetValue())

if __name__ == "__main__":
    app = MyApp(False)
    app.MainLoop()
Note that I know very little about wxPython and this is just the minimal changes needed to get the example linked above to run on GTK. The main change is that on GTK you must wait until the window is created before you can set it as output for the video.
Post Reply