def test_gstreamer_versions(self): Gst.init(None) pp.pprint(ubuntu_version) # ubuntu 16.04 says: # ['Linux', '4.4.0', '38', 'generic', 'x86_64', 'with', 'Ubuntu', '16.04', 'xenial'] # travis says # ['Linux', '4.4.0', '38', 'generic', 'x86_64', 'with', 'debian', 'jessie', 'sid'] # docker says: # ['Linux', '4.4.17', 'boot2docker', 'x86_64', 'with', 'debian', 'stretch', 'sid'] if ("trusty" in ubuntu_version or "jessie" in ubuntu_version or "stretch" in ubuntu_version): # assert GObject.pygobject_version == (3, 22, 0) assert GObject.pygobject_version[0] == 3 assert GObject.pygobject_version[1] >= 22 assert GObject.pygobject_version[2] >= 0 else: # assert GObject.pygobject_version == (3, 20, 0) assert GObject.pygobject_version[0] == 3 assert GObject.pygobject_version[1] >= 20 assert GObject.pygobject_version[2] >= 0 # Verify Gstremaer 1.8.2 or 1.8.3 gst_version_string = Gst.version_string() m = re.search("(GStreamer 1.8.2|GStreamer 1.8.3)", gst_version_string) # If we get a string match on either of these versions then we have # 1.8.2/1.8.3, else None assert m
def test_gstreamer_versions(self): Gst.init(None) pp.pprint(ubuntu_version) # ubuntu 16.04 says: # ['Linux', '4.4.0', '38', 'generic', 'x86_64', 'with', 'Ubuntu', '16.04', 'xenial'] # travis says # ['Linux', '4.4.0', '38', 'generic', 'x86_64', 'with', 'debian', 'jessie', 'sid'] # docker says: # ['Linux', '4.4.17', 'boot2docker', 'x86_64', 'with', 'debian', 'stretch', 'sid'] if ( "trusty" in ubuntu_version or "jessie" in ubuntu_version or "stretch" in ubuntu_version ): # assert GObject.pygobject_version == (3, 22, 0) assert GObject.pygobject_version[0] == 3 assert GObject.pygobject_version[1] >= 22 assert GObject.pygobject_version[2] >= 0 else: # assert GObject.pygobject_version == (3, 20, 0) assert GObject.pygobject_version[0] == 3 assert GObject.pygobject_version[1] >= 20 assert GObject.pygobject_version[2] >= 0 # Verify Gstremaer 1.8.2 or 1.8.3 gst_version_string = Gst.version_string() m = re.search("(GStreamer 1.8.2|GStreamer 1.8.3)", gst_version_string) # If we get a string match on either of these versions then we have # 1.8.2/1.8.3, else None assert m
def quote_uri(uri): """Encodes a URI according to RFC 2396. Does not touch the file:/// part. Args: uri (str, byte): Uri Returns: (str): string of uri """ # NOTE: bossjones added # If we have a byte instead of a strng, decode to str type if isinstance(uri, compat.bytes): uri = uri.decode("utf-8") # Split off the "file:///" part, if present. # In [34]: uri = 'file:///etc/fstab' # # In [35]: compat.urlsplit(uri, allow_fragments=False) # Out[35]: SplitResult(scheme='file', netloc='', path='/etc/fstab', query='', fragment='') parts = compat.urlsplit(uri, allow_fragments=False) # Make absolutely sure the string is unquoted before quoting again! # In [46]: raw_path = compat.unquote(parts.path) # # In [47]: raw_path # Out[47]: '/etc/fstab' raw_path = compat.unquote(parts.path) # For computing thumbnail md5 hashes in the media library, we must adhere to # RFC 2396. It is quite tricky to handle all corner cases, leave it to Gst: return Gst.filename_to_uri(raw_path)
def gstreamer_info(): other = [] other.append("Python wrapper: python-gi %s" % gi.__version__) found_elements = [] missing_elements = [] for name, status in _gstreamer_check_elements(): if status: found_elements.append(name) else: missing_elements.append(name) other.append("Relevant elements:") other.append(" Found:") for element in found_elements: other.append(" %s" % element) if not found_elements: other.append(" none") other.append(" Not found:") for element in missing_elements: other.append(" %s" % element) if not missing_elements: other.append(" none") return { "name": "GStreamer", "version": ".".join(map(str, Gst.version())), "path": os.path.dirname(gi.__file__), "other": "\n".join(other), }
def uri_is_valid(uri): """Checks if the specified URI is usable (of type file://). Will also check if the size is valid (> 0). Args: uri (str): The location to check. Return: (boolean): True if valid, False otherwise. """ # If we have a byte instead of a strng, decode to str type if isinstance(uri, compat.bytes): uri = uri.decode("utf-8") return (Gst.uri_is_valid(uri) and Gst.uri_get_protocol(uri) == "file" and len(os.path.basename(Gst.uri_get_location(uri))) > 0)
def test_gstreamer_info(self): result = deps.gstreamer_info() assert "GStreamer" == result["name"] assert ".".join(map(str, Gst.version())) == result["version"] assert "gi" in result["path"] assert "__init__.py" not in result["path"] assert "Python wrapper: python-gi" in result["other"] assert gi.__version__ in result["other"] assert "Relevant elements:" in result["other"]
def uri_is_valid(uri): """Checks if the specified URI is usable (of type file://). Will also check if the size is valid (> 0). Args: uri (str): The location to check. Return: (boolean): True if valid, False otherwise. """ # If we have a byte instead of a strng, decode to str type if isinstance(uri, compat.bytes): uri = uri.decode("utf-8") return ( Gst.uri_is_valid(uri) and Gst.uri_get_protocol(uri) == "file" and len(os.path.basename(Gst.uri_get_location(uri))) > 0 )
def get_connected_audio_devices(): devices = {} dm = Gst.DeviceMonitor() dm.start() for device in dm.get_devices(): device_class = device.get_device_class() props = device.get_properties() element = device.create_element(None) type_name = element.get_factory().get_name() device_name = element.props.device print("%s device=%r" % (type_name, device_name)) dm.stop()
def on_debug_activate(self): # FIXME: This needs to use dynamic paths, it's possible that we're having issues because of order of operations # FIXME: STATIC PATH 7/3/2018 # dotfile = ( # "/home/pi/dev/bossjones-github/scarlett_os/_debug/generator-listener.dot" # ) # pngfile = "/home/pi/dev/bossjones-github/scarlett_os/_debug/generator-listener-pipeline.png" # NOQA dotfile = self._dotfile_listener pngfile = self._pngfile_listener if os.access(dotfile, os.F_OK): os.remove(dotfile) if os.access(pngfile, os.F_OK): os.remove(pngfile) Gst.debug_bin_to_dot_file(self.pipelines_stack[0], Gst.DebugGraphDetails.ALL, "generator-listener") cmd = "/usr/bin/dot -Tpng -o {pngfile} {dotfile}".format( pngfile=pngfile, dotfile=dotfile) os.system(cmd)
def on_debug_activate(self): # FIXME: This needs to use dynamic paths, it's possible that we're having issues because of order of operations # FIXME: STATIC PATH 7/3/2018 # dotfile = ( # "/home/pi/dev/bossjones-github/scarlett_os/_debug/generator-listener.dot" # ) # pngfile = "/home/pi/dev/bossjones-github/scarlett_os/_debug/generator-listener-pipeline.png" # NOQA dotfile = self._dotfile_listener pngfile = self._pngfile_listener if os.access(dotfile, os.F_OK): os.remove(dotfile) if os.access(pngfile, os.F_OK): os.remove(pngfile) Gst.debug_bin_to_dot_file( self.pipelines_stack[0], Gst.DebugGraphDetails.ALL, "generator-listener" ) cmd = "/usr/bin/dot -Tpng -o {pngfile} {dotfile}".format( pngfile=pngfile, dotfile=dotfile ) os.system(cmd)
def calculate_duration(num_samples, sample_rate): """Determine duration of samples using GStreamer helper for precise math.""" if _gst_available(): return Gst.util_uint64_scale(num_samples, Gst.SECOND, sample_rate)
def init_gst(self): logger.debug("Inside init_gst") self.start_time = time.time() pipeline = Gst.parse_launch(" ! ".join( self.get_pocketsphinx_definition())) logger.debug("After get_pocketsphinx_definition") # Add pipeline obj to stack we can pull from later self.pipelines_stack.append(pipeline) gst_bus = pipeline.get_bus() # gst_bus = pipeline.get_gst_bus() gst_bus.add_signal_watch() self.bus_message_element_handler_id = gst_bus.connect( "message::element", self._on_message) self.bus_message_eos_handler_id = gst_bus.connect( "message::eos", self._on_message) self.bus_message_error_handler_id = gst_bus.connect( "message::error", self._on_message) self.bus_message_state_changed_handler_id = gst_bus.connect( "message::state-changed", self._on_state_changed) # Add bus obj to stack we can pull from later self.gst_bus_stack.append(gst_bus) appsink = pipeline.get_by_name("appsink") appsink.set_property( "caps", Gst.Caps.from_string( "audio/x-raw,format=(string)S16LE,rate=(int)16000,channels=(int)1,layout=(string)interleaved" ), ) appsink.set_property("drop", False) appsink.set_property("max-buffers", BUFFER_SIZE) appsink.set_property("sync", False) # The callback to receive decoded data. appsink.set_property("emit-signals", True) appsink.connect("new-sample", self._new_sample) self.caps_handler = appsink.get_static_pad("sink").connect( "notify::caps", self._notify_caps) self.elements_stack.append(appsink) # ************************************************************ # get gst pipeline element pocketsphinx and set properties - BEGIN # ************************************************************ pocketsphinx = pipeline.get_by_name("asr") # from scarlett_os.internal.debugger import dump # print("debug-2018-pocketsphinx - BEGIN") # dump(pocketsphinx.get_property('decoder')) # print("debug-2018-pocketsphinx - END") # print(pocketsphinx.list_properties()) if self._hmm: pocketsphinx.set_property("hmm", self._hmm) if self._lm: pocketsphinx.set_property("lm", self._lm) if self._dic: pocketsphinx.set_property("dict", self._dic) if self._fwdflat: pocketsphinx.set_property("fwdflat", self._fwdflat) if self._bestpath: pocketsphinx.set_property("bestpath", self._bestpath) if self._dsratio: pocketsphinx.set_property("dsratio", self._dsratio) if self._maxhmmpf: pocketsphinx.set_property("maxhmmpf", self._maxhmmpf) if self._bestpath: pocketsphinx.set_property("bestpath", self._bestpath) # if self._silprob: # pocketsphinx.set_property("silprob", self._silprob) # if self._wip: # pocketsphinx.set_property("wip", self._wip) # ************************************************************ # get gst pipeline element pocketsphinx and set properties - END # ************************************************************ # NOTE: Old way of setting pocketsphinx properties. 8/5/2018 # pocketsphinx.set_property( # "fwdflat", True # ) # Enable Flat Lexicon Search | Default: true # pocketsphinx.set_property( # "bestpath", True # ) # Enable Graph Search | Boolean. Default: true # pocketsphinx.set_property( # "dsratio", 1 # ) # Evaluate acoustic model every N frames | Integer. Range: 1 - 10 Default: 1 # pocketsphinx.set_property( # "maxhmmpf", 3000 # ) # Maximum number of HMMs searched per frame | Integer. Range: 1 - 100000 Default: 30000 # pocketsphinx.set_property( # "bestpath", True # ) # Enable Graph Search | Boolean. Default: true # pocketsphinx.set_property('maxwpf', -1) # # pocketsphinx.set_property('maxwpf', 20) # Maximum number of words # searched per frame | Range: 1 - 100000 Default: -1 self.elements_stack.append(pocketsphinx) capsfilter_queue = pipeline.get_by_name("capsfilter_queue") capsfilter_queue.set_property("leaky", True) # prefer fresh data capsfilter_queue.set_property("silent", False) capsfilter_queue.set_property("max-size-time", 0) # 0 seconds capsfilter_queue.set_property("max-size-buffers", 0) capsfilter_queue.set_property("max-size-bytes", 0) self.capsfilter_queue_overrun_handler_id = capsfilter_queue.connect( "overrun", self._log_queue_overrun) # capsfilter_queue.connect('overrun', self._on_overrun) # capsfilter_queue.connect('underrun', self._on_underrun) # capsfilter_queue.connect('pushing', self._on_pushing) # capsfilter_queue.connect('running', self._on_running) self.elements_stack.append(capsfilter_queue) ident = pipeline.get_by_name("ident") # ident.connect('handoff', self._on_handoff) self.elements_stack.append(ident) logger.debug("After all self.elements_stack.append() calls") # Set up the queue for data and run the main thread. self.queue = queue.Queue(QUEUE_SIZE) self.thread = get_loop_thread()
def init_gst(self): logger.debug("Inside init_gst") self.start_time = time.time() pipeline = Gst.parse_launch(" ! ".join(self.get_pocketsphinx_definition())) logger.debug("After get_pocketsphinx_definition") # Add pipeline obj to stack we can pull from later self.pipelines_stack.append(pipeline) gst_bus = pipeline.get_bus() # gst_bus = pipeline.get_gst_bus() gst_bus.add_signal_watch() self.bus_message_element_handler_id = gst_bus.connect( "message::element", self._on_message ) self.bus_message_eos_handler_id = gst_bus.connect( "message::eos", self._on_message ) self.bus_message_error_handler_id = gst_bus.connect( "message::error", self._on_message ) self.bus_message_state_changed_handler_id = gst_bus.connect( "message::state-changed", self._on_state_changed ) # Add bus obj to stack we can pull from later self.gst_bus_stack.append(gst_bus) appsink = pipeline.get_by_name("appsink") appsink.set_property( "caps", Gst.Caps.from_string( "audio/x-raw,format=(string)S16LE,rate=(int)16000,channels=(int)1,layout=(string)interleaved" ), ) appsink.set_property("drop", False) appsink.set_property("max-buffers", BUFFER_SIZE) appsink.set_property("sync", False) # The callback to receive decoded data. appsink.set_property("emit-signals", True) appsink.connect("new-sample", self._new_sample) self.caps_handler = appsink.get_static_pad("sink").connect( "notify::caps", self._notify_caps ) self.elements_stack.append(appsink) # ************************************************************ # get gst pipeline element pocketsphinx and set properties - BEGIN # ************************************************************ pocketsphinx = pipeline.get_by_name("asr") # from scarlett_os.internal.debugger import dump # print("debug-2018-pocketsphinx - BEGIN") # dump(pocketsphinx.get_property('decoder')) # print("debug-2018-pocketsphinx - END") # print(pocketsphinx.list_properties()) if self._hmm: pocketsphinx.set_property("hmm", self._hmm) if self._lm: pocketsphinx.set_property("lm", self._lm) if self._dic: pocketsphinx.set_property("dict", self._dic) if self._fwdflat: pocketsphinx.set_property("fwdflat", self._fwdflat) if self._bestpath: pocketsphinx.set_property("bestpath", self._bestpath) if self._dsratio: pocketsphinx.set_property("dsratio", self._dsratio) if self._maxhmmpf: pocketsphinx.set_property("maxhmmpf", self._maxhmmpf) if self._bestpath: pocketsphinx.set_property("bestpath", self._bestpath) # if self._silprob: # pocketsphinx.set_property("silprob", self._silprob) # if self._wip: # pocketsphinx.set_property("wip", self._wip) # ************************************************************ # get gst pipeline element pocketsphinx and set properties - END # ************************************************************ # NOTE: Old way of setting pocketsphinx properties. 8/5/2018 # pocketsphinx.set_property( # "fwdflat", True # ) # Enable Flat Lexicon Search | Default: true # pocketsphinx.set_property( # "bestpath", True # ) # Enable Graph Search | Boolean. Default: true # pocketsphinx.set_property( # "dsratio", 1 # ) # Evaluate acoustic model every N frames | Integer. Range: 1 - 10 Default: 1 # pocketsphinx.set_property( # "maxhmmpf", 3000 # ) # Maximum number of HMMs searched per frame | Integer. Range: 1 - 100000 Default: 30000 # pocketsphinx.set_property( # "bestpath", True # ) # Enable Graph Search | Boolean. Default: true # pocketsphinx.set_property('maxwpf', -1) # # pocketsphinx.set_property('maxwpf', 20) # Maximum number of words # searched per frame | Range: 1 - 100000 Default: -1 self.elements_stack.append(pocketsphinx) capsfilter_queue = pipeline.get_by_name("capsfilter_queue") capsfilter_queue.set_property("leaky", True) # prefer fresh data capsfilter_queue.set_property("silent", False) capsfilter_queue.set_property("max-size-time", 0) # 0 seconds capsfilter_queue.set_property("max-size-buffers", 0) capsfilter_queue.set_property("max-size-bytes", 0) self.capsfilter_queue_overrun_handler_id = capsfilter_queue.connect( "overrun", self._log_queue_overrun ) # capsfilter_queue.connect('overrun', self._on_overrun) # capsfilter_queue.connect('underrun', self._on_underrun) # capsfilter_queue.connect('pushing', self._on_pushing) # capsfilter_queue.connect('running', self._on_running) self.elements_stack.append(capsfilter_queue) ident = pipeline.get_by_name("ident") # ident.connect('handoff', self._on_handoff) self.elements_stack.append(ident) logger.debug("After all self.elements_stack.append() calls") # Set up the queue for data and run the main thread. self.queue = queue.Queue(QUEUE_SIZE) self.thread = get_loop_thread()