OdyO moteur audio en ligne de commande

Rédigé par BeHuman Aucun commentaire
Classé dans : Python Mots clés : pygst, gstreamer, moteur, audio, multimédia

Salut à tous 

 
bon comme signaler dans le titre OdyO est un script Python utilisant pygst. Sont but principal est de lire des fichier audio mais surtout de facilité la récupération des information de lecture, comme la position, temps restant....etc
 
voilà l'aide de OdyO:
$ ./odyo
OdyO v0.2 GNU/GPL v3
by David Lhoumaud <craft@ckdevelop.org> 
USAGE:
    play            New player
        odyo play "/realpath/filename" <fadein> <fadeout>
        
    pause           Pause player
        odyo pause
        
    stop            Stop player
        odyo stop
        
    seek            Seek in player
        odyo seek <milliseconds>
        
    volume          Set volume player
        odyo volume <0-1.0>
        
    filename            Current filename
        odyo filename
            return: "/realpath/filename"
        
    position        Display current position
        odyo position 
            return: <position>
 
Il manque encord quelque options das l'aide, comme la gestion des fondu en direct, ou la gestion des PORTS Socket TCP/IP pour un contrôle à distance.
Exemple d'utilisation:
Jouer un son
odyo play $"HOME/filename" 2 5
est équivaut à ça
odyo play $"HOME/filename" 2 5 "host=localhost:3309"
Vous pouvez aussi spécifier votre adresse IP et paramétrer les NAT de votre box pour un contrôle à distance de votre moteur audio
odyo play $"HOME/filename" 2 5 "host=192.168.1.68:3309"
imaginer vous sur un pc externe
odyo position "host=19.25.64.85:3309"
vous récupérez la position de lecture du lecteur distant
 
voilà la source:
#!/usr/bin/env python
#-*- coding:utf-8 -*-

import sys, os, time, thread, socket, commands
import glib, gobject
import pygst
import gst

class CLI_Main:
    
    def __init__(self):
        self.player = gst.element_factory_make("playbin2", "player")
        if "jack" in sys.argv[len(sys.argv)-1]:
            out = gst.element_factory_make("jackaudiosink", "out")
            self.player.add(out)
        bus = self.player.get_bus()
        bus.add_signal_watch()
        bus.connect("message", self.on_message)
        
    def on_message(self, bus, message):
        t = message.type
        if t == gst.MESSAGE_EOS:
            self.player.set_state(gst.STATE_NULL)
            self.playmode = False
        elif t == gst.MESSAGE_ERROR:
            self.player.set_state(gst.STATE_NULL)
            err, debug = message.parse_error()
            print "Error: %s" % err, debug
            self.playmode = False
            
    def query_position(self):
        "Returns a (position, duration) tuple"
        try:
            position, format = self.player.query_position(gst.FORMAT_TIME)
        except:
            position = gst.CLOCK_TIME_NONE
        try:
            duration, format = self.player.query_duration(gst.FORMAT_TIME)
        except:
            duration = gst.CLOCK_TIME_NONE
        return (position, duration)
        
    def pause(self):
        gst.info("pausing...")
        self.player.set_state(gst.STATE_PAUSED)
        self.playmode = True

    def play(self):
        gst.info("playing...")
        self.player.set_state(gst.STATE_PLAYING)
        #Start FadeIn
        if len(sys.argv) > 3:
            if float(sys.argv[3]) > 0:
                self.player.set_property('volume', 0)
                self.FadeIn(float(sys.argv[3]),1)
            else:
                self.player.set_property('volume', 1)
        else:
            self.player.set_property('volume', 1)
        #End FadeIn
        
    def stop(self):
        #FadeOut
        if len(sys.argv) > 3:
            if float(sys.argv[4]) > 0:
                self.FadeOut(float(sys.argv[4]),0)
            else:
                self.player.set_property('volume', 0)
        else:
            self.player.set_property('volume', 0)
        #End FadeOut
        gst.info("stopped")
        self.player.set_state(gst.STATE_NULL)
        self.playmode = False
    
    def seek(self, location):
        gst.debug("seeking to %r" % location)
        event = gst.event_new_seek(1.0, gst.FORMAT_TIME,
            gst.SEEK_FLAG_FLUSH | gst.SEEK_FLAG_ACCURATE,
            gst.SEEK_TYPE_SET, location,
            gst.SEEK_TYPE_NONE, 0)

        res = self.player.send_event(event)
        if res:
            gst.info("setting new stream time to 0")
            self.player.set_new_stream_time(0L)
        else:
            gst.error("seek to %r failed" % location)
            
    def volume(self, vol):
        self.player.set_property("volume", vol)

    def convert_ns(self, t, a):
        # This method was submitted by Sam Mason.
        # It's much shorter than the original one.
        #temps restant
        _rms = (a/1000000)-(t/1000000)
        rs = (a/1000000000)-(t/1000000000)
        rm,rs = divmod(rs, 60)
        if rm < 60:
            _rest="%i;%02i:%02i" %(_rms,rm,rs)
        else:
            rh,rm = divmod(rm, 60)
            _rest="%i;%i:%02i:%02i" %(_rms,rh,rm,rs)
            
        #temps écoulé
        _ms = t/1000000
        s,ns = divmod(t, 1000000000)
        m,s = divmod(s, 60)
        if m < 60:
            _ecoul="%i;%02i:%02i|%s" %(_ms,m,s,_rest)
        else:
            h,m = divmod(m, 60)
            _ecoul="%i;%i:%02i:%02i|%s" %(_ms,h,m,s,_rest)
            
        #temps total
        _ms = a/1000000
        s,ns = divmod(a, 1000000000)
        m,s = divmod(s, 60)
        if m < 60:
            return "%s|%i;%02i:%02i" %(_ecoul,_ms,m,s)
        else:
            h,m = divmod(m, 60)
            return "%s|%i;%i:%02i:%02i" %(_ecoul,_ms,h,m,s)
    
    def FadeIn(self, seconds, to):
        i=self.player.get_property('volume')
        while i < to:
            i+=0.001
            self.player.set_property('volume', i)
            time.sleep(seconds/1000)
    
    def FadeOut(self, seconds, to):
        i=self.player.get_property('volume')
        while i > to:
            i-=0.001
            if i > -0.000000:
                self.player.set_property('volume', i)
            else:
                break
            time.sleep(seconds/1000)
    
    def start(self):
        if os.path.isfile(sys.argv[2]):
            # Create a TCP/IP socket
            self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            if "host=" in sys.argv[len(sys.argv)-1]:
                self.server_name = sys.argv[len(sys.argv)-1].split('=')[1].split(':')[0]
                _port = sys.argv[len(sys.argv)-1].split('=')[1].split(':')[1]
                if self.server_name == "default":
                    self.server_name = commands.getoutput("ifconfig").split("\n")[1].split()[1][4:]
            else:
                self.server_name="localhost"
                _port=3309
            self.server_address = (self.server_name, int(_port))
            self.sock.bind(self.server_address)
            self.sock.listen(1)
            # END Create a TCP/IP socket
            
            if 'http://' in sys.argv[2]:
                self.player.set_property("uri", sys.argv[2])
            else:
                self.player.set_property("uri", "file://" + sys.argv[2])
            self.p_position = gst.CLOCK_TIME_NONE
            self.p_duration = gst.CLOCK_TIME_NONE
            print "Server "+self.server_name+":"+str(_port)+" started"
            self.playmode = True
            self.play()
            
            
            _PAUSE=False
            while self.playmode:
                self.connection, self.client_address = self.sock.accept()
                data = self.connection.recv(100)
                _data = data.split(' ')

                print str(self.client_address)+" > "+str(data)
                if _data[0] == 'pause':
                    if _PAUSE:
                        _PAUSE=False
                        self.play()
                    else:
                        _PAUSE=True
                        self.pause()
                elif _data[0] == 'stop':
                    self.stop()
                elif _data[0] == 'seek':
                    self.seek(int(_data[1]))
                elif _data[0] == 'volume':
                    self.volume(float(_data[1]))
                elif _data[0] == 'fade':
                    if float(_data[1]) > self.player.get_property('volume'):
                        self.FadeIn(float(_data[2]),float(_data[1]))
                    else:
                        self.FadeOut(float(_data[2]),float(_data[1]))
                elif _data[0] == 'getvolume':
                    _vol=str(self.player.get_property('volume')).strip()
                    self.connection.sendall(_vol)
                elif _data[0] == 'filename':
                    self.connection.sendall(sys.argv[2])
                elif _data[0] == 'position':
                    self.p_position, self.p_duration = self.query_position()
                    self.connection.sendall(self.convert_ns(self.p_position,self.p_duration))
                self.connection.close()
                    
        time.sleep(1)
        loop.quit()

######################################################################

def aide():
    print("""OdyO v0.2 GNU/GPL v3
by David Lhoumaud <craft@ckdevelop.org> 
USAGE:
    play            New player
        odyo play "/realpath/filename" <fadein> <fadeout>
        
    pause           Pause player
        odyo pause
        
    stop            Stop player
        odyo stop
        
    seek            Seek in player
        odyo seek <milliseconds>
        
    volume          Set volume player
        odyo volume <0-1.0>
        
    filename            Current filename
        odyo filename
            return: "/realpath/filename"
        
    position        Display current position
        odyo position 
            return: <position>""")
    sys.exit()

# TCP/IP socket
def GetClientControl(message, sock):
    amount_received = 0
    amount_expected = len(message)
    while amount_received < amount_expected:
        data = sock.recv(16384).strip()
        if message == "getvolume":
            amount_received += amount_expected
        else:
            amount_received += len(data)
        print data
        
def ClientControl(message,_GET):
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    if "host=" in sys.argv[len(sys.argv)-1]:
        _host = sys.argv[len(sys.argv)-1].split('=')[1].split(':')[0]
        _port = sys.argv[len(sys.argv)-1].split('=')[1].split(':')[1]
        if _host == "default":
            _host = commands.getoutput("ifconfig").split("\n")[1].split()[1][4:]
    else:
        _host="localhost"
        _port=3309
        
    server_address = (_host,int(_port))
    sock.connect(server_address)
    try:
        sock.sendall(message)
        if _GET:
            GetClientControl(message, sock)
    finally:
        sock.close()
    sys.exit()


filedir=os.path.expanduser("~" )+"/.odyo/"
if not os.path.exists(filedir):
    os.mkdir(filedir)

if len(sys.argv) < 2:
    aide()
#SET
if sys.argv[1] == "play":
    mainclass = CLI_Main()
    thread.start_new_thread(mainclass.start, ())
    gobject.threads_init()
    loop = glib.MainLoop()
    loop.run()
    
elif sys.argv[1] == "pause":
    ClientControl(sys.argv[1], False)
elif sys.argv[1] == "stop":
    ClientControl(sys.argv[1], False)
elif sys.argv[1] == "seek":
    ClientControl(sys.argv[1]+' '+str(int(sys.argv[2])*100000), False)
elif sys.argv[1] == "volume":
    if len(sys.argv) > 2:
        ClientControl(sys.argv[1]+' '+str(float(sys.argv[2])/100.000), False)
    else:
        ClientControl('getvolume', True)
elif sys.argv[1] == "fade":
    ClientControl(sys.argv[1]+' '+str(float(sys.argv[2])/100.000)+' '+sys.argv[3], False)
#GET
elif sys.argv[1] == "filename":
    ClientControl(sys.argv[1], True)
elif sys.argv[1] == "position":
    ClientControl(sys.argv[1], True)

else:
    aide()

Cet exercice à vraiment été un pure plaisir.

 

Écrire un commentaire

Quelle est la dernière lettre du mot ydb3u ?

Fil RSS des commentaires de cet article