#!/usr/bin/env python3
import argparse
import functools
import gi
import itertools
import sys

gi.require_version("Gst", "1.0")
from gi.repository import Gst, GObject


Gst.init(sys.argv)


class Example(object):

    def __init__(self, media_type, uri):
        self.pipeline = Gst.ElementFactory.make("playbin", None)
        self.pipeline.set_property("uri", uri)

        # For some reason this crashes if you do this in a loop and add all
        # media types
        self.pipeline.connect("{}-tags-changed".format(media_type),
            functools.partial(self.on_tags_changed, media_type))
        
        bus = self.pipeline.get_bus()
        bus.add_signal_watch()
        bus.connect("message::error", self.on_error)
        bus.connect("message::eos", self.on_eos)
        
        self.main_loop = GObject.MainLoop()

    def on_eos(self, bus, message):
        print("EOS")
        self.quit()

    def on_error(self, bus, message):
        print(message.parse_error())
        self.quit()
    
    def on_tags_changed(self, media_type, _, i):
        pad_tags = self.pipeline.emit("get-{}-tags".format(media_type), i)
        pad = self.pipeline.emit("get-{}-pad".format(media_type), i)
        event_tags = Gst.TagList.new_empty()
        for i in itertools.count():
            event = pad.get_sticky_event(Gst.EventType.TAG, i)
            if event is None:
                break
            event_tags = event_tags.merge(event.parse_tag(), Gst.TagMergeMode.REPLACE)
        print("{} pad {} got tags:\ninput-selector pad tags: {}\nsticky event tags: {}\n".format(media_type, i,
            pad_tags.to_string(), event_tags.to_string()))

    def quit(self):
        if self.pipeline.set_state(Gst.State.NULL) == 0:
            print("Failed to set pipeline to NULL")
        self.main_loop.quit()

    def run(self):
        if self.pipeline.set_state(Gst.State.PLAYING) == 0:
            print("Failed to set pipeline to playing")
        self.main_loop.run()


def main():
    parser = argparse.ArgumentParser()
    parser.add_argument("--type", "-t", default="text", choices=("audio", "text", "video"))
    parser.add_argument("uri")
    args = parser.parse_args()

    Example(args.type, args.uri).run()


if __name__ == "__main__":
    sys.exit(main())
