Forum > Audio and Video

Porting a Python GStreamer program into Lazarus

(1/2) > >>

Aruna:
Hello, I wrote a Python+GStreamer program sometime back. I wanted to try and port it to Lazarus. What would be the best way to proceed? The python code is below.

--- Code: Python  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---#!/usr/bin/env python3import gigi.require_version('Gtk', '3.0')gi.require_version('Gst', '1.0')from gi.repository import Gtk, Gstimport time class RadioApp(Gtk.Window):        def __init__(self):        super().__init__()        self.connect("destroy", Gtk.main_quit)                self.init_ui()        self.init_gstreamer()     def init_ui(self):        self.set_size_request(500, 650)        self.set_position(Gtk.WindowPosition.CENTER)        self.set_title('Python3 + GTK3 + Gstreamer Demo')         vbox = Gtk.Box()        vbox.set_orientation(Gtk.Orientation.VERTICAL)                                hbox = Gtk.Box()        hbox.set_orientation(Gtk.Orientation.HORIZONTAL)                btn_radio = Gtk.Button.new_with_label("Radio")        btn_atc = Gtk.Button.new_with_label("Air Traffic Control")        btn_police = Gtk.Button.new_with_label("Police")                btn_atc.connect("clicked", self.load_atc)        btn_radio.connect("clicked", self.load_radio)        btn_police.connect("clicked", self.load_police)                hbox.pack_start(btn_radio, False, False, 0)        hbox.pack_start(btn_atc, False, False, 0)        hbox.pack_start(btn_police, False, False, 0)                vbox.pack_start(hbox, False, False, 0)                scrolled_window = Gtk.ScrolledWindow()        scrolled_window.set_shadow_type(Gtk.ShadowType.ETCHED_IN)        scrolled_window.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC)                scrolled_window2 = Gtk.ScrolledWindow()                        vbox.pack_start(scrolled_window, True, True, 0)        vbox.pack_start(scrolled_window2, True, True, 0)                self.store = Gtk.ListStore(str, str, str)        self.load_radio(None)  # Load initial radio stations                self.treeview = Gtk.TreeView(model=self.store)        self.treeview.connect("row-activated", self.on_activated)        #self.treeview.set_rules_hint(True)        scrolled_window.add(self.treeview)                renderer_text = Gtk.CellRendererText()        column = Gtk.TreeViewColumn("Station", renderer_text, text=0)        column.set_sort_column_id(0)        self.treeview.append_column(column)                renderer_text = Gtk.CellRendererText()        column = Gtk.TreeViewColumn("Description", renderer_text, text=1)        column.set_sort_column_id(1)        self.treeview.append_column(column)                self.listbox = Gtk.ListBox()        scrolled_window2.add(self.listbox)        #vbox.pack_start(self.listbox, True, True, 0)                        global nowplaying        nowplaying = Gtk.Label()        vbox.pack_start(nowplaying, False, False, 0)                global statusbar        statusbar = Gtk.Statusbar()        vbox.pack_start(statusbar, False, False, 0)                hbox = Gtk.HBox()        hbox.pack_end(statusbar, True, True, 0)                global btn        btn = Gtk.Button.new_with_label("Stop")        btn.connect("clicked", self.stop)        hbox.pack_end(btn, False, False, 0)                global btn2        btn2 = Gtk.Button.new_with_label("Vol -")        btn2.connect("clicked", self.voldown)        hbox.pack_end(btn2, False, False, 0)                global btn3        btn3 = Gtk.Button.new_with_label("Vol +")        btn3.connect("clicked", self.volup)        hbox.pack_end(btn3, False, False, 0)               #hbox.pack_end(btn_radio, False, False, 0)               #hbox.pack_end(btn_atc, False, False, 0)               #hbox.pack_end(btn_police, False, False, 0)                               vbox.pack_start(hbox, False, False, 0)                self.add(vbox)        self.show_all()     def init_gstreamer(self):        Gst.init(None)        self.playbin = Gst.ElementFactory.make("playbin", "player")        bus = self.playbin.get_bus()        bus.add_signal_watch()        bus.enable_sync_message_emission()        bus.connect("message::tag", self.bus_message_tag)        #bus.connect("message", self.bus_message_tag)     def bus_message_tag(self, bus, message):        taglist = message.parse_tag()                          tag_string = taglist.get_string(Gst.TAG_TITLE)                 print(tag_string[1])                if tag_string[1] is None:            nowplaying.set_text("No Stream Info")        else:                nowplaying.set_text(tag_string[1])            label = Gtk.Label()            label.set_text(tag_string[1] +" : "+ time.ctime())            self.listbox.add(label)                  self.show_all()                        #for key in taglist.keys():        #    print(key.ljust(15) + " : " + str(taglist[key]))        #t = taglist.get_string("title")        #nowplaying.set_text(t)     def voldown(self, widget):        self.playbin.set_property("volume", self.playbin.get_property("volume") - 0.1)    def volup(self, widget):        self.playbin.set_property("volume", self.playbin.get_property("volume") + 0.1)            print(self.playbin.get_property("volume"))     def stop(self, widget):        txt = btn.get_label()        if txt == "Stop":            print("Stop selected")            btn.set_label("Play")            self.playbin.set_state(Gst.State.NULL)        elif txt == "Play":            print("Play selected")            btn.set_label("Stop")            self.playbin.set_state(Gst.State.PLAYING)     def on_activated(self, treeView, path, column):        txt = btn.get_label()        model = treeView.get_model()        iter = model.get_iter(path)        if iter:            text = model.get_value(iter, 2)            #statusbar.push(0, text)                        self.playbin.set_state(Gst.State.NULL)            self.playbin.set_property("uri", text)            self.playbin.set_state(Gst.State.PLAYING)                        if txt == "Play":                btn.set_label("Stop")     def load_atc(self, widget):        self.store.clear()        for station in atc:            self.store.append(list(station))     def load_radio(self, widget):        self.store.clear()        for station in stations:            self.store.append(list(station))        def load_police(self, widget):        self.store.clear()        for station in police:            self.store.append(list(station))         if __name__ == "__main__":    stations = [('Deep House Radio','Bucharest - Romania','https://streaming-01.xtservers.com:7000/stream'),                ('HIRU FM', 'Sri Lanka', "https://radio.lotustechnologieslk.net:2020/stream/hirufmgarden"),                ('SHAA FM','Sri Lanka','https://radio.lotustechnologieslk.net:2020/stream/shaafmgarden'),                ('Sirasa FM','Sri Lanka','http://live.trusl.com:1170/;;'),                ('Hot 80s Hits', 'ShoutCast', 'http://216.245.210.78:9900/stream'),                                 ('Heartbeat FM', 'Lovesongs & Heartbreakers', 'http://cast5.magicstreams.gr:8010/stream')]     atc = [('Tokyo International Airport', 'Japan', 'https://s1-bos.liveatc.net/rjtt_app_dep?nocache=2024062002221314785"'),           ('Kuwait International Airport', 'Kuwait City', 'http://d.liveatc.net/okbk'),           ('Esenboga International Airport', 'Ankara, Turkey', 'http://d.liveatc.net/ltac'),           ('TTC','Toronto','https://broadcastify.cdnstream1.com/31629')]               police = [('Bay Area','San Francisco','https://broadcastify.cdnstream1.com/34756')]            app = RadioApp()    Gtk.main() 

cdbc:
Hi
Hmmm ...the gui-stuff seems pretty straightforward, i.e.: can be easily copied with laz' LCL (note: at least I can read it and make sense of it  ;D )
Regarding the 'gst'-stuff, I think it's a matter of creating a class, that takes care of the gstreamer related stuff and then instantiate that in the place of a 'presenter', so to speak. Let the GStreamer be your 'Model', create a 'Presenter' to handle it and communicate actions/results to/from the LCL-'View'
What python does, is act like MV instead of the full MVP...
Should be doable  8)
Regards Benny

af0815:
The only problem I see, is to find the correct gstreamer bindings for pascal.

cdbc:
Hi
Hmmm, at least C# is one of Anders' languages... /similarities/  %)
https://gstreamer.freedesktop.org/src/gstreamer-sharp/ from here I downloaded the latest version(1.24.5), at the bottom of the page.
In that archive there's a /big/ file called 'gstreamer.api.raw' and when you open it, it's a xml-file with all the enums and functions in libgstreamer.so.1
Maybe one can pick'n choose what to bind, enough to get it to work... *big* file.
Regards Benny

varianus:
For my audio player, Ovoplayer, I've manually written bindings for some Gstreamer audio API, https://github.com/varianus/ovoplayer/blob/master/src/import-engines/gstreamer.pas.
It support Gstreamer 0.1 and 1.0 releases.

The bindings is then used in this unit to play audio files, https://github.com/varianus/ovoplayer/blob/master/src/audioengine_gstreamer.pas
This unit is heavy coupled to my player code, but should give a raw idea on how to interact with the API.

Navigation

[0] Message Index

[#] Next page

Go to full version