diff --git a/docs/html/pipewire_python.html b/docs/html/pipewire_python.html index a782e91..f8ed22e 100644 --- a/docs/html/pipewire_python.html +++ b/docs/html/pipewire_python.html @@ -86,12 +86,12 @@
Developed with ❤️ by Pablo Diaz & Anna Absi
+Developed with ❤️ by Pablo Diaz
pip3 install pipewire_python # or pip
+pip3 install pipewire_python # or pip
43class Controller: - 44 """ - 45 Class that controls pipewire command line interface - 46 with shell commands, handling outputs, loading default - 47 configs and more. - 48 """ - 49 - 50 _pipewire_cli = { # Help - 51 "--help": "--help", # -h - 52 "--version": "--version", - 53 "--remote": None, # -r - 54 } - 55 - 56 _pipewire_modes = { # Modes - 57 "--playback": None, # -p - 58 "--record": None, # -r - 59 "--midi": None, # -m - 60 } - 61 - 62 _pipewire_list_targets = { # "--list-targets": None, - 63 "list_playback": None, - 64 "list_record": None, - 65 } - 66 - 67 _pipewire_configs = { # Configs - 68 "--media-type": None, # *default=Audio - 69 "--media-category": None, # *default=Playback - 70 "--media-role": None, # *default=Music - 71 "--target": None, # *default=auto - 72 "--latency": None, # *default=100ms (SOURCE FILE if not specified) - 73 "--rate": None, # *default=48000 - 74 "--channels": None, # [1,2] *default=2 - 75 "--channel-map": None, # ["stereo", "surround-51", "FL,FR"...] *default="FL,FR" - 76 "--format": None, # [u8|s8|s16|s32|f32|f64] *default=s16 - 77 "--volume": None, # [0.0,1.0] *default=1.000 - 78 "--quality": None, # -q # [0,15] *default=4 - 79 "--verbose": None, # -v - 80 } - 81 - 82 _kill_pipewire = { - 83 "all": ["kill", "$(pidof pw-cat)"], - 84 "playback": ["kill", "$(pidof pw-play)"], - 85 "record": ["kill", "$(pidof pw-record)"], - 86 } - 87 - 88 def __init__( - 89 self, - 90 # Debug - 91 verbose: bool = False, - 92 ): - 93 """This constructor load default configs from OS executing - 94 the following pipewire command - 95 - 96 ```bash - 97 #!/bin/bash - 98 # Get defaults from output of: - 99 pw-cat -h -100 ``` -101 """ -102 # LOAD ALL DEFAULT PARAMETERS +@@ -1364,49 +1362,49 @@41class Controller: + 42 """ + 43 Class that controls pipewire command line interface + 44 with shell commands, handling outputs, loading default + 45 configs and more. + 46 """ + 47 + 48 _pipewire_cli = { # Help + 49 "--help": "--help", # -h + 50 "--version": "--version", + 51 "--remote": None, # -r + 52 } + 53 + 54 _pipewire_modes = { # Modes + 55 "--playback": None, # -p + 56 "--record": None, # -r + 57 "--midi": None, # -m + 58 } + 59 + 60 _pipewire_list_targets = { # "--list-targets": None, + 61 "list_playback": None, + 62 "list_record": None, + 63 } + 64 + 65 _pipewire_configs = { # Configs + 66 "--media-type": None, # *default=Audio + 67 "--media-category": None, # *default=Playback + 68 "--media-role": None, # *default=Music + 69 "--target": None, # *default=auto + 70 "--latency": None, # *default=100ms (SOURCE FILE if not specified) + 71 "--rate": None, # *default=48000 + 72 "--channels": None, # [1,2] *default=2 + 73 "--channel-map": None, # ["stereo", "surround-51", "FL,FR"...] *default="FL,FR" + 74 "--format": None, # [u8|s8|s16|s32|f32|f64] *default=s16 + 75 "--volume": None, # [0.0,1.0] *default=1.000 + 76 "--quality": None, # -q # [0,15] *default=4 + 77 "--verbose": None, # -v + 78 } + 79 + 80 _kill_pipewire = { + 81 "all": ["kill", "$(pidof pw-cat)"], + 82 "playback": ["kill", "$(pidof pw-play)"], + 83 "record": ["kill", "$(pidof pw-record)"], + 84 } + 85 + 86 def __init__( + 87 self, + 88 # Debug + 89 verbose: bool = False, + 90 ): + 91 """This constructor load default configs from OS executing + 92 the following pipewire command + 93 + 94 ```bash + 95 #!/bin/bash + 96 # Get defaults from output of: + 97 pw-cat -h + 98 ``` + 99 """ +100 # LOAD ALL DEFAULT PARAMETERS +101 +102 mycommand = ["pw-cat", "-h"] 103 -104 mycommand = ["pw-cat", "-h"] -105 -106 # get default parameters with help -107 stdout, _ = _execute_shell_command(command=mycommand, verbose=verbose) # stderr -108 # convert stdout to dictionary -109 dict_default_values = _get_dict_from_stdout(stdout=str(stdout.decode()), verbose=verbose) -110 -111 if verbose: -112 print(self._pipewire_configs) -113 -114 # Save default system configs to our json -115 self._pipewire_configs.update( -116 ([(key, dict_default_values[key]) for key in dict_default_values]) -117 ) -118 -119 if verbose: -120 print(self._pipewire_configs) -121 -122 # Delete keys with None values -123 self._pipewire_configs = _drop_keys_with_none_values(self._pipewire_configs) -124 -125 if verbose: -126 print(self._pipewire_configs) -127 -128 # Load values of list targets -129 self.load_list_targets(mode="playback", verbose=verbose) -130 self.load_list_targets(mode="record", verbose=verbose) -131 -132 def _help_cli( -133 self, -134 # Debug -135 verbose: bool = True, -136 ): -137 """Get pipewire command line help""" +104 # get default parameters with help +105 stdout, _ = _execute_shell_command(command=mycommand, verbose=verbose) # stderr +106 # convert stdout to dictionary +107 dict_default_values = _get_dict_from_stdout(stdout=str(stdout.decode()), verbose=verbose) +108 +109 if verbose: +110 print(self._pipewire_configs) +111 +112 # Save default system configs to our json +113 self._pipewire_configs.update( +114 ([(key, dict_default_values[key]) for key in dict_default_values]) +115 ) +116 +117 if verbose: +118 print(self._pipewire_configs) +119 +120 # Delete keys with None values +121 self._pipewire_configs = _drop_keys_with_none_values(self._pipewire_configs) +122 +123 if verbose: +124 print(self._pipewire_configs) +125 +126 # Load values of list targets +127 self.load_list_targets(mode="playback", verbose=verbose) +128 self.load_list_targets(mode="record", verbose=verbose) +129 +130 def _help_cli( +131 self, +132 # Debug +133 verbose: bool = True, +134 ): +135 """Get pipewire command line help""" +136 +137 mycommand = ["pipewire", self._pipewire_cli["--help"]] 138 -139 mycommand = ["pipewire", self._pipewire_cli["--help"]] +139 stdout, _ = _execute_shell_command(command=mycommand, verbose=verbose) # stderr 140 -141 stdout, _ = _execute_shell_command(command=mycommand, verbose=verbose) # stderr +141 return stdout 142 -143 return stdout -144 -145 def get_version( -146 self, -147 # Debug -148 verbose: bool = False, -149 ): -150 """Get version of pipewire installed on OS by executing the following -151 code: -152 -153 ```bash -154 #!/bin/bash -155 pw-cli --version -156 ``` -157 -158 Args: -159 verbose (bool) : True enable debug logs. *default=False -160 -161 Returns: -162 - versions (list) : Versions of pipewire compiled -163 """ +143 def get_version( +144 self, +145 # Debug +146 verbose: bool = False, +147 ): +148 """Get version of pipewire installed on OS by executing the following +149 code: +150 +151 ```bash +152 #!/bin/bash +153 pw-cli --version +154 ``` +155 +156 Args: +157 verbose (bool) : True enable debug logs. *default=False +158 +159 Returns: +160 - versions (list) : Versions of pipewire compiled +161 """ +162 +163 mycommand = ["pw-cli", "--version"] 164 -165 mycommand = ["pw-cli", "--version"] -166 -167 if verbose: -168 print(f"[mycommand]{mycommand}") -169 -170 stdout, _ = _execute_shell_command(command=mycommand, timeout=-1, verbose=verbose) -171 versions = stdout.decode().split("\n")[1:] +165 if verbose: +166 print(f"[mycommand]{mycommand}") +167 +168 stdout, _ = _execute_shell_command(command=mycommand, timeout=-1, verbose=verbose) +169 versions = stdout.decode().split("\n")[1:] +170 +171 self._pipewire_cli["--version"] = versions 172 -173 self._pipewire_cli["--version"] = versions +173 return versions 174 -175 return versions -176 -177 def verbose( -178 self, -179 status: bool = True, -180 ): -181 """Get full log of pipewire stream status with the command `pw-cat` +175 def verbose( +176 self, +177 status: bool = True, +178 ): +179 """Get full log of pipewire stream status with the command `pw-cat` +180 +181 An example of pw-cli usage is the code below: 182 -183 An example of pw-cli usage is the code below: -184 -185 ```bash -186 #!/bin/bash -187 # For example -188 pw-cat --playback beers.wav --verbose -189 ``` +183 ```bash +184 #!/bin/bash +185 # For example +186 pw-cat --playback beers.wav --verbose +187 ``` +188 +189 that will generate an output like this: 190 -191 that will generate an output like this: -192 -193 ```bash -194 opened file "beers.wav" format 00010002 channels:2 rate:44100 -195 using default channel map: FL,FR -196 rate=44100 channels=2 fmt=s16 samplesize=2 stride=4 latency=4410 (0.100s) -197 connecting playback stream; target_id=4294967295 -198 stream state changed unconnected -> connecting -199 stream param change: id=2 -200 stream properties: -201 media.type = "Audio" -202 ... -203 now=0 rate=0/0 ticks=0 delay=0 queued=0 -204 remote 0 is named "pipewire-0" -205 core done -206 stream state changed connecting -> paused -207 stream param change: id=2 -208 ... -209 stream param change: id=15 -210 stream param change: id=15 -211 now=13465394419270 rate=1/48000 ticks=35840 delay=512 queued=0 -212 now=13466525228363 rate=1/48000 ticks=90112 delay=512 queued=0 -213 ... -214 stream drained -215 stream state changed streaming -> paused +191 ```bash +192 opened file "beers.wav" format 00010002 channels:2 rate:44100 +193 using default channel map: FL,FR +194 rate=44100 channels=2 fmt=s16 samplesize=2 stride=4 latency=4410 (0.100s) +195 connecting playback stream; target_id=4294967295 +196 stream state changed unconnected -> connecting +197 stream param change: id=2 +198 stream properties: +199 media.type = "Audio" +200 ... +201 now=0 rate=0/0 ticks=0 delay=0 queued=0 +202 remote 0 is named "pipewire-0" +203 core done +204 stream state changed connecting -> paused +205 stream param change: id=2 +206 ... +207 stream param change: id=15 +208 stream param change: id=15 +209 now=13465394419270 rate=1/48000 ticks=35840 delay=512 queued=0 +210 now=13466525228363 rate=1/48000 ticks=90112 delay=512 queued=0 +211 ... +212 stream drained +213 stream state changed streaming -> paused +214 stream param change: id=4 +215 stream state changed paused -> unconnected 216 stream param change: id=4 -217 stream state changed paused -> unconnected -218 stream param change: id=4 -219 ``` -220 """ -221 -222 if status: -223 self._pipewire_configs["--verbose"] = " " -224 else: -225 pass -226 -227 def get_config(self): -228 """Return config dictionary with default or setup variables, remember that -229 this object changes only on python-side. Is not updated on real time, -230 For real-time, please create and destroy the class. -231 -232 Args: -233 Nothing -234 -235 Returns: -236 - _pipewire_configs (`dict`) : dictionary with config values +217 ``` +218 """ +219 +220 if status: +221 self._pipewire_configs["--verbose"] = " " +222 else: +223 pass +224 +225 def get_config(self): +226 """Return config dictionary with default or setup variables, remember that +227 this object changes only on python-side. Is not updated on real time, +228 For real-time, please create and destroy the class. +229 +230 Args: +231 Nothing +232 +233 Returns: +234 - _pipewire_configs (`dict`) : dictionary with config values +235 +236 """ 237 -238 """ +238 return self._pipewire_configs 239 -240 return self._pipewire_configs -241 -242 def set_config( -243 self, -244 # configs -245 media_type=None, -246 media_category=None, -247 media_role=None, -248 target=None, -249 latency=None, -250 rate=None, -251 channels=None, -252 channels_map=None, -253 _format=None, -254 volume=None, -255 quality=None, -256 # Debug -257 verbose=False, -258 ): -259 """Method that get args as variables and set them -260 to the `json` parameter of the class `_pipewire_configs`, -261 then you can use in other method, such as `playback(...)` or -262 `record(...)`. This method verifies values to avoid wrong -263 settings. -264 -265 Args: -266 media_type : Set media type -267 media_category : Set media category -268 media_role : Set media role -269 target : Set node target -270 latency : Set node latency *example=100ms -271 rate : Set sample rate [8000,11025,16000,22050,44100,48000,88200,96000,176400,192000,352800,384000] -272 channels : Numbers of channels [1,2] -273 channels_map : ["stereo", "surround-51", "FL,FR", ...] -274 _format : ["u8", "s8", "s16", "s32", "f32", "f64"] -275 volume : Stream volume [0.000, 1.000] -276 quality : Resampler quality [0, 15] -277 verbose (`bool`): True enable debug logs. *default=False -278 -279 Returns: -280 - Nothing -281 -282 More: -283 Check all links listed at the beginning of this page -284 """ # 1 - media_type -285 if media_type: -286 self._pipewire_configs["--media-type"] = str(media_type) -287 elif media_type is None: -288 pass -289 else: -290 raise ValueError( -291 f"{MESSAGES_ERROR['ValueError']}[media_type='{media_type}'] EMPTY VALUE" -292 ) -293 # 2 - media_category -294 if media_category: -295 self._pipewire_configs["--media-category"] = str(media_category) -296 elif media_category is None: -297 pass -298 else: -299 raise ValueError( -300 f"{MESSAGES_ERROR['ValueError']}[media_category='{media_category}'] EMPTY VALUE" -301 ) -302 # 3 - media_role -303 if media_role: -304 self._pipewire_configs["--media-role"] = str(media_role) -305 elif media_role is None: -306 pass -307 else: -308 raise ValueError( -309 f"{MESSAGES_ERROR['ValueError']}[media_role='{media_role}'] EMPTY VALUE" -310 ) -311 # 4 - target -312 if target: -313 self._pipewire_configs["--target"] = str(target) -314 elif target is None: -315 pass -316 else: -317 raise ValueError(f"{MESSAGES_ERROR['ValueError']}[target='{target}'] EMPTY VALUE") -318 # 5 - latency -319 if latency: -320 if any(chr.isdigit() for chr in latency): # Contain numbers -321 self._pipewire_configs["--latency"] = str(latency) -322 else: -323 raise ValueError( -324 f"{MESSAGES_ERROR['ValueError']}[latency='{latency}'] NO NUMBER IN VARIABLE" -325 ) -326 elif latency is None: -327 pass -328 else: -329 raise ValueError(f"{MESSAGES_ERROR['ValueError']}[latency='{latency}'] EMPTY VALUE") -330 # 6 - rate -331 if rate: -332 if rate in RECOMMENDED_RATES: -333 self._pipewire_configs["--rate"] = str(rate) -334 else: -335 raise ValueError( -336 f"{MESSAGES_ERROR['ValueError']}[rate='{rate}']\ -337 VALUE NOT IN RECOMMENDED LIST \n{RECOMMENDED_RATES}" -338 ) -339 elif rate is None: -340 pass -341 else: -342 raise ValueError(f"{MESSAGES_ERROR['ValueError']}[rate='{rate}'] EMPTY VALUE") -343 # 7 - channels -344 if channels: -345 if channels in [1, 2]: # values -346 self._pipewire_configs["--channels"] = str(channels) -347 else: -348 raise ValueError( -349 f"{MESSAGES_ERROR['ValueError']}[channels='{channels}']\ -350 WRONG VALUE\n ONLY 1 or 2." -351 ) -352 elif channels is None: -353 pass -354 else: -355 raise ValueError(f"{MESSAGES_ERROR['ValueError']}[channels='{channels}'] EMPTY VALUE") -356 # 8 - channels-map -357 if channels_map: -358 self._pipewire_configs["--channels-map"] = str(channels_map) -359 elif channels_map is None: -360 pass -361 else: -362 raise ValueError( -363 f"{MESSAGES_ERROR['ValueError']}[channels_map='{channels_map}'] EMPTY VALUE" -364 ) -365 # 9 - format -366 if _format: -367 if _format in RECOMMENDED_FORMATS: -368 self._pipewire_configs["--format"] = str(_format) -369 else: -370 raise ValueError( -371 f"{MESSAGES_ERROR['ValueError']}[_format='{_format}']\ -372 VALUE NOT IN RECOMMENDED LIST \n{RECOMMENDED_FORMATS}" -373 ) -374 elif _format is None: -375 pass -376 else: -377 raise ValueError(f"{MESSAGES_ERROR['ValueError']}[_format='{_format}'] EMPTY VALUE") -378 # 10 - volume -379 if volume: -380 if 0.0 <= volume <= 1.0: -381 self._pipewire_configs["--volume"] = str(volume) -382 else: -383 raise ValueError( -384 f"{MESSAGES_ERROR['ValueError']}[volume='{volume}']\ -385 OUT OF RANGE \n [0.000, 1.000]" -386 ) -387 elif volume is None: -388 pass -389 else: -390 raise ValueError(f"{MESSAGES_ERROR['ValueError']}[volume='{volume}'] EMPTY VALUE") -391 # 11 - quality -392 if quality: -393 if 0 <= quality <= 15: -394 self._pipewire_configs["--quality"] = str(quality) -395 else: -396 raise ValueError( -397 f"{MESSAGES_ERROR['ValueError']}[quality='{quality}'] OUT OF RANGE \n [0, 15]" -398 ) -399 elif quality is None: -400 pass -401 else: -402 raise ValueError(f"{MESSAGES_ERROR['ValueError']}[volume='{volume}'] EMPTY VALUE") -403 -404 # 12 - verbose cli -405 if verbose: # True -406 self._pipewire_configs["--verbose"] = " " -407 else: -408 pass -409 -410 if verbose: -411 print(self._pipewire_configs) -412 -413 def load_list_targets( -414 self, -415 mode, # playback or record -416 # Debug, -417 verbose: bool = False, -418 ): -419 """Returns a list of targets to playback or record. Then you can use -420 the output to select a device to playback or record. -421 """ -422 -423 if mode == "playback": -424 mycommand = ["pw-cat", "--playback", "--list-targets"] -425 stdout, _ = _execute_shell_command(command=mycommand, timeout=-1, verbose=verbose) -426 self._pipewire_list_targets["list_playback"] = _generate_dict_list_targets( -427 longstring=stdout.decode(), verbose=verbose -428 ) -429 elif mode == "record": -430 mycommand = ["pw-cat", "--record", "--list-targets"] -431 stdout, _ = _execute_shell_command(command=mycommand, timeout=-1, verbose=verbose) -432 self._pipewire_list_targets["list_record"] = _generate_dict_list_targets( -433 longstring=stdout.decode(), verbose=verbose -434 ) -435 else: -436 raise AttributeError(MESSAGES_ERROR["ValueError"]) -437 -438 if verbose: -439 print(f"[mycommand]{mycommand}") -440 -441 def get_list_targets( -442 self, -443 # Debug, -444 verbose: bool = False, -445 ): -446 """Returns a list of targets to playback or record. Then you can use -447 the output to select a device to playback or record. -448 -449 Returns: -450 - `_pipewire_list_targets` -451 -452 Examples: -453 ```python -454 >>> Controller().get_list_targets() -455 { -456 "list_playback": { -457 "86": { -458 "description": "Starship/Matisse HD Audio Controller Pro", -459 "prior": "936" -460 }, -461 "_list_nodes": [ -462 "86" -463 ], -464 "_node_default": [ -465 "86" -466 ], -467 "_alsa_node": [ -468 "alsa_output.pci-0000_0a_00.4.pro-output-0" -469 ] -470 }, -471 "list_record": { -472 "86": { -473 "description": "Starship/Matisse HD Audio Controller Pro", -474 "prior": "936" -475 }, -476 "_list_nodes": [ -477 "86" -478 ], -479 "_node_default": [ -480 "86" -481 ], -482 "_alsa_node": [ -483 "alsa_output.pci-0000_0a_00.4.pro-output-0" -484 ] -485 } -486 } -487 ``` -488 """ -489 if verbose: -490 print(self._pipewire_list_targets) -491 return self._pipewire_list_targets -492 -493 def get_list_interfaces( -494 self, -495 filtered_by_type: str = True, -496 type_interfaces: str = "Client", -497 # Debug -498 verbose: bool = False, -499 ): -500 """Returns a list of applications currently using pipewire on Client. -501 An example of pw-cli usage is the code below: -502 -503 ```bash -504 #!/bin/bash -505 pw-cli ls Client -506 ``` -507 Args: -508 filtered_by_type : If False, returns all. If not, returns a fitered dict -509 type_interfaces : Set type of Interface ["Client","Link","Node","Factory","Module","Metadata","Endpoint","Session","Endpoint Stream","EndpointLink","Port"] -510 -511 Returns: -512 - dict_interfaces_filtered: dictionary with list of interfaces matching conditions -513 -514 Examples: -515 ```python -516 >>> Controller().get_list_interfaces() -517 -518 ``` -519 """ -520 mycommand = ["pw-cli", "info", "all"] -521 -522 # if verbose: -523 # print(f"[mycommand]{mycommand}") -524 -525 stdout, _ = _execute_shell_command(command=mycommand, timeout=-1, verbose=verbose) -526 dict_interfaces = _generate_dict_interfaces(longstring=stdout.decode(), verbose=verbose) -527 -528 if filtered_by_type: -529 dict_interfaces_filtered = _filter_by_type( -530 dict_interfaces=dict_interfaces, type_interfaces=type_interfaces -531 ) -532 else: -533 dict_interfaces_filtered = dict_interfaces +240 def set_config( +241 self, +242 # configs +243 media_type=None, +244 media_category=None, +245 media_role=None, +246 target=None, +247 latency=None, +248 rate=None, +249 channels=None, +250 channels_map=None, +251 _format=None, +252 volume=None, +253 quality=None, +254 # Debug +255 verbose=False, +256 ): +257 """Method that get args as variables and set them +258 to the `json` parameter of the class `_pipewire_configs`, +259 then you can use in other method, such as `playback(...)` or +260 `record(...)`. This method verifies values to avoid wrong +261 settings. +262 +263 Args: +264 media_type : Set media type +265 media_category : Set media category +266 media_role : Set media role +267 target : Set node target +268 latency : Set node latency *example=100ms +269 rate : Set sample rate [8000,11025,16000,22050,44100,48000,88200,96000,176400,192000,352800,384000] +270 channels : Numbers of channels [1,2] +271 channels_map : ["stereo", "surround-51", "FL,FR", ...] +272 _format : ["u8", "s8", "s16", "s32", "f32", "f64"] +273 volume : Stream volume [0.000, 1.000] +274 quality : Resampler quality [0, 15] +275 verbose (`bool`): True enable debug logs. *default=False +276 +277 Returns: +278 - Nothing +279 +280 More: +281 Check all links listed at the beginning of this page +282 """ # 1 - media_type +283 if media_type: +284 self._pipewire_configs["--media-type"] = str(media_type) +285 elif media_type is None: +286 pass +287 else: +288 raise ValueError( +289 f"{MESSAGES_ERROR['ValueError']}[media_type='{media_type}'] EMPTY VALUE" +290 ) +291 # 2 - media_category +292 if media_category: +293 self._pipewire_configs["--media-category"] = str(media_category) +294 elif media_category is None: +295 pass +296 else: +297 raise ValueError( +298 f"{MESSAGES_ERROR['ValueError']}[media_category='{media_category}'] EMPTY VALUE" +299 ) +300 # 3 - media_role +301 if media_role: +302 self._pipewire_configs["--media-role"] = str(media_role) +303 elif media_role is None: +304 pass +305 else: +306 raise ValueError( +307 f"{MESSAGES_ERROR['ValueError']}[media_role='{media_role}'] EMPTY VALUE" +308 ) +309 # 4 - target +310 if target: +311 self._pipewire_configs["--target"] = str(target) +312 elif target is None: +313 pass +314 else: +315 raise ValueError(f"{MESSAGES_ERROR['ValueError']}[target='{target}'] EMPTY VALUE") +316 # 5 - latency +317 if latency: +318 if any(chr.isdigit() for chr in latency): # Contain numbers +319 self._pipewire_configs["--latency"] = str(latency) +320 else: +321 raise ValueError( +322 f"{MESSAGES_ERROR['ValueError']}[latency='{latency}'] NO NUMBER IN VARIABLE" +323 ) +324 elif latency is None: +325 pass +326 else: +327 raise ValueError(f"{MESSAGES_ERROR['ValueError']}[latency='{latency}'] EMPTY VALUE") +328 # 6 - rate +329 if rate: +330 if rate in RECOMMENDED_RATES: +331 self._pipewire_configs["--rate"] = str(rate) +332 else: +333 raise ValueError( +334 f"{MESSAGES_ERROR['ValueError']}[rate='{rate}']\ +335 VALUE NOT IN RECOMMENDED LIST \n{RECOMMENDED_RATES}" +336 ) +337 elif rate is None: +338 pass +339 else: +340 raise ValueError(f"{MESSAGES_ERROR['ValueError']}[rate='{rate}'] EMPTY VALUE") +341 # 7 - channels +342 if channels: +343 if channels in [1, 2]: # values +344 self._pipewire_configs["--channels"] = str(channels) +345 else: +346 raise ValueError( +347 f"{MESSAGES_ERROR['ValueError']}[channels='{channels}']\ +348 WRONG VALUE\n ONLY 1 or 2." +349 ) +350 elif channels is None: +351 pass +352 else: +353 raise ValueError(f"{MESSAGES_ERROR['ValueError']}[channels='{channels}'] EMPTY VALUE") +354 # 8 - channels-map +355 if channels_map: +356 self._pipewire_configs["--channels-map"] = str(channels_map) +357 elif channels_map is None: +358 pass +359 else: +360 raise ValueError( +361 f"{MESSAGES_ERROR['ValueError']}[channels_map='{channels_map}'] EMPTY VALUE" +362 ) +363 # 9 - format +364 if _format: +365 if _format in RECOMMENDED_FORMATS: +366 self._pipewire_configs["--format"] = str(_format) +367 else: +368 raise ValueError( +369 f"{MESSAGES_ERROR['ValueError']}[_format='{_format}']\ +370 VALUE NOT IN RECOMMENDED LIST \n{RECOMMENDED_FORMATS}" +371 ) +372 elif _format is None: +373 pass +374 else: +375 raise ValueError(f"{MESSAGES_ERROR['ValueError']}[_format='{_format}'] EMPTY VALUE") +376 # 10 - volume +377 if volume: +378 if 0.0 <= volume <= 1.0: +379 self._pipewire_configs["--volume"] = str(volume) +380 else: +381 raise ValueError( +382 f"{MESSAGES_ERROR['ValueError']}[volume='{volume}']\ +383 OUT OF RANGE \n [0.000, 1.000]" +384 ) +385 elif volume is None: +386 pass +387 else: +388 raise ValueError(f"{MESSAGES_ERROR['ValueError']}[volume='{volume}'] EMPTY VALUE") +389 # 11 - quality +390 if quality: +391 if 0 <= quality <= 15: +392 self._pipewire_configs["--quality"] = str(quality) +393 else: +394 raise ValueError( +395 f"{MESSAGES_ERROR['ValueError']}[quality='{quality}'] OUT OF RANGE \n [0, 15]" +396 ) +397 elif quality is None: +398 pass +399 else: +400 raise ValueError(f"{MESSAGES_ERROR['ValueError']}[volume='{volume}'] EMPTY VALUE") +401 +402 # 12 - verbose cli +403 if verbose: # True +404 self._pipewire_configs["--verbose"] = " " +405 else: +406 pass +407 +408 if verbose: +409 print(self._pipewire_configs) +410 +411 def load_list_targets( +412 self, +413 mode, # playback or record +414 # Debug, +415 verbose: bool = False, +416 ): +417 """Returns a list of targets to playback or record. Then you can use +418 the output to select a device to playback or record. +419 """ +420 +421 if mode == "playback": +422 mycommand = ["pw-cat", "--playback", "--list-targets"] +423 stdout, _ = _execute_shell_command(command=mycommand, timeout=-1, verbose=verbose) +424 self._pipewire_list_targets["list_playback"] = _generate_dict_list_targets( +425 longstring=stdout.decode(), verbose=verbose +426 ) +427 elif mode == "record": +428 mycommand = ["pw-cat", "--record", "--list-targets"] +429 stdout, _ = _execute_shell_command(command=mycommand, timeout=-1, verbose=verbose) +430 self._pipewire_list_targets["list_record"] = _generate_dict_list_targets( +431 longstring=stdout.decode(), verbose=verbose +432 ) +433 else: +434 raise AttributeError(MESSAGES_ERROR["ValueError"]) +435 +436 if verbose: +437 print(f"[mycommand]{mycommand}") +438 +439 def get_list_targets( +440 self, +441 # Debug, +442 verbose: bool = False, +443 ): +444 """Returns a list of targets to playback or record. Then you can use +445 the output to select a device to playback or record. +446 +447 Returns: +448 - `_pipewire_list_targets` +449 +450 Examples: +451 ```python +452 >>> Controller().get_list_targets() +453 { +454 "list_playback": { +455 "86": { +456 "description": "Starship/Matisse HD Audio Controller Pro", +457 "prior": "936" +458 }, +459 "_list_nodes": [ +460 "86" +461 ], +462 "_node_default": [ +463 "86" +464 ], +465 "_alsa_node": [ +466 "alsa_output.pci-0000_0a_00.4.pro-output-0" +467 ] +468 }, +469 "list_record": { +470 "86": { +471 "description": "Starship/Matisse HD Audio Controller Pro", +472 "prior": "936" +473 }, +474 "_list_nodes": [ +475 "86" +476 ], +477 "_node_default": [ +478 "86" +479 ], +480 "_alsa_node": [ +481 "alsa_output.pci-0000_0a_00.4.pro-output-0" +482 ] +483 } +484 } +485 ``` +486 """ +487 if verbose: +488 print(self._pipewire_list_targets) +489 return self._pipewire_list_targets +490 +491 def get_list_interfaces( +492 self, +493 filtered_by_type: str = True, +494 type_interfaces: str = "Client", +495 # Debug +496 verbose: bool = False, +497 ): +498 """Returns a list of applications currently using pipewire on Client. +499 An example of pw-cli usage is the code below: +500 +501 ```bash +502 #!/bin/bash +503 pw-cli ls Client +504 ``` +505 Args: +506 filtered_by_type : If False, returns all. If not, returns a fitered dict +507 type_interfaces : Set type of Interface ["Client","Link","Node","Factory","Module","Metadata","Endpoint","Session","Endpoint Stream","EndpointLink","Port"] +508 +509 Returns: +510 - dict_interfaces_filtered: dictionary with list of interfaces matching conditions +511 +512 Examples: +513 ```python +514 >>> Controller().get_list_interfaces() +515 +516 ``` +517 """ +518 mycommand = ["pw-cli", "info", "all"] +519 +520 # if verbose: +521 # print(f"[mycommand]{mycommand}") +522 +523 stdout, _ = _execute_shell_command(command=mycommand, timeout=-1, verbose=verbose) +524 dict_interfaces = _generate_dict_interfaces(longstring=stdout.decode(), verbose=verbose) +525 +526 if filtered_by_type: +527 dict_interfaces_filtered = _filter_by_type( +528 dict_interfaces=dict_interfaces, type_interfaces=type_interfaces +529 ) +530 else: +531 dict_interfaces_filtered = dict_interfaces +532 +533 return dict_interfaces_filtered 534 -535 return dict_interfaces_filtered -536 -537 def playback( -538 self, -539 audio_filename: str = "myplayback.wav", -540 # Debug -541 verbose: bool = False, -542 ): -543 """Execute pipewire command to play an audio file with the following -544 command: -545 -546 ```bash -547 #!/bin/bash -548 pw-cat --playback {audio_filename} + {configs} -549 # configs are a concatenated params -550 ``` -551 -552 Args: -553 audio_filename (`str`): Path of the file to be played. *default='myplayback.wav' -554 verbose (`bool`): True enable debug logs. *default=False -555 -556 Returns: -557 - stdout (`str`): Shell response to the command in stdout format -558 - stderr (`str`): Shell response response to the command in stderr format -559 """ -560 warnings.warn("The name of the function may change on future releases", DeprecationWarning) -561 -562 mycommand = ["pw-cat", "--playback", audio_filename] + _generate_command_by_dict( -563 mydict=self._pipewire_configs, verbose=verbose -564 ) -565 -566 if verbose: -567 print(f"[mycommand]{mycommand}") -568 -569 stdout, stderr = _execute_shell_command(command=mycommand, timeout=-1, verbose=verbose) -570 return stdout, stderr -571 -572 def record( -573 self, -574 audio_filename: str = "myplayback.wav", -575 timeout_seconds=5, -576 # Debug -577 verbose: bool = False, -578 ): -579 """Execute pipewire command to record an audio file, with a timeout of 5 -580 seconds with the following code and exiting the shell when tiomeout is over. -581 -582 ```bash -583 #!/bin/bash -584 pw-cat --record {audio_filename} -585 # timeout is managed by python3 (when signal CTRL+C is sended) -586 ``` -587 -588 Args: -589 audio_filename (`str`): Path of the file to be played. *default='myplayback.wav' -590 verbose (`bool`): True enable debug logs. *default=False -591 -592 Returns: -593 - stdout (`str`): Shell response to the command in stdout format -594 - stderr (`str`): Shell response response to the command in stderr format -595 """ -596 warnings.warn("The name of the function may change on future releases", DeprecationWarning) -597 -598 mycommand = ["pw-cat", "--record", audio_filename] + _generate_command_by_dict( -599 mydict=self._pipewire_configs, verbose=verbose -600 ) -601 -602 if verbose: -603 print(f"[mycommand]{mycommand}") -604 -605 stdout, stderr = _execute_shell_command( -606 command=mycommand, timeout=timeout_seconds, verbose=verbose -607 ) -608 return stdout, stderr -609 -610 def clear_devices( -611 self, -612 mode: str = "all", # ['all','playback','record'] -613 # Debug -614 verbose: bool = False, -615 ): -616 """Function to stop process running under pipewire executed by -617 python controller and with default process name of `pw-cat`, `pw-play` or `pw-record`. -618 -619 Args: -620 mode (`str`) : string to kill process under `pw-cat`, `pw-play` or `pw-record`. -621 -622 Returns: -623 - stdoutdict (`dict`) : a dictionary with keys of `mode`. -624 -625 Example with pipewire: -626 pw-cat process -627 """ +535 def playback( +536 self, +537 audio_filename: str = "myplayback.wav", +538 # Debug +539 verbose: bool = False, +540 ): +541 """Execute pipewire command to play an audio file with the following +542 command: +543 +544 ```bash +545 #!/bin/bash +546 pw-cat --playback {audio_filename} + {configs} +547 # configs are a concatenated params +548 ``` +549 +550 Args: +551 audio_filename (`str`): Path of the file to be played. *default='myplayback.wav' +552 verbose (`bool`): True enable debug logs. *default=False +553 +554 Returns: +555 - stdout (`str`): Shell response to the command in stdout format +556 - stderr (`str`): Shell response response to the command in stderr format +557 """ +558 warnings.warn("The name of the function may change on future releases", DeprecationWarning) +559 +560 mycommand = ["pw-cat", "--playback", audio_filename] + _generate_command_by_dict( +561 mydict=self._pipewire_configs, verbose=verbose +562 ) +563 +564 if verbose: +565 print(f"[mycommand]{mycommand}") +566 +567 stdout, stderr = _execute_shell_command(command=mycommand, timeout=-1, verbose=verbose) +568 return stdout, stderr +569 +570 def record( +571 self, +572 audio_filename: str = "myplayback.wav", +573 timeout_seconds=5, +574 # Debug +575 verbose: bool = False, +576 ): +577 """Execute pipewire command to record an audio file, with a timeout of 5 +578 seconds with the following code and exiting the shell when tiomeout is over. +579 +580 ```bash +581 #!/bin/bash +582 pw-cat --record {audio_filename} +583 # timeout is managed by python3 (when signal CTRL+C is sended) +584 ``` +585 +586 Args: +587 audio_filename (`str`): Path of the file to be played. *default='myplayback.wav' +588 verbose (`bool`): True enable debug logs. *default=False +589 +590 Returns: +591 - stdout (`str`): Shell response to the command in stdout format +592 - stderr (`str`): Shell response response to the command in stderr format +593 """ +594 warnings.warn("The name of the function may change on future releases", DeprecationWarning) +595 +596 mycommand = ["pw-cat", "--record", audio_filename] + _generate_command_by_dict( +597 mydict=self._pipewire_configs, verbose=verbose +598 ) +599 +600 if verbose: +601 print(f"[mycommand]{mycommand}") +602 +603 stdout, stderr = _execute_shell_command( +604 command=mycommand, timeout=timeout_seconds, verbose=verbose +605 ) +606 return stdout, stderr +607 +608 def clear_devices( +609 self, +610 mode: str = "all", # ['all','playback','record'] +611 # Debug +612 verbose: bool = False, +613 ): +614 """Function to stop process running under pipewire executed by +615 python controller and with default process name of `pw-cat`, `pw-play` or `pw-record`. +616 +617 Args: +618 mode (`str`) : string to kill process under `pw-cat`, `pw-play` or `pw-record`. +619 +620 Returns: +621 - stdoutdict (`dict`) : a dictionary with keys of `mode`. +622 +623 Example with pipewire: +624 pw-cat process +625 """ +626 +627 mycommand = self._kill_pipewire[mode] 628 -629 mycommand = self._kill_pipewire[mode] -630 -631 if verbose: -632 print(f"[mycommands]{mycommand}") +629 if verbose: +630 print(f"[mycommands]{mycommand}") +631 +632 stdout, _ = _execute_shell_command(command=mycommand, verbose=verbose) 633 -634 stdout, _ = _execute_shell_command(command=mycommand, verbose=verbose) -635 -636 return {mode: stdout} +634 return {mode: stdout}
88 def __init__( - 89 self, - 90 # Debug - 91 verbose: bool = False, - 92 ): - 93 """This constructor load default configs from OS executing - 94 the following pipewire command - 95 - 96 ```bash - 97 #!/bin/bash - 98 # Get defaults from output of: - 99 pw-cat -h -100 ``` -101 """ -102 # LOAD ALL DEFAULT PARAMETERS +@@ -1416,7 +1414,7 @@86 def __init__( + 87 self, + 88 # Debug + 89 verbose: bool = False, + 90 ): + 91 """This constructor load default configs from OS executing + 92 the following pipewire command + 93 + 94 ```bash + 95 #!/bin/bash + 96 # Get defaults from output of: + 97 pw-cat -h + 98 ``` + 99 """ +100 # LOAD ALL DEFAULT PARAMETERS +101 +102 mycommand = ["pw-cat", "-h"] 103 -104 mycommand = ["pw-cat", "-h"] -105 -106 # get default parameters with help -107 stdout, _ = _execute_shell_command(command=mycommand, verbose=verbose) # stderr -108 # convert stdout to dictionary -109 dict_default_values = _get_dict_from_stdout(stdout=str(stdout.decode()), verbose=verbose) -110 -111 if verbose: -112 print(self._pipewire_configs) -113 -114 # Save default system configs to our json -115 self._pipewire_configs.update( -116 ([(key, dict_default_values[key]) for key in dict_default_values]) -117 ) -118 -119 if verbose: -120 print(self._pipewire_configs) -121 -122 # Delete keys with None values -123 self._pipewire_configs = _drop_keys_with_none_values(self._pipewire_configs) -124 -125 if verbose: -126 print(self._pipewire_configs) -127 -128 # Load values of list targets -129 self.load_list_targets(mode="playback", verbose=verbose) -130 self.load_list_targets(mode="record", verbose=verbose) +104 # get default parameters with help +105 stdout, _ = _execute_shell_command(command=mycommand, verbose=verbose) # stderr +106 # convert stdout to dictionary +107 dict_default_values = _get_dict_from_stdout(stdout=str(stdout.decode()), verbose=verbose) +108 +109 if verbose: +110 print(self._pipewire_configs) +111 +112 # Save default system configs to our json +113 self._pipewire_configs.update( +114 ([(key, dict_default_values[key]) for key in dict_default_values]) +115 ) +116 +117 if verbose: +118 print(self._pipewire_configs) +119 +120 # Delete keys with None values +121 self._pipewire_configs = _drop_keys_with_none_values(self._pipewire_configs) +122 +123 if verbose: +124 print(self._pipewire_configs) +125 +126 # Load values of list targets +127 self.load_list_targets(mode="playback", verbose=verbose) +128 self.load_list_targets(mode="record", verbose=verbose)
#!/bin/bash # Get defaults from output of: -pw-cat -h +pw-cat -h
145 def get_version( -146 self, -147 # Debug -148 verbose: bool = False, -149 ): -150 """Get version of pipewire installed on OS by executing the following -151 code: -152 -153 ```bash -154 #!/bin/bash -155 pw-cli --version -156 ``` -157 -158 Args: -159 verbose (bool) : True enable debug logs. *default=False -160 -161 Returns: -162 - versions (list) : Versions of pipewire compiled -163 """ +@@ -1473,7 +1471,7 @@143 def get_version( +144 self, +145 # Debug +146 verbose: bool = False, +147 ): +148 """Get version of pipewire installed on OS by executing the following +149 code: +150 +151 ```bash +152 #!/bin/bash +153 pw-cli --version +154 ``` +155 +156 Args: +157 verbose (bool) : True enable debug logs. *default=False +158 +159 Returns: +160 - versions (list) : Versions of pipewire compiled +161 """ +162 +163 mycommand = ["pw-cli", "--version"] 164 -165 mycommand = ["pw-cli", "--version"] -166 -167 if verbose: -168 print(f"[mycommand]{mycommand}") -169 -170 stdout, _ = _execute_shell_command(command=mycommand, timeout=-1, verbose=verbose) -171 versions = stdout.decode().split("\n")[1:] +165 if verbose: +166 print(f"[mycommand]{mycommand}") +167 +168 stdout, _ = _execute_shell_command(command=mycommand, timeout=-1, verbose=verbose) +169 versions = stdout.decode().split("\n")[1:] +170 +171 self._pipewire_cli["--version"] = versions 172 -173 self._pipewire_cli["--version"] = versions -174 -175 return versions +173 return versions
@@ -1505,55 +1503,55 @@#!/bin/bash -pw-cli --version +pw-cli --version
Returns:
177 def verbose( -178 self, -179 status: bool = True, -180 ): -181 """Get full log of pipewire stream status with the command `pw-cat` +@@ -1564,38 +1562,38 @@175 def verbose( +176 self, +177 status: bool = True, +178 ): +179 """Get full log of pipewire stream status with the command `pw-cat` +180 +181 An example of pw-cli usage is the code below: 182 -183 An example of pw-cli usage is the code below: -184 -185 ```bash -186 #!/bin/bash -187 # For example -188 pw-cat --playback beers.wav --verbose -189 ``` +183 ```bash +184 #!/bin/bash +185 # For example +186 pw-cat --playback beers.wav --verbose +187 ``` +188 +189 that will generate an output like this: 190 -191 that will generate an output like this: -192 -193 ```bash -194 opened file "beers.wav" format 00010002 channels:2 rate:44100 -195 using default channel map: FL,FR -196 rate=44100 channels=2 fmt=s16 samplesize=2 stride=4 latency=4410 (0.100s) -197 connecting playback stream; target_id=4294967295 -198 stream state changed unconnected -> connecting -199 stream param change: id=2 -200 stream properties: -201 media.type = "Audio" -202 ... -203 now=0 rate=0/0 ticks=0 delay=0 queued=0 -204 remote 0 is named "pipewire-0" -205 core done -206 stream state changed connecting -> paused -207 stream param change: id=2 -208 ... -209 stream param change: id=15 -210 stream param change: id=15 -211 now=13465394419270 rate=1/48000 ticks=35840 delay=512 queued=0 -212 now=13466525228363 rate=1/48000 ticks=90112 delay=512 queued=0 -213 ... -214 stream drained -215 stream state changed streaming -> paused +191 ```bash +192 opened file "beers.wav" format 00010002 channels:2 rate:44100 +193 using default channel map: FL,FR +194 rate=44100 channels=2 fmt=s16 samplesize=2 stride=4 latency=4410 (0.100s) +195 connecting playback stream; target_id=4294967295 +196 stream state changed unconnected -> connecting +197 stream param change: id=2 +198 stream properties: +199 media.type = "Audio" +200 ... +201 now=0 rate=0/0 ticks=0 delay=0 queued=0 +202 remote 0 is named "pipewire-0" +203 core done +204 stream state changed connecting -> paused +205 stream param change: id=2 +206 ... +207 stream param change: id=15 +208 stream param change: id=15 +209 now=13465394419270 rate=1/48000 ticks=35840 delay=512 queued=0 +210 now=13466525228363 rate=1/48000 ticks=90112 delay=512 queued=0 +211 ... +212 stream drained +213 stream state changed streaming -> paused +214 stream param change: id=4 +215 stream state changed paused -> unconnected 216 stream param change: id=4 -217 stream state changed paused -> unconnected -218 stream param change: id=4 -219 ``` -220 """ -221 -222 if status: -223 self._pipewire_configs["--verbose"] = " " -224 else: -225 pass +217 ``` +218 """ +219 +220 if status: +221 self._pipewire_configs["--verbose"] = " " +222 else: +223 passReturns:
#!/bin/bash # For example -pw-cat --playback beers.wav --verbose +pw-cat --playback beers.wav --verbose
that will generate an output like this:
-opened file "beers.wav" format 00010002 channels:2 rate:44100 -using default channel map: FL,FR -rate=44100 channels=2 fmt=s16 samplesize=2 stride=4 latency=4410 (0.100s) -connecting playback stream; target_id=4294967295 -stream state changed unconnected -> connecting -stream param change: id=2 -stream properties: - media.type = "Audio" - ... -now=0 rate=0/0 ticks=0 delay=0 queued=0 -remote 0 is named "pipewire-0" -core done -stream state changed connecting -> paused -stream param change: id=2 +
opened file "beers.wav" format 00010002 channels:2 rate:44100 +using default channel map: FL,FR +rate=44100 channels=2 fmt=s16 samplesize=2 stride=4 latency=4410 (0.100s) +connecting playback stream; target_id=4294967295 +stream state changed unconnected -> connecting +stream param change: id=2 +stream properties: + media.type = "Audio" + ... +now=0 rate=0/0 ticks=0 delay=0 queued=0 +remote 0 is named "pipewire-0" +core done +stream state changed connecting -> paused +stream param change: id=2 ... -stream param change: id=15 -stream param change: id=15 -now=13465394419270 rate=1/48000 ticks=35840 delay=512 queued=0 -now=13466525228363 rate=1/48000 ticks=90112 delay=512 queued=0 +stream param change: id=15 +stream param change: id=15 +now=13465394419270 rate=1/48000 ticks=35840 delay=512 queued=0 +now=13466525228363 rate=1/48000 ticks=90112 delay=512 queued=0 ... -stream drained -stream state changed streaming -> paused -stream param change: id=4 -stream state changed paused -> unconnected -stream param change: id=4 +stream drained +stream state changed streaming -> paused +stream param change: id=4 +stream state changed paused -> unconnected +stream param change: id=4
227 def get_config(self): -228 """Return config dictionary with default or setup variables, remember that -229 this object changes only on python-side. Is not updated on real time, -230 For real-time, please create and destroy the class. -231 -232 Args: -233 Nothing -234 -235 Returns: -236 - _pipewire_configs (`dict`) : dictionary with config values +@@ -1662,176 +1660,176 @@225 def get_config(self): +226 """Return config dictionary with default or setup variables, remember that +227 this object changes only on python-side. Is not updated on real time, +228 For real-time, please create and destroy the class. +229 +230 Args: +231 Nothing +232 +233 Returns: +234 - _pipewire_configs (`dict`) : dictionary with config values +235 +236 """ 237 -238 """ -239 -240 return self._pipewire_configs +238 return self._pipewire_configsReturns:
242 def set_config( -243 self, -244 # configs -245 media_type=None, -246 media_category=None, -247 media_role=None, -248 target=None, -249 latency=None, -250 rate=None, -251 channels=None, -252 channels_map=None, -253 _format=None, -254 volume=None, -255 quality=None, -256 # Debug -257 verbose=False, -258 ): -259 """Method that get args as variables and set them -260 to the `json` parameter of the class `_pipewire_configs`, -261 then you can use in other method, such as `playback(...)` or -262 `record(...)`. This method verifies values to avoid wrong -263 settings. -264 -265 Args: -266 media_type : Set media type -267 media_category : Set media category -268 media_role : Set media role -269 target : Set node target -270 latency : Set node latency *example=100ms -271 rate : Set sample rate [8000,11025,16000,22050,44100,48000,88200,96000,176400,192000,352800,384000] -272 channels : Numbers of channels [1,2] -273 channels_map : ["stereo", "surround-51", "FL,FR", ...] -274 _format : ["u8", "s8", "s16", "s32", "f32", "f64"] -275 volume : Stream volume [0.000, 1.000] -276 quality : Resampler quality [0, 15] -277 verbose (`bool`): True enable debug logs. *default=False -278 -279 Returns: -280 - Nothing -281 -282 More: -283 Check all links listed at the beginning of this page -284 """ # 1 - media_type -285 if media_type: -286 self._pipewire_configs["--media-type"] = str(media_type) -287 elif media_type is None: -288 pass -289 else: -290 raise ValueError( -291 f"{MESSAGES_ERROR['ValueError']}[media_type='{media_type}'] EMPTY VALUE" -292 ) -293 # 2 - media_category -294 if media_category: -295 self._pipewire_configs["--media-category"] = str(media_category) -296 elif media_category is None: -297 pass -298 else: -299 raise ValueError( -300 f"{MESSAGES_ERROR['ValueError']}[media_category='{media_category}'] EMPTY VALUE" -301 ) -302 # 3 - media_role -303 if media_role: -304 self._pipewire_configs["--media-role"] = str(media_role) -305 elif media_role is None: -306 pass -307 else: -308 raise ValueError( -309 f"{MESSAGES_ERROR['ValueError']}[media_role='{media_role}'] EMPTY VALUE" -310 ) -311 # 4 - target -312 if target: -313 self._pipewire_configs["--target"] = str(target) -314 elif target is None: -315 pass -316 else: -317 raise ValueError(f"{MESSAGES_ERROR['ValueError']}[target='{target}'] EMPTY VALUE") -318 # 5 - latency -319 if latency: -320 if any(chr.isdigit() for chr in latency): # Contain numbers -321 self._pipewire_configs["--latency"] = str(latency) -322 else: -323 raise ValueError( -324 f"{MESSAGES_ERROR['ValueError']}[latency='{latency}'] NO NUMBER IN VARIABLE" -325 ) -326 elif latency is None: -327 pass -328 else: -329 raise ValueError(f"{MESSAGES_ERROR['ValueError']}[latency='{latency}'] EMPTY VALUE") -330 # 6 - rate -331 if rate: -332 if rate in RECOMMENDED_RATES: -333 self._pipewire_configs["--rate"] = str(rate) -334 else: -335 raise ValueError( -336 f"{MESSAGES_ERROR['ValueError']}[rate='{rate}']\ -337 VALUE NOT IN RECOMMENDED LIST \n{RECOMMENDED_RATES}" -338 ) -339 elif rate is None: -340 pass -341 else: -342 raise ValueError(f"{MESSAGES_ERROR['ValueError']}[rate='{rate}'] EMPTY VALUE") -343 # 7 - channels -344 if channels: -345 if channels in [1, 2]: # values -346 self._pipewire_configs["--channels"] = str(channels) -347 else: -348 raise ValueError( -349 f"{MESSAGES_ERROR['ValueError']}[channels='{channels}']\ -350 WRONG VALUE\n ONLY 1 or 2." -351 ) -352 elif channels is None: -353 pass -354 else: -355 raise ValueError(f"{MESSAGES_ERROR['ValueError']}[channels='{channels}'] EMPTY VALUE") -356 # 8 - channels-map -357 if channels_map: -358 self._pipewire_configs["--channels-map"] = str(channels_map) -359 elif channels_map is None: -360 pass -361 else: -362 raise ValueError( -363 f"{MESSAGES_ERROR['ValueError']}[channels_map='{channels_map}'] EMPTY VALUE" -364 ) -365 # 9 - format -366 if _format: -367 if _format in RECOMMENDED_FORMATS: -368 self._pipewire_configs["--format"] = str(_format) -369 else: -370 raise ValueError( -371 f"{MESSAGES_ERROR['ValueError']}[_format='{_format}']\ -372 VALUE NOT IN RECOMMENDED LIST \n{RECOMMENDED_FORMATS}" -373 ) -374 elif _format is None: -375 pass -376 else: -377 raise ValueError(f"{MESSAGES_ERROR['ValueError']}[_format='{_format}'] EMPTY VALUE") -378 # 10 - volume -379 if volume: -380 if 0.0 <= volume <= 1.0: -381 self._pipewire_configs["--volume"] = str(volume) -382 else: -383 raise ValueError( -384 f"{MESSAGES_ERROR['ValueError']}[volume='{volume}']\ -385 OUT OF RANGE \n [0.000, 1.000]" -386 ) -387 elif volume is None: -388 pass -389 else: -390 raise ValueError(f"{MESSAGES_ERROR['ValueError']}[volume='{volume}'] EMPTY VALUE") -391 # 11 - quality -392 if quality: -393 if 0 <= quality <= 15: -394 self._pipewire_configs["--quality"] = str(quality) -395 else: -396 raise ValueError( -397 f"{MESSAGES_ERROR['ValueError']}[quality='{quality}'] OUT OF RANGE \n [0, 15]" -398 ) -399 elif quality is None: -400 pass -401 else: -402 raise ValueError(f"{MESSAGES_ERROR['ValueError']}[volume='{volume}'] EMPTY VALUE") -403 -404 # 12 - verbose cli -405 if verbose: # True -406 self._pipewire_configs["--verbose"] = " " -407 else: -408 pass -409 -410 if verbose: -411 print(self._pipewire_configs) +@@ -1886,33 +1884,33 @@240 def set_config( +241 self, +242 # configs +243 media_type=None, +244 media_category=None, +245 media_role=None, +246 target=None, +247 latency=None, +248 rate=None, +249 channels=None, +250 channels_map=None, +251 _format=None, +252 volume=None, +253 quality=None, +254 # Debug +255 verbose=False, +256 ): +257 """Method that get args as variables and set them +258 to the `json` parameter of the class `_pipewire_configs`, +259 then you can use in other method, such as `playback(...)` or +260 `record(...)`. This method verifies values to avoid wrong +261 settings. +262 +263 Args: +264 media_type : Set media type +265 media_category : Set media category +266 media_role : Set media role +267 target : Set node target +268 latency : Set node latency *example=100ms +269 rate : Set sample rate [8000,11025,16000,22050,44100,48000,88200,96000,176400,192000,352800,384000] +270 channels : Numbers of channels [1,2] +271 channels_map : ["stereo", "surround-51", "FL,FR", ...] +272 _format : ["u8", "s8", "s16", "s32", "f32", "f64"] +273 volume : Stream volume [0.000, 1.000] +274 quality : Resampler quality [0, 15] +275 verbose (`bool`): True enable debug logs. *default=False +276 +277 Returns: +278 - Nothing +279 +280 More: +281 Check all links listed at the beginning of this page +282 """ # 1 - media_type +283 if media_type: +284 self._pipewire_configs["--media-type"] = str(media_type) +285 elif media_type is None: +286 pass +287 else: +288 raise ValueError( +289 f"{MESSAGES_ERROR['ValueError']}[media_type='{media_type}'] EMPTY VALUE" +290 ) +291 # 2 - media_category +292 if media_category: +293 self._pipewire_configs["--media-category"] = str(media_category) +294 elif media_category is None: +295 pass +296 else: +297 raise ValueError( +298 f"{MESSAGES_ERROR['ValueError']}[media_category='{media_category}'] EMPTY VALUE" +299 ) +300 # 3 - media_role +301 if media_role: +302 self._pipewire_configs["--media-role"] = str(media_role) +303 elif media_role is None: +304 pass +305 else: +306 raise ValueError( +307 f"{MESSAGES_ERROR['ValueError']}[media_role='{media_role}'] EMPTY VALUE" +308 ) +309 # 4 - target +310 if target: +311 self._pipewire_configs["--target"] = str(target) +312 elif target is None: +313 pass +314 else: +315 raise ValueError(f"{MESSAGES_ERROR['ValueError']}[target='{target}'] EMPTY VALUE") +316 # 5 - latency +317 if latency: +318 if any(chr.isdigit() for chr in latency): # Contain numbers +319 self._pipewire_configs["--latency"] = str(latency) +320 else: +321 raise ValueError( +322 f"{MESSAGES_ERROR['ValueError']}[latency='{latency}'] NO NUMBER IN VARIABLE" +323 ) +324 elif latency is None: +325 pass +326 else: +327 raise ValueError(f"{MESSAGES_ERROR['ValueError']}[latency='{latency}'] EMPTY VALUE") +328 # 6 - rate +329 if rate: +330 if rate in RECOMMENDED_RATES: +331 self._pipewire_configs["--rate"] = str(rate) +332 else: +333 raise ValueError( +334 f"{MESSAGES_ERROR['ValueError']}[rate='{rate}']\ +335 VALUE NOT IN RECOMMENDED LIST \n{RECOMMENDED_RATES}" +336 ) +337 elif rate is None: +338 pass +339 else: +340 raise ValueError(f"{MESSAGES_ERROR['ValueError']}[rate='{rate}'] EMPTY VALUE") +341 # 7 - channels +342 if channels: +343 if channels in [1, 2]: # values +344 self._pipewire_configs["--channels"] = str(channels) +345 else: +346 raise ValueError( +347 f"{MESSAGES_ERROR['ValueError']}[channels='{channels}']\ +348 WRONG VALUE\n ONLY 1 or 2." +349 ) +350 elif channels is None: +351 pass +352 else: +353 raise ValueError(f"{MESSAGES_ERROR['ValueError']}[channels='{channels}'] EMPTY VALUE") +354 # 8 - channels-map +355 if channels_map: +356 self._pipewire_configs["--channels-map"] = str(channels_map) +357 elif channels_map is None: +358 pass +359 else: +360 raise ValueError( +361 f"{MESSAGES_ERROR['ValueError']}[channels_map='{channels_map}'] EMPTY VALUE" +362 ) +363 # 9 - format +364 if _format: +365 if _format in RECOMMENDED_FORMATS: +366 self._pipewire_configs["--format"] = str(_format) +367 else: +368 raise ValueError( +369 f"{MESSAGES_ERROR['ValueError']}[_format='{_format}']\ +370 VALUE NOT IN RECOMMENDED LIST \n{RECOMMENDED_FORMATS}" +371 ) +372 elif _format is None: +373 pass +374 else: +375 raise ValueError(f"{MESSAGES_ERROR['ValueError']}[_format='{_format}'] EMPTY VALUE") +376 # 10 - volume +377 if volume: +378 if 0.0 <= volume <= 1.0: +379 self._pipewire_configs["--volume"] = str(volume) +380 else: +381 raise ValueError( +382 f"{MESSAGES_ERROR['ValueError']}[volume='{volume}']\ +383 OUT OF RANGE \n [0.000, 1.000]" +384 ) +385 elif volume is None: +386 pass +387 else: +388 raise ValueError(f"{MESSAGES_ERROR['ValueError']}[volume='{volume}'] EMPTY VALUE") +389 # 11 - quality +390 if quality: +391 if 0 <= quality <= 15: +392 self._pipewire_configs["--quality"] = str(quality) +393 else: +394 raise ValueError( +395 f"{MESSAGES_ERROR['ValueError']}[quality='{quality}'] OUT OF RANGE \n [0, 15]" +396 ) +397 elif quality is None: +398 pass +399 else: +400 raise ValueError(f"{MESSAGES_ERROR['ValueError']}[volume='{volume}'] EMPTY VALUE") +401 +402 # 12 - verbose cli +403 if verbose: # True +404 self._pipewire_configs["--verbose"] = " " +405 else: +406 pass +407 +408 if verbose: +409 print(self._pipewire_configs)More:
413 def load_list_targets( -414 self, -415 mode, # playback or record -416 # Debug, -417 verbose: bool = False, -418 ): -419 """Returns a list of targets to playback or record. Then you can use -420 the output to select a device to playback or record. -421 """ -422 -423 if mode == "playback": -424 mycommand = ["pw-cat", "--playback", "--list-targets"] -425 stdout, _ = _execute_shell_command(command=mycommand, timeout=-1, verbose=verbose) -426 self._pipewire_list_targets["list_playback"] = _generate_dict_list_targets( -427 longstring=stdout.decode(), verbose=verbose -428 ) -429 elif mode == "record": -430 mycommand = ["pw-cat", "--record", "--list-targets"] -431 stdout, _ = _execute_shell_command(command=mycommand, timeout=-1, verbose=verbose) -432 self._pipewire_list_targets["list_record"] = _generate_dict_list_targets( -433 longstring=stdout.decode(), verbose=verbose -434 ) -435 else: -436 raise AttributeError(MESSAGES_ERROR["ValueError"]) -437 -438 if verbose: -439 print(f"[mycommand]{mycommand}") +@@ -1933,57 +1931,57 @@411 def load_list_targets( +412 self, +413 mode, # playback or record +414 # Debug, +415 verbose: bool = False, +416 ): +417 """Returns a list of targets to playback or record. Then you can use +418 the output to select a device to playback or record. +419 """ +420 +421 if mode == "playback": +422 mycommand = ["pw-cat", "--playback", "--list-targets"] +423 stdout, _ = _execute_shell_command(command=mycommand, timeout=-1, verbose=verbose) +424 self._pipewire_list_targets["list_playback"] = _generate_dict_list_targets( +425 longstring=stdout.decode(), verbose=verbose +426 ) +427 elif mode == "record": +428 mycommand = ["pw-cat", "--record", "--list-targets"] +429 stdout, _ = _execute_shell_command(command=mycommand, timeout=-1, verbose=verbose) +430 self._pipewire_list_targets["list_record"] = _generate_dict_list_targets( +431 longstring=stdout.decode(), verbose=verbose +432 ) +433 else: +434 raise AttributeError(MESSAGES_ERROR["ValueError"]) +435 +436 if verbose: +437 print(f"[mycommand]{mycommand}")More:
441 def get_list_targets( -442 self, -443 # Debug, -444 verbose: bool = False, -445 ): -446 """Returns a list of targets to playback or record. Then you can use -447 the output to select a device to playback or record. -448 -449 Returns: -450 - `_pipewire_list_targets` -451 -452 Examples: -453 ```python -454 >>> Controller().get_list_targets() -455 { -456 "list_playback": { -457 "86": { -458 "description": "Starship/Matisse HD Audio Controller Pro", -459 "prior": "936" -460 }, -461 "_list_nodes": [ -462 "86" -463 ], -464 "_node_default": [ -465 "86" -466 ], -467 "_alsa_node": [ -468 "alsa_output.pci-0000_0a_00.4.pro-output-0" -469 ] -470 }, -471 "list_record": { -472 "86": { -473 "description": "Starship/Matisse HD Audio Controller Pro", -474 "prior": "936" -475 }, -476 "_list_nodes": [ -477 "86" -478 ], -479 "_node_default": [ -480 "86" -481 ], -482 "_alsa_node": [ -483 "alsa_output.pci-0000_0a_00.4.pro-output-0" -484 ] -485 } -486 } -487 ``` -488 """ -489 if verbose: -490 print(self._pipewire_list_targets) -491 return self._pipewire_list_targets +@@ -2051,49 +2049,49 @@439 def get_list_targets( +440 self, +441 # Debug, +442 verbose: bool = False, +443 ): +444 """Returns a list of targets to playback or record. Then you can use +445 the output to select a device to playback or record. +446 +447 Returns: +448 - `_pipewire_list_targets` +449 +450 Examples: +451 ```python +452 >>> Controller().get_list_targets() +453 { +454 "list_playback": { +455 "86": { +456 "description": "Starship/Matisse HD Audio Controller Pro", +457 "prior": "936" +458 }, +459 "_list_nodes": [ +460 "86" +461 ], +462 "_node_default": [ +463 "86" +464 ], +465 "_alsa_node": [ +466 "alsa_output.pci-0000_0a_00.4.pro-output-0" +467 ] +468 }, +469 "list_record": { +470 "86": { +471 "description": "Starship/Matisse HD Audio Controller Pro", +472 "prior": "936" +473 }, +474 "_list_nodes": [ +475 "86" +476 ], +477 "_node_default": [ +478 "86" +479 ], +480 "_alsa_node": [ +481 "alsa_output.pci-0000_0a_00.4.pro-output-0" +482 ] +483 } +484 } +485 ``` +486 """ +487 if verbose: +488 print(self._pipewire_list_targets) +489 return self._pipewire_list_targetsReturns:
493 def get_list_interfaces( -494 self, -495 filtered_by_type: str = True, -496 type_interfaces: str = "Client", -497 # Debug -498 verbose: bool = False, -499 ): -500 """Returns a list of applications currently using pipewire on Client. -501 An example of pw-cli usage is the code below: -502 -503 ```bash -504 #!/bin/bash -505 pw-cli ls Client -506 ``` -507 Args: -508 filtered_by_type : If False, returns all. If not, returns a fitered dict -509 type_interfaces : Set type of Interface ["Client","Link","Node","Factory","Module","Metadata","Endpoint","Session","Endpoint Stream","EndpointLink","Port"] -510 -511 Returns: -512 - dict_interfaces_filtered: dictionary with list of interfaces matching conditions -513 -514 Examples: -515 ```python -516 >>> Controller().get_list_interfaces() -517 -518 ``` -519 """ -520 mycommand = ["pw-cli", "info", "all"] -521 -522 # if verbose: -523 # print(f"[mycommand]{mycommand}") -524 -525 stdout, _ = _execute_shell_command(command=mycommand, timeout=-1, verbose=verbose) -526 dict_interfaces = _generate_dict_interfaces(longstring=stdout.decode(), verbose=verbose) -527 -528 if filtered_by_type: -529 dict_interfaces_filtered = _filter_by_type( -530 dict_interfaces=dict_interfaces, type_interfaces=type_interfaces -531 ) -532 else: -533 dict_interfaces_filtered = dict_interfaces -534 -535 return dict_interfaces_filtered +@@ -2102,7 +2100,7 @@491 def get_list_interfaces( +492 self, +493 filtered_by_type: str = True, +494 type_interfaces: str = "Client", +495 # Debug +496 verbose: bool = False, +497 ): +498 """Returns a list of applications currently using pipewire on Client. +499 An example of pw-cli usage is the code below: +500 +501 ```bash +502 #!/bin/bash +503 pw-cli ls Client +504 ``` +505 Args: +506 filtered_by_type : If False, returns all. If not, returns a fitered dict +507 type_interfaces : Set type of Interface ["Client","Link","Node","Factory","Module","Metadata","Endpoint","Session","Endpoint Stream","EndpointLink","Port"] +508 +509 Returns: +510 - dict_interfaces_filtered: dictionary with list of interfaces matching conditions +511 +512 Examples: +513 ```python +514 >>> Controller().get_list_interfaces() +515 +516 ``` +517 """ +518 mycommand = ["pw-cli", "info", "all"] +519 +520 # if verbose: +521 # print(f"[mycommand]{mycommand}") +522 +523 stdout, _ = _execute_shell_command(command=mycommand, timeout=-1, verbose=verbose) +524 dict_interfaces = _generate_dict_interfaces(longstring=stdout.decode(), verbose=verbose) +525 +526 if filtered_by_type: +527 dict_interfaces_filtered = _filter_by_type( +528 dict_interfaces=dict_interfaces, type_interfaces=type_interfaces +529 ) +530 else: +531 dict_interfaces_filtered = dict_interfaces +532 +533 return dict_interfaces_filteredReturns:
@@ -2142,40 +2140,40 @@#!/bin/bash -pw-cli ls Client +pw-cli ls Client
Returns:
537 def playback( -538 self, -539 audio_filename: str = "myplayback.wav", -540 # Debug -541 verbose: bool = False, -542 ): -543 """Execute pipewire command to play an audio file with the following -544 command: -545 -546 ```bash -547 #!/bin/bash -548 pw-cat --playback {audio_filename} + {configs} -549 # configs are a concatenated params -550 ``` -551 -552 Args: -553 audio_filename (`str`): Path of the file to be played. *default='myplayback.wav' -554 verbose (`bool`): True enable debug logs. *default=False -555 -556 Returns: -557 - stdout (`str`): Shell response to the command in stdout format -558 - stderr (`str`): Shell response response to the command in stderr format -559 """ -560 warnings.warn("The name of the function may change on future releases", DeprecationWarning) -561 -562 mycommand = ["pw-cat", "--playback", audio_filename] + _generate_command_by_dict( -563 mydict=self._pipewire_configs, verbose=verbose -564 ) -565 -566 if verbose: -567 print(f"[mycommand]{mycommand}") -568 -569 stdout, stderr = _execute_shell_command(command=mycommand, timeout=-1, verbose=verbose) -570 return stdout, stderr +@@ -2184,7 +2182,7 @@535 def playback( +536 self, +537 audio_filename: str = "myplayback.wav", +538 # Debug +539 verbose: bool = False, +540 ): +541 """Execute pipewire command to play an audio file with the following +542 command: +543 +544 ```bash +545 #!/bin/bash +546 pw-cat --playback {audio_filename} + {configs} +547 # configs are a concatenated params +548 ``` +549 +550 Args: +551 audio_filename (`str`): Path of the file to be played. *default='myplayback.wav' +552 verbose (`bool`): True enable debug logs. *default=False +553 +554 Returns: +555 - stdout (`str`): Shell response to the command in stdout format +556 - stderr (`str`): Shell response response to the command in stderr format +557 """ +558 warnings.warn("The name of the function may change on future releases", DeprecationWarning) +559 +560 mycommand = ["pw-cat", "--playback", audio_filename] + _generate_command_by_dict( +561 mydict=self._pipewire_configs, verbose=verbose +562 ) +563 +564 if verbose: +565 print(f"[mycommand]{mycommand}") +566 +567 stdout, stderr = _execute_shell_command(command=mycommand, timeout=-1, verbose=verbose) +568 return stdout, stderrReturns:
@@ -2219,43 +2217,43 @@#!/bin/bash -pw-cat --playback {audio_filename} + {configs} +pw-cat --playback {audio_filename} + {configs} # configs are a concatenated params
Returns:
572 def record( -573 self, -574 audio_filename: str = "myplayback.wav", -575 timeout_seconds=5, -576 # Debug -577 verbose: bool = False, -578 ): -579 """Execute pipewire command to record an audio file, with a timeout of 5 -580 seconds with the following code and exiting the shell when tiomeout is over. -581 -582 ```bash -583 #!/bin/bash -584 pw-cat --record {audio_filename} -585 # timeout is managed by python3 (when signal CTRL+C is sended) -586 ``` -587 -588 Args: -589 audio_filename (`str`): Path of the file to be played. *default='myplayback.wav' -590 verbose (`bool`): True enable debug logs. *default=False -591 -592 Returns: -593 - stdout (`str`): Shell response to the command in stdout format -594 - stderr (`str`): Shell response response to the command in stderr format -595 """ -596 warnings.warn("The name of the function may change on future releases", DeprecationWarning) -597 -598 mycommand = ["pw-cat", "--record", audio_filename] + _generate_command_by_dict( -599 mydict=self._pipewire_configs, verbose=verbose -600 ) -601 -602 if verbose: -603 print(f"[mycommand]{mycommand}") -604 -605 stdout, stderr = _execute_shell_command( -606 command=mycommand, timeout=timeout_seconds, verbose=verbose -607 ) -608 return stdout, stderr +@@ -2264,7 +2262,7 @@570 def record( +571 self, +572 audio_filename: str = "myplayback.wav", +573 timeout_seconds=5, +574 # Debug +575 verbose: bool = False, +576 ): +577 """Execute pipewire command to record an audio file, with a timeout of 5 +578 seconds with the following code and exiting the shell when tiomeout is over. +579 +580 ```bash +581 #!/bin/bash +582 pw-cat --record {audio_filename} +583 # timeout is managed by python3 (when signal CTRL+C is sended) +584 ``` +585 +586 Args: +587 audio_filename (`str`): Path of the file to be played. *default='myplayback.wav' +588 verbose (`bool`): True enable debug logs. *default=False +589 +590 Returns: +591 - stdout (`str`): Shell response to the command in stdout format +592 - stderr (`str`): Shell response response to the command in stderr format +593 """ +594 warnings.warn("The name of the function may change on future releases", DeprecationWarning) +595 +596 mycommand = ["pw-cat", "--record", audio_filename] + _generate_command_by_dict( +597 mydict=self._pipewire_configs, verbose=verbose +598 ) +599 +600 if verbose: +601 print(f"[mycommand]{mycommand}") +602 +603 stdout, stderr = _execute_shell_command( +604 command=mycommand, timeout=timeout_seconds, verbose=verbose +605 ) +606 return stdout, stderrReturns:
@@ -2299,33 +2297,33 @@#!/bin/bash -pw-cat --record {audio_filename} +pw-cat --record {audio_filename} # timeout is managed by python3 (when signal CTRL+C is sended)
Returns:
610 def clear_devices( -611 self, -612 mode: str = "all", # ['all','playback','record'] -613 # Debug -614 verbose: bool = False, -615 ): -616 """Function to stop process running under pipewire executed by -617 python controller and with default process name of `pw-cat`, `pw-play` or `pw-record`. -618 -619 Args: -620 mode (`str`) : string to kill process under `pw-cat`, `pw-play` or `pw-record`. -621 -622 Returns: -623 - stdoutdict (`dict`) : a dictionary with keys of `mode`. -624 -625 Example with pipewire: -626 pw-cat process -627 """ +608 def clear_devices( +609 self, +610 mode: str = "all", # ['all','playback','record'] +611 # Debug +612 verbose: bool = False, +613 ): +614 """Function to stop process running under pipewire executed by +615 python controller and with default process name of `pw-cat`, `pw-play` or `pw-record`. +616 +617 Args: +618 mode (`str`) : string to kill process under `pw-cat`, `pw-play` or `pw-record`. +619 +620 Returns: +621 - stdoutdict (`dict`) : a dictionary with keys of `mode`. +622 +623 Example with pipewire: +624 pw-cat process +625 """ +626 +627 mycommand = self._kill_pipewire[mode] 628 -629 mycommand = self._kill_pipewire[mode] -630 -631 if verbose: -632 print(f"[mycommands]{mycommand}") +629 if verbose: +630 print(f"[mycommands]{mycommand}") +631 +632 stdout, _ = _execute_shell_command(command=mycommand, verbose=verbose) 633 -634 stdout, _ = _execute_shell_command(command=mycommand, verbose=verbose) -635 -636 return {mode: stdout} +634 return {mode: stdout}