#python #list #search
#python #Список #Поиск
Вопрос:
Не уверен, как правильно сформулировать заголовок, но у меня есть этот список:
Sink Input #1535
Driver: protocol-native.c
Owner Module: 10
Client: 21932
Sink: 0
Sample Specification: s16le 2ch 44100Hz
Channel Map: front-left,front-right
Format: pcm, format.sample_format = ""s16le"" format.rate = "44100" format.channels = "2" format.channel_map = ""front-left,front-right""
Corked: no
Mute: no
Volume: front-left: 32768 / 50% / -18.06 dB, front-right: 32768 / 50% / -18.06 dB
balance 0.00
Buffer Latency: 0 usec
Sink Latency: 23084 usec
Resample method: n/a
Properties:
media.name = "Simple DirectMedia Layer"
application.name = "ffplay"
с целой кучей других вещей, следующих.
Сначала мне нужно сопоставить на Input Sink#
и записать следующие цифры до конца строки. Затем я должен выполнить поиск по application.name =
и записать название программы, которое следует в кавычках. Затем поиск должен повториться для нескольких приемников и названий программ. Позже я планирую вернуть все входные номера приемников для данного имени приложения.
Текущий метод использует грубую силу и высокие системные ресурсы. Есть ли лучший метод, чем этот:
def sink_list(prog,func):
''' Return list of Firefox or ffplay input sinks indices
'''
indices = []
result = os.popen('pactl list short sink-inputs')
.read().strip().splitlines()
# TODO: We could be doing one os.popen and grabbing all sinks at once
if len(result) == 0:
print('sink_list() found no input sinks at all.'
' Called by: ' func)
return indices
for line in result:
sink = line.split('t')[0]
app = os.popen('pactl list sink-inputs | grep "Sink Input #'
sink '" -A20 | grep application.name').read()
# print("Searching for:",prog," in:",app," using input sink#:",sink)
if prog in app:
indices.append(sink)
# print('indices',prog,':',indices)
if len(indices) == 0:
print("sink_list() found no input sink for: '" prog
"' called by: " func)
return indices
# print("Found Input Sinks:", indices)
return indices
Отвечать на комментарии
Был запрошен ввод:
''' Get old PID's and Input Sinks before ffplay '''
old_pid = pid_list( "ffplay", "play_start()" )
old_sink = sink_list( "ffplay", "play_start()" )
self.have_ffplay_input_sink = False # Each ffplay can have diff #
# Launch ffplay in the background. CANNOT query result, it stops bkgrnd
os.popen('ffplay -autoexit ' '"' self.current_song_path '"'
' -nodisp 2>' TMP_CURR_SONG ' amp;')
''' Get New PID's and Input Sinks for ffplay '''
# Give time for `ffplay` to create pulseaudio sink.
root.after(100) # THIS IS UGLY, root.after is machine dependent!!!
if not self.top2_is_active: return # Play window closed?
new_pid = pid_list("ffplay", "play_start()")
new_sink = sink_list("ffplay", "play_start()")
self.top2_ffplay_pid = list_diff(new_pid, old_pid, "play_start()")
self.top2_ffplay_sink = list_diff(new_sink, old_sink, "play_start()")
Комментарии:
1. Взгляните на
in
оператор python. Он реализует ту частьgrep
, которая вам нужна.2. @MadPhysicist Спасибо за этот совет. Я использую
grep
повсюду в моей последней программе на Python, и это моя вторая программа. Я программирую на bash всего четыре года.3. Python, как правило, более универсален, чем bash. Вам понравится, как только вы к нему привыкнете
4. Можете ли вы показать пример вывода для нескольких приемников?
5. @MadPhysicist Если вам интересно, сегодня я ответил на свой собственный вопрос.
Ответ №1:
Я отвечу на свой собственный вопрос на случай, если это поможет другим.
Это функция, которую я написал, которая возвращает исходные требования плюс текущий объем:
def sink_master():
all_lines = []
all_lines = os.popen('pactl list sink-inputs').read().splitlines()
all_sinks = []
in_sink = False
in_volume = False
for line in all_lines:
if in_sink is False and "Sink Input #" in line:
this_sink = line.split('#')[1]
in_sink = True
continue
if in_sink is True and in_volume is False and "Volume:" in line:
this_volume = line.split('/')[1]
this_volume = this_volume.replace(' ','')
this_volume = this_volume.replace('%','')
in_volume = True
continue
if in_sink is True and in_volume is True and "tion.name =" in line:
this_name = line.split('=')[1]
this_name = this_name.replace(' ','')
this_name = this_name.replace('"','')
in_sink = False
in_volume = False
all_sinks.append(tuple((this_sink,this_volume,this_name)))
continue
print(all_sinks)
return all_sinks
Когда вы запускаете его, он возвращает список кортежей:
[('1828', '100', 'Firefox'), ('1891', '50', 'ffplay'), ('1907', '100', 'ffplay')]
Каждый кортеж содержит:
- Приемник ввода # используется
pulseaudio
(соблюдаетсяffplay
) - Текущий объем (с пробелами и
%
зачищен) - Название приложения (с удаленными двойными кавычками
"
)