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?
Raspberry Pi / Debian use of GStreamer
Re: Raspberry Pi / Debian use of GStreamer
I don't use wxPython, but Google found this: https://www.daniweb.com/programming/tut ... n-wxpython
Maybe it helps.
Maybe it helps.
Use the source, Luke!
Re: Raspberry Pi / Debian use of GStreamer
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.
Re: Raspberry Pi / Debian use of GStreamer
Ok, sorry then. But technically it should be possible, i do the same in a wxWidgets C++ application using libvlc.
Use the source, Luke!
Re: Raspberry Pi / Debian use of GStreamer
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.
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.
Re: Raspberry Pi / Debian use of GStreamer
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.
-
- Super wx Problem Solver
- Posts: 466
- Joined: Tue Jun 20, 2006 6:47 pm
- Contact:
Re: Raspberry Pi / Debian use of GStreamer
This should work if your using the x11 backend. I'm not sure what to do if your using wayland instead.
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.
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()