#!/usr/bin/env python3 import subprocess import sys CARD_INDEX = 2 # Можно изменить при необходимости def _get_mixer_name(card_index, mixer_type=None): """ Вспомогательная функция: находит микшер указанного типа или первый из списка. Args: card_index: Индекс звуковой карты mixer_type: Тип микшера ('Playback' или 'Capture'). Если None, вернет первый найденный. """ try: result = subprocess.run( ['amixer', '-c', str(card_index), 'scontrols'], capture_output=True, text=True, check=True ) # Если указан конкретный тип микшера, ищем его if mixer_type in ['Playback', 'Capture']: for line in result.stdout.splitlines(): name = line.strip().replace("Simple mixer control '", "").replace("',0", "") if name == mixer_type: return name print(f"Mixer type '{mixer_type}' not found for card {card_index}.", file=sys.stderr) return None # Если тип не указан, возвращаем первый подходящий for line in result.stdout.splitlines(): name = line.strip().replace("Simple mixer control '", "").replace("',0", "") if name in ['Playback', 'Capture']: return name print(f"No valid mixer (Playback/Capture) found for card {card_index}.", file=sys.stderr) return None except subprocess.CalledProcessError as e: print(f"Error listing mixers: {e}", file=sys.stderr) return None def get_volume(card_index, mixer_type=None): """ Получить текущую громкость для устройства (card_index). Args: card_index: Индекс звуковой карты mixer_type: Тип микшера ('Playback' или 'Capture'). Если None, используется первый найденный. Возвращает: int (0-100) или None при ошибке. """ mixer_name = _get_mixer_name(card_index, mixer_type) if not mixer_name: print(f"No valid mixer found for card {card_index} with type {mixer_type}.", file=sys.stderr) return None try: result = subprocess.run( ['amixer', '-c', str(card_index), '-M', 'sget', mixer_name], capture_output=True, text=True, check=True ) for line in result.stdout.splitlines(): if '[' in line and ']' in line and '%' in line: percentage = line.split('[')[1].split(']')[0].strip('%') return int(percentage) return None except subprocess.CalledProcessError as e: print(f"Failed to get volume: {e}", file=sys.stderr) return None except ValueError: print("Failed to parse volume percentage.", file=sys.stderr) return None def set_volume(card_index, volume, mixer_type=None): """ Установить громкость для устройства (card_index). Args: card_index: Индекс звуковой карты volume: Громкость (int от 0 до 100) mixer_type: Тип микшера ('Playback' или 'Capture'). Если None, используется первый найденный. Возвращает: True при успехе, False при ошибке. """ if not (0 <= volume <= 100): print("Volume must be between 0 and 100.", file=sys.stderr) return False mixer_name = _get_mixer_name(card_index, mixer_type) if not mixer_name: print(f"No valid mixer found for card {card_index} with type {mixer_type}.", file=sys.stderr) return False try: subprocess.run( ['amixer', '-c', str(card_index), '-M', 'sset', mixer_name, f'{volume}%'], check=True ) print(f"Volume set to {volume}% for card {card_index}, mixer '{mixer_name}'") return True except subprocess.CalledProcessError as e: print(f"Failed to set volume: {e}", file=sys.stderr) return False # === Пример использования (раскомментировать для теста) === # if __name__ == "__main__": # print("Current volume:", get_volume(CARD_INDEX)) # set_volume(CARD_INDEX, 75) # print("New volume:", get_volume(CARD_INDEX))