Seite 1 von 1
Multimedia mit wxPython
Verfasst: Sonntag 18. Dezember 2011, 14:51
von akhof
Hallo!
Ich bin gerade dabei einen Audio-Player mit wxPython zu machen.
Ich habe mich im Inat mal nach Bibiliotheken zur Soundwiedergabe umgeschaut, habe auch was dazu gefunden, weiß aber nicht, welcher der Beste für meinen Zweck ist.
Ich möchte, dass man natürlich den Sound
pausieren und dann wieder starten bzw. stoppen kann
,dass man die Lautstärke ändern kann
,dass verschiedene Soundeigenschaften [optional: Geschwindigkeit, usw...] verstellen kann
Ich weiß nicht, ob das alles machbar ist, hier aber meine Suchergebnisse:
wx.Sound
wave, pymedia.audio.sound
MplayerCtrl
evt. noch etwas anderes
Das ganze soll sowohl auf Linux, als auch auf Windows funktionieren.
Ich badanke mich für alle Antworten schoneinmal im Vorraus!
akhof

Re: Multimedia mit wxPython
Verfasst: Sonntag 18. Dezember 2011, 21:36
von Dav1d
Definitiv MplayerCtrl - nein Spaß bei Seite (ich bin der Autor)
MplayerCtrtl:
- ermöglicht dir das Abspielen so ziemlicher aller Formate, Audio wie Video
- kompletter Funktionsumfang des MPlayers (schneller, langsamer, osd…)
- Nachteil: benötigt eine Mplayer.exe
wx.media.MediaCtrl
- wenige Formate
- verwendet unter Linux gstreamer, unter Win WMP und unter MAC quicktime
- wird mitgeliefert
- wenige, bis keine Funktionen, wie Geschwindigkeit erhöhen
Wenn es nur um Sounds geht, gibt es noch diverse andere Python-Bibliotheken, allerdings kann ich zu denen nichts sagen. Mein persönlicher Favorit ist die MplayerCtrl, ich habe sie genau deswegen geschrieben, weil ich Probleme hatte mit wx.media.MediaCtrl verschiedene Formate abzuspielen (allerdings Videos) und weil mir wx.media.MediaCtrl zu wenig Funktion geboten hat.
Re: Multimedia mit wxPython
Verfasst: Montag 19. Dezember 2011, 07:47
von akhof
Wow!
Vielen Dank für die schnelle Antowort!
Knnst du mir eine gute Dokumentation dazu empfehlen?
akhof

Re: Multimedia mit wxPython
Verfasst: Montag 19. Dezember 2011, 08:46
von Dav1d
Re: Multimedia mit wxPython
Verfasst: Montag 19. Dezember 2011, 16:19
von akhof
Danke!

Ich habe außerdem ein Beispiel gefunden:
http://www.blog.pythonlibrary.org/2010/ ... ia-player/
leider kommt nun eine Fehlermeldung:
Code: Alles auswählen
TypeError
"in method 'Slider_SetRange', expected argument 3 of type 'int'"
Datei: /usr/lib64/python2.7/site-packages/wx-2.8-gtk2-unicode/wx/_controls.py, Zeile: 2692
->und dass, obwohl in der Datei [siehe unten] steht, dass nur zwei Argumente erwartet werden??
in Zeile 2692 steht folgendes: [falls damit jemand was anstllen kann

]
Code: Alles auswählen
def SetRange(*args, **kwargs):
"""SetRange(self, int minValue, int maxValue)"""
return _controls_.Slider_SetRange(*args, **kwargs)
akhof

Re: Multimedia mit wxPython
Verfasst: Montag 19. Dezember 2011, 19:09
von Dav1d
Oh ja, von driscollis
Der ganze Traceback wäre interessant, besonders die Zeile im Skript.
Übrigens dein Code-Ausschnitt nimm beliebig viele Argumente entgegen, was du das siehst ist übrigens Teil des swig-Wrappers also uninteressant.
Re: Multimedia mit wxPython
Verfasst: Montag 19. Dezember 2011, 21:50
von akhof
ok!
Ich kenn mich mit Python nicht so aus, aber die Fehlermeldung bedeutet doch, dass als 3. Element ein Int gebraucht wird.
Aber soll ich einfach ne 0 einsetzen??
akhof

Re: Multimedia mit wxPython
Verfasst: Montag 19. Dezember 2011, 22:02
von BlackJack
@akhof: Nein Du solltest mal einen Traceback zeigen damit mit man sieht wie der Aufruf aussieht. Und vielleicht mal schauen welchen Typ das Argument hat was Du da übergibst.
Nachtrag: Ich habe es mal ausprobiert: das Argument ist ja *da*, aber es ist nicht vom Typ `int` sondern `None`.
Re: Multimedia mit wxPython
Verfasst: Montag 19. Dezember 2011, 22:25
von akhof
Das Problem ist, dass ich nicht so genau weiß, wo dieser error passiert.
Auch beim Debugen ist nichts richtiges rausgekommen (nicht genau wo)
ich weiß (ist mir jetzt etwas peinlich

) nicht genau, wass Ihr mit
traceback meint :K
akhof

Re: Multimedia mit wxPython
Verfasst: Montag 19. Dezember 2011, 22:36
von BlackJack
@akhof: Traceback ist das wo "Traceback" am Anfang steht und wo Du uns nur die letzte Zeile von gezeigt hast:
Code: Alles auswählen
Traceback (most recent call last):
File "mediaplayer.py", line 122, in on_add_file
self.playbackSlider.SetRange(0, t_len)
File "/usr/lib/python2.6/dist-packages/wx-2.8-gtk2-unicode/wx/_controls.py", line 2692, in SetRange
return _controls_.Slider_SetRange(*args, **kwargs)
TypeError: in method 'Slider_SetRange', expected argument 3 of type 'int'
Da sieht man auch deutlich in welcher Zeile der Aufruf in der ``mediaplayer.py`` gemacht wird, der zu dieser Ausnahme führt. Und `t_len` ist an der Stelle `None`, sollte aber eine Zahl sein.
Re: Multimedia mit wxPython
Verfasst: Montag 19. Dezember 2011, 22:41
von akhof
Achso!

Ich benutze eric, und da hab ich sowas noch nie gesehen, aber gut...
Code: Alles auswählen
/usr/lib64/python2.7/site-packages/wx-2.8-gtk2-unicode/wx/_core.py:14512: UserWarning: wxPython/wxWidgets release number mismatch
warnings.warn("wxPython/wxWidgets release number mismatch")
Traceback (most recent call last):
File "mediaplayer.py", line 122, in on_add_file
self.playbackSlider.SetRange(0, t_len)
File "/usr/lib64/python2.7/site-packages/wx-2.8-gtk2-unicode/wx/_controls.py", line 2692, in SetRange
return _controls_.Slider_SetRange(*args, **kwargs)
TypeError: in method 'Slider_SetRange', expected argument 3 of type 'int'
->genau das ist es...
...ich habe aber keine ahnung, wieso, weshalb und warum
...auch, weil in der "Doku" nur steht, dass zwei Argumente benötigt werden ([self], min, max)
akhof
Danke nochmal für die schnellen Antworten!
Re: Multimedia mit wxPython
Verfasst: Montag 19. Dezember 2011, 22:50
von BlackJack
@akhof: Es werden laut Doku drei Argumente erwartet. In der Zählung ist das `self` mit enthalten. Die Fehlermeldung sagt, dass das dritte Argument, also `max`, den falschen Typ hat. Und das hat es auch tatsächlich denn zu dem Zeitpunkt wo der Fehler auftritt ist `t_len` an `None` gebunden, weil das der Rückgabewert von ``self.mplayer.GetTimeLength()`` ist. Warum *das* so ist kann ich auch nur vermuten. Vielleicht kann man die Länge erst ermitteln wenn man angefangen hat die Datei abzuspielen und nicht schon wenn man sie geladen hat, keine Ahnung.
Re: Multimedia mit wxPython
Verfasst: Montag 19. Dezember 2011, 22:53
von akhof
ich werde mal versuchen, die funktionenaufrufe etwas umzustellen!
aber danke!

Re: Multimedia mit wxPython
Verfasst: Montag 19. Dezember 2011, 23:03
von BlackJack
Das Programm scheint insgesamt nicht wirklich zu funktionieren. `on_update_playback()` wird bei mir nicht aufgerufen, womit der Fortschritts-Slider sowieso nicht aktualisiert wird. Beziehungsweise erst wenn ich auf Pause klicke, dann aber in Eein-Sekunden-Zeitschritten in denen auch das Video immer ein ganz kleines Stück weiter läuft. Also ist Pause eher eine Slowmotion-Funktion.
Die Event-Handler für die MplayerCtrl-Ereignisse werden auch nicht aufgerufen.
Re: Multimedia mit wxPython
Verfasst: Montag 19. Dezember 2011, 23:09
von akhof
ich hab mal ein bisschen rumprobiert, und habe dann mal, ein bisschen premitiv, einfach nen timer eingebaut, also den "sekunden-zähler" eine sckunde später gestartet, das hat auch soweit gefunkt.
Code: Alles auswählen
def on_add_file(self, event):
"""
Add a Movie and start playing it
"""
wildcard = "Media Files (*.*)|*.*"
dlg = wx.FileDialog(
self, message="Choose a file",
defaultDir=self.currentFolder,
defaultFile="",
wildcard=wildcard,
style=wx.OPEN | wx.CHANGE_DIR
)
if dlg.ShowModal() == wx.ID_OK:
path = dlg.GetPath()
self.currentFolder = os.path.dirname(path[0])
trackPath = '"%s"' % path.replace("\\", "/")
self.mplayer.Loadfile(trackPath)
self.timer = wx.Timer(self)
self.Bind(wx.EVT_TIMER, self.timer_out, self.timer)
self.timer.Start(1000)
def timer_out(self, event):
t_len = self.mplayer.GetTimeLength()
self.playbackSlider.SetRange(0, t_len)
self.playbackTimer.Start(100)
nun habe ich aber folgende probleme [lange liste]:
- wenn ich die Wiedergabe pausiere, stottert der sound, auch probeweise das video weiter
- ich kann niht die stelle angeben, die ich mir ausehen will
- der sound-pegel kann nicht verstellt werden
ich hatte mir dieses thema schon sehr schwer vorgestelt, aber dass es so viele "schwere" Probleme gibt, damit hatte ich nicht gerechnet
akhof

Re: Multimedia mit wxPython
Verfasst: Dienstag 20. Dezember 2011, 14:32
von Dav1d
Der Code sagt leider nicht viel aus, außer, dass du den slider falsch verwendest.
Das ist ein recht teurer Aufruf, den du alle 100ms absetzte, es müssen Daten in einen fd geschrieben werden, die Antwort vom Prozess abgewartet werden. Außerdem ändert sich die Länge des Videos/Lieds nicht, d.h. du musst die "Range" mit SetRange nur einmal setzten, zu Beginn des Videos. Updaten musst du mit .SetValue.
Re: Multimedia mit wxPython
Verfasst: Dienstag 20. Dezember 2011, 15:02
von BlackJack
@Dav1d: Ab wann darf man denn `GetTimeLength()` aufrufen? akhof hat das ja hauptsächlich deswegen in den Timer-Handler verschoben, weil der Aufruf an der Originalstelle von dem Multimediaplayer `None` zurück gegeben hat. Kann es sein, dass das Video schon laufen muss bevor man die Methode aufrufen darf?
Re: Multimedia mit wxPython
Verfasst: Dienstag 20. Dezember 2011, 15:23
von Dav1d
Ja, die Media-Datei muss schon gestartet sein, dafür lässt sich wunderbar das EVT_MEDIA_STARTED Event verwenden.
Kleines Beispiel, ändert die Lautstärke auf Tastendruck und zeigt die Länge und aktuelle Position an:
Code: Alles auswählen
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import MplayerCtrl as mpc
import youtube
import wx
#mpc.DEBUG = True
class Frame(wx.Frame):
def __init__(self, parent, id, size=(-1,-1)):
wx.Frame.__init__(self, parent, id, size=size)
self.mpc = mpc.MplayerCtrl(self, -1, 'mplayer')
self.Bind(mpc.EVT_MEDIA_STARTED, self.media_started)
self.Bind(mpc.EVT_MEDIA_FINISHED, self.media_finished)
self.Bind(mpc.EVT_PROCESS_STARTED, self.process_started)
self.Bind(mpc.EVT_PROCESS_STOPPED, self.process_stopped)
self.mpc.Bind(wx.EVT_KEY_DOWN, self.key_down)
self.timer = wx.Timer()
self.interval = 100
self.timer.Bind(wx.EVT_TIMER, self.on_timer, self.timer)
self.Center()
self.Show()
def media_started(self, evt):
print '----------> Media started'
print 'Länge:', self.mpc.GetTimeLength()
self.timer.Start(self.interval)
def media_finished(self, evt):
print '----------> Media finished'
def process_started(self, evt):
print '----------> Process started'
self.mpc.Loadfile('testmovie ü.mpg')
def process_stopped(self, evt):
print '----------> Process stopped'
def on_timer(self, evt):
if self.mpc.playing:
print 'Pos:', self.mpc.GetTimePos()
self.timer.Start(self.interval)
def key_down(self, evt):
k = evt.GetKeyCode()
if k in (43, 45) and self.mpc.playing:
volume = self.mpc.volume
if k == 43:
if not volume > 95:
self.mpc.volume += 5
elif k == 45:
if not volume <= 5:
self.mpc.volume -= 5
evt.Skip()
if __name__ == '__main__':
app = wx.App()
f = Frame(None, -1)
app.MainLoop()
Re: Multimedia mit wxPython
Verfasst: Dienstag 20. Dezember 2011, 17:12
von BlackJack
@Dav1d: Wenn es denn funktioniert — wie gesagt bei dem oben angeführten Beispielprogramm `mediaplayer.py` werden die Handler nicht aufgerufen. Bei Deinem Beispiel funktioniert es.
Re: Multimedia mit wxPython
Verfasst: Dienstag 20. Dezember 2011, 23:02
von Dav1d
@BlackJack, du meinst den Blogbeitrag von driscollis? - Der sollte funktionieren (wobei der zu Zeiten von 0.1.3 entstanden ist, aktuell ist 0.3.1, erst letztens geupdated

)