2020年9月21日 星期一

GStreamer(Gst) - play mp3 file

process or thread 都可用
#!/usr/bin/env python3
# coding=utf8

import sys, os
import gc
import gi
import threading
gi.require_version('Gst', '1.0')
from gi.repository import Gst, GObject

import signal
from multiprocessing import Process

class mp3Player_Core:

    def __init__(self):
        Gst.init(None)
        GObject.threads_init()
        self.player = Gst.ElementFactory.make("playbin", "player")

    def __del__(self):
        print("...delete...")


    def start_stop(self, filepath):
        if os.path.isfile(filepath):
            filepath = os.path.realpath(filepath)
            self.player.set_property("uri", "file://" + filepath)
            play = self.player.set_state(Gst.State.PLAYING)
            
            # bus 相關的,寫在play內,不要寫在 __init__,不然FD會不斷增加
            bus = self.player.get_bus()
            bus.add_signal_watch()
            bus.connect("message", self.on_message)
            
            msg = bus.timed_pop_filtered (Gst.CLOCK_TIME_NONE, Gst.MessageType.ERROR | Gst.MessageType.EOS);
            play = self.player.set_state(Gst.State.NULL)
            print("1. Refcnt of msg={}, play={}".format(sys.getrefcount(msg), sys.getrefcount(play)))
            gc.collect()
        else:
            play = self.player.set_state(Gst.State.NULL)
            play = None
            gc.collect()


    def signal_handler(sig, frame):
        self.player.set_state(Gst.State.NULL)
        sys.exit(0)


    def on_message(self, bus, message):
        t = message.type
        if t == Gst.MessageType.EOS:
            self.player.set_state(Gst.State.NULL)
        elif t == Gst.MessageType.ERROR:
            self.player.set_state(Gst.State.NULL)
            err, debug = message.parse_error()
            print ("Error: %s" % err, debug)

#class mp3Player(threading.Thread):
class mp3Player(Process):
    def __init__(self):
        #threading.Thread.__init__(self)
        Process.__init__(self)
        self.__playCore = mp3Player_Core()
        self.__filePath = None
    
    def setFilePath(self, filepath):
        self.__filePath = filepath

    def run(self):
        self.__playCore.start_stop(self.__filePath)

if __name__ == '__main__':
    while True:
        test = mp3Player()
        test.setFilePath("/home/ubuntu/demo.mp3")
        test.start()
        test.join()
        test = None
        gc.collect()
        test = mp3Player()
        test.setFilePath("/home/ubuntu/demo2.mp3")
        test.start()
        test.join()
        test = None
        gc.collect()
    print("\n\tExit Main!! \n")
    os._exit(0)

沒有留言:

張貼留言