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
Multimedia mit wxPython
Definitiv MplayerCtrl - nein Spaß bei Seite (ich bin der Autor)
MplayerCtrtl:
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
- wenige Formate
- verwendet unter Linux gstreamer, unter Win WMP und unter MAC quicktime
- wird mitgeliefert
- wenige, bis keine Funktionen, wie Geschwindigkeit erhöhen
the more they change the more they stay the same
Wow!
Vielen Dank für die schnelle Antowort!
Knnst du mir eine gute Dokumentation dazu empfehlen?
akhof
Vielen Dank für die schnelle Antowort!
Knnst du mir eine gute Dokumentation dazu empfehlen?
akhof
Klar:
wx.media.MediaCtrl: http://www.wxpython.org/docs/api/wx.med ... class.html, http://docs.wxwidgets.org/2.8.12/wx_wxmediactrl.html
und MplayerCtrl: http://packages.python.org/MplayerCtrl/
wx.media.MediaCtrl: http://www.wxpython.org/docs/api/wx.med ... class.html, http://docs.wxwidgets.org/2.8.12/wx_wxmediactrl.html
und MplayerCtrl: http://packages.python.org/MplayerCtrl/
the more they change the more they stay the same
Danke!
Ich habe außerdem ein Beispiel gefunden: http://www.blog.pythonlibrary.org/2010/ ... ia-player/
leider kommt nun eine Fehlermeldung:
->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 ]
akhof
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
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)
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.
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.
the more they change the more they stay the same
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
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
@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`.
Nachtrag: Ich habe es mal ausprobiert: das Argument ist ja *da*, aber es ist nicht vom Typ `int` sondern `None`.
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
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
@akhof: Traceback ist das wo "Traceback" am Anfang steht und wo Du uns nur die letzte Zeile von gezeigt hast:
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.
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'
Achso!
Ich benutze eric, und da hab ich sowas noch nie gesehen, aber gut...
->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!
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'
...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!
@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.
ich werde mal versuchen, die funktionenaufrufe etwas umzustellen!
aber danke!
aber danke!
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.
Die Event-Handler für die MplayerCtrl-Ereignisse werden auch nicht aufgerufen.
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.
nun habe ich aber folgende probleme [lange liste]:
akhof
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
akhof
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.
Code: Alles auswählen
t_len = self.mplayer.GetTimeLength()
the more they change the more they stay the same
@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?
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:
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()
the more they change the more they stay the same
@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.
@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 )
the more they change the more they stay the same