1#!/usr/bin/env python3

2

3 from argparse import ArgumentParser

4 import gi

5 import logging

6 import re

7 import os

8 import sys

9 import time

10

11 gi.require_version("Gst", "1.0")

12 gi.require_version("GLib", "2.0")

13 from gi.repository import Gst # noqa: E402

14 from gi.repository import GLib # noqa: E402

15 from subprocess import check_output # noqa: E402

16

17

18 def check_state(device):

19 """Checks whether the sink is available for the given device."""

20 sink_info = check_output(

21 ["pactl", "list", "sinks"], universal_newlines=True

22 )

23

24 data = sink_info.split("\n")

25 try:

26 device_name = re.findall(

27 r".*Name:\s.*%s.*" % device, sink_info, re.IGNORECASE

28 )[0].lstrip()

29 sink = re.findall(

30 r".*Name:\s(.*%s.*)" % device, sink_info, re.IGNORECASE

31 )[0].lstrip()

32 status = data[data.index("\t" + device_name) - 1]

33 except (IndexError, ValueError):

34 logging.error("Failed to find status for device: %s" % device)

35 return False

36

37 os.environ["PULSE_SINK"] = sink

38 logging.info("[ Pulse sink ]".center(80, "="))

39 logging.info("Device: %s %s" % (device_name.strip(), status.strip()))

40 return status

41

42

43 def main():

44 parser = ArgumentParser(description="Simple GStreamer pipeline player")

45 parser.add_argument("PIPELINE", help="Quoted GStreamer pipeline to launch")

46 parser.add_argument(

47 "-t",

48 "--timeout",

49 type=int,

50 required=True,

51 help="Timeout for running the pipeline",

52 )

53 parser.add_argument(

54 "-d", "--device", type=str, help="Device to check for status"

55 )

56 args = parser.parse_args()

57

58 logging.basicConfig(

59 format="%(levelname)s:%(message)s",

60 level=logging.INFO,

61 stream=sys.stdout,

62 )

63

64 exit_code = 0

65 if args.device:

66 if not check_state(args.device):

67 exit_code = 1

68

69 Gst.init(None)

70 try:

71 print(

72 "Attempting to initialize Gstreamer pipeline: {}".format(

73 args.PIPELINE

74 )

75 )

76 element = Gst.parse_launch(args.PIPELINE)

77 except GLib.GError as error:

78 print("Specified pipeline couldn't be processed.")

79 print("Error when processing pipeline: {}".format(error))

80 # Exit harmlessly

81 return 2

82

83 print("Pipeline initialized, now starting playback.")

84 element.set_state(Gst.State.PLAYING)

85

86 if args.timeout:

87 time.sleep(args.timeout)

88

89 element.set_state(Gst.State.NULL)

90

91 return exit_code

92

93

94 if __name__ == "__main__":

95 sys.exit(main())