#!/usr/bin/python3
import gi, os
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk, GLib

GST_OK = False
try:
    gi.require_version('Gst', '1.0')
    from gi.repository import Gst
    Gst.init(None)
    GST_OK = True
except Exception:
    pass

OUT = '/tmp/recording.wav'

class App(Gtk.Window):
    def __init__(self):
        super().__init__(title='Audio Recorder')
        self.set_default_size(320, 180)
        self.pipeline = None
        self.recording = False
        vbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=10)
        vbox.set_margin_top(20); vbox.set_margin_bottom(20)
        vbox.set_margin_start(20); vbox.set_margin_end(20)
        self.add(vbox)
        if not GST_OK:
            vbox.add(Gtk.Label(label='GStreamer not available.\nInstall python3-gst-1.0 to enable recording.\nOutput would go to /tmp/recording.wav'))
            return
        self.status = Gtk.Label(label='Ready to record')
        vbox.pack_start(self.status, True, True, 0)
        self.file_label = Gtk.Label(label=f'Output: {OUT}')
        vbox.pack_start(self.file_label, False, False, 0)
        self.btn = Gtk.Button(label='⏺  Start Recording')
        self.btn.connect('clicked', self.toggle)
        vbox.pack_start(self.btn, False, False, 0)
        self.timer_id = None
        self.seconds = 0
    def toggle(self, *_):
        if not self.recording:
            self.start_recording()
        else:
            self.stop_recording()
    def start_recording(self):
        self.pipeline = Gst.parse_launch(
            f'autoaudiosrc ! audioconvert ! wavenc ! filesink location={OUT}')
        self.pipeline.set_state(Gst.State.PLAYING)
        self.recording = True
        self.seconds = 0
        self.btn.set_label('⏹  Stop Recording')
        self.timer_id = GLib.timeout_add(1000, self.update_timer)
    def stop_recording(self):
        if self.pipeline:
            self.pipeline.send_event(Gst.Event.new_eos())
            GLib.timeout_add(500, self._finish_stop)
    def _finish_stop(self):
        if self.pipeline:
            self.pipeline.set_state(Gst.State.NULL)
            self.pipeline = None
        self.recording = False
        self.btn.set_label('⏺  Start Recording')
        if self.timer_id: GLib.source_remove(self.timer_id)
        size = os.path.getsize(OUT) if os.path.exists(OUT) else 0
        self.status.set_text(f'Saved: {OUT} ({size//1024} KB)')
        return False
    def update_timer(self):
        self.seconds += 1
        m, s = divmod(self.seconds, 60)
        self.status.set_text(f'Recording... {m:02d}:{s:02d}')
        return self.recording

win = App()
win.connect('destroy', Gtk.main_quit)
win.show_all()
Gtk.main()
