Skip to content

Instantly share code, notes, and snippets.

@mishashevelinn
Forked from ramast/pulse-recorder.py
Created September 3, 2023 11:12
Show Gist options
  • Select an option

  • Save mishashevelinn/ca1c74725f1616f55f83177e9cfa84dc to your computer and use it in GitHub Desktop.

Select an option

Save mishashevelinn/ca1c74725f1616f55f83177e9cfa84dc to your computer and use it in GitHub Desktop.

Revisions

  1. @ramast ramast revised this gist May 27, 2020. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion pulse-recorder.py
    Original file line number Diff line number Diff line change
    @@ -1,5 +1,5 @@
    #!/usr/bin/env python3
    # Original code came from these stackoverflow answers:
    # Based on code from these stackoverflow answers:
    # https://askubuntu.com/questions/60837/record-a-programs-output-with-pulseaudio/910879#910879
    import re
    import subprocess
  2. @ramast ramast revised this gist May 27, 2020. 1 changed file with 2 additions and 0 deletions.
    2 changes: 2 additions & 0 deletions pulse-recorder.py
    Original file line number Diff line number Diff line change
    @@ -1,4 +1,6 @@
    #!/usr/bin/env python3
    # Original code came from these stackoverflow answers:
    # https://askubuntu.com/questions/60837/record-a-programs-output-with-pulseaudio/910879#910879
    import re
    import subprocess
    import sys
  3. @ramast ramast created this gist Jul 23, 2019.
    110 changes: 110 additions & 0 deletions pulse-recorder.py
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,110 @@
    #!/usr/bin/env python3
    import re
    import subprocess
    import sys
    import os
    import signal
    from time import sleep

    INDEX_RE = re.compile(r'[0-9]+$')
    APP_NAME_RE = re.compile(r'"([^"]+)"')
    SINK_RE=re.compile("\s*sink: ([0-9]+) <.*>")

    DEFAULT_OUTPUT_RE = re.compile(r'^\s*name: <([^ >]+)>')

    record_module_id = None

    def get_default_output():
    #pacmd list-sinks | grep -A1 "* index" | grep -oP "<\K[^ >]+"
    output = subprocess.run(["pacmd", "list-sinks"], stdout=subprocess.PIPE, check=True).stdout
    for line in output.decode('utf-8').split('\n'):
    match = DEFAULT_OUTPUT_RE.match(line)
    if match:
    return match[1]
    print("Can't seem to find proper input sink, are you using pulseaudio?")
    sys.exit(3)

    def load_record_module():
    default_output = get_default_output()
    output = subprocess.run(
    ["pactl", "load-module", "module-combine-sink", "sink_name=record-n-play", f"slaves={default_output}",
    "sink_properties=device.description=Record-and-Play"],
    stdout=subprocess.PIPE, check=True).stdout
    return int(output.strip())

    def load_apps():
    output = subprocess.run(["pacmd", "list-sink-inputs"], stdout=subprocess.PIPE, check=True).stdout
    output = output.decode('utf-8').split('\n')

    indexes = []
    app_names = []
    sinks = []

    for line in output:
    if "index" in line:
    index = INDEX_RE.findall(line)[0]
    indexes.append(index)
    elif "application.name" in line:
    app_name = APP_NAME_RE.findall(line)[0]
    app_names.append(app_name)
    elif len(sinks) < len(indexes) and "sink: " in line:
    sink = SINK_RE.match(line)[1]
    sinks.append(sink)

    if len(indexes) == 0:
    print("Sorry, couldn't find any input audio channels")
    sys.exit(1)
    return indexes, app_names, sinks

    def cleanup(*args, **kwargs):
    if record_module_id is None:
    sys.exit(0)
    return

    os.system(f"pactl move-sink-input {indexes[user_selection]} {sinks[user_selection]}")
    os.system(f"pactl unload-module {record_module_id}")
    print("Terminated")
    sys.exit(0)
    signal.signal(signal.SIGTERM, cleanup)
    signal.signal(signal.SIGINT, cleanup)


    if os.path.exists("temp.mp3"):
    print("temp.mp3 already exist, aborting")
    sys.exit(2)

    _, app_names, _ = load_apps()
    print("")
    for idx, app_name in enumerate(app_names):
    print(f"{idx + 1} - {app_name}")
    print("")

    while True:
    try:
    user_selection = int(input("Please enter a number: "))
    except ValueError:
    print("Only numbers are allowed")
    continue

    if user_selection > len(app_names) or user_selection <= 0:
    print("Number out of range")
    continue

    user_selection = int(user_selection) - 1
    break

    app_name = app_names[user_selection]
    print(f"Your selection was: {app_name}")
    input("Please press enter when you are ready to start")

    while True:
    indexes, app_names, sinks = load_apps()
    if app_name not in app_names:
    print("Couldn't find selected audio channel, retrying")
    sleep(0.2)
    continue
    user_selection = app_names.index(app_name)
    record_module_id=load_record_module()
    os.system(f"pactl move-sink-input {indexes[user_selection]} record-n-play")
    os.system(f"parec --format=s16le -d record-n-play.monitor | lame -r -q 3 --lowpass 17 --abr 192 - 'temp.mp3'")
    cleanup()