Forum > Audio and Video
Porting a Python GStreamer program into Lazarus
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