Kategorien

DIY (3) Gnome Extension (3) Laptop (1) Linux (8) Server (2) Windows (1)

26 März 2018

Aufnahme sämtlicher Audioquellen

Um diverse möglichst verlustfreie Audio Mitschnitte zu machen, völlig unabhängig welche Quelle abgespielt wird (Streaming wie Radio, Podcasts, etc. etc. - also alles mögliche was der Soundkarte zugeführt wird), setze ich ein Script ein. Mit einem Starter im Gnome Menü, starte ich das Script, anschließend wartet es 30 Sekunden auf einer aktiven Audioquelle. Sobald eine Audioquelle anfängt zu spielen, wird diese aufgenommen. Nach beenden der Audioquelle/Wiedergabe wird eine Titelabfrage vorgenommen und anschließend wahlweise als WAV oder als MP3 inkl. ID3 Tag gespeichert.

Umgesetzt wird dies mit pulseaudio-utils, ffmpeg, mp3splt und für die visuelle Ein-Ausgabe zenity sowie libnotify-bin.

Einzige Manko daran ist, dass es nach Wiedergabe-Stopp manchmal bis zu 20 Sekunden dauern kann, bis PulseAudio bemerkt das kein Audiosignal mehr anliegt. Aber diese Stille lässt sich beispielsweise mit mp3splt korrigieren.

Das Script wird bei mir in
/home/sven/.bin
abgelegt. Das dazugehörige Programm Icon unter
/home/sven/.bin/icons
Angepasst werden muss nur SCRIPT_ICON, voreingestellt greift er auf einem PNG Bild RECORD.png zu
/home/sven/.bin/icons/RECORD.png
 Und SCRIPT_DESTINATION, der die Audiodatei voreingestellt im folgenden Verzeichnis speichert
/home/sven/Musik
Der Aufruf geschieht mittels einem für Gnome erstellten Starter im Verzeichnis
/home/sven/local/share/applications/Record.desktop
Der wie folgt aussieht
[Desktop Entry]
Comment=
Terminal=false
Name=Ton Aufzeichnen
Exec=/home/sven/.bin/record
Type=Application
Icon=/home/sven/.bin/icons/RECORD.png
Das eigentliche Script schaut dann schlussendlich wie folgt aus:
#!/bin/bash
function require() {
    for prog in "$@"; do
        [ `which $prog` ] || { notify-send -i "${SCRIPT_ICON}" -u critical $SCRIPT_NAME "Binary '$prog' not installed. Exit now..."; exit 1; }
    done
}

SCRIPT=$(basename "$0")
SCRIPT_NAME=$(basename "$0" | tr [a-z] [A-Z])
SCRIPT_PATH="$(dirname "$(readlink -e "$0")")"
SCRIPT_ICON="${SCRIPT_PATH}/icons/RECORD.png"
SCRIPT_ICONS="${SCRIPT_PATH}/icons"
SCRIPT_DESTINATION="${HOME}/Musik"

require "ffmpeg" "zenity" "pacmd" "parec" "mp3splt"

i=0; while [[ "`pacmd list-sink-inputs | grep "sink input(s)" | awk '{print $1}'`" == 0 ]] || [[ "`pacmd list-sink-inputs | grep "sink input(s)" | awk '{print $1}'`" -gt 1 ]]; do 
    if [ $i -eq 0 ]; then
        notify-send -i "${SCRIPT_ICON}" -u normal $SCRIPT_NAME "Warte nun 30 Sekunden auf dem zu speichernden Stream"
    elif [ $i -eq 300 ]; then
        if [[ "`pacmd list-sink-inputs | grep "sink input(s)" | awk '{print $1}'`" == 0 ]]; then
            notify-send -i "${SCRIPT_ICON}" -u critical $SCRIPT_NAME "Es wurde kein Audio Stream zur Soundkarte erkannt"
            exit 1
        elif [[ "`pacmd list-sink-inputs | grep "sink input(s)" | awk '{print $1}'`" -gt 1 ]]; then
            notify-send -i "${SCRIPT_ICON}" -u critical $SCRIPT_NAME "Zu viele Audio Streams zur Soundkarte erkannt"
            exit 1
        fi
    fi
    i=$[$i+1]
    sleep 0.1
done

CONTENT="$(pacmd list-sink-inputs)"
APPLICATION="$(echo "$CONTENT" | grep "application\.name" | awk '{print $3}' | sed 's/\"//g')"
INDEXEXIST="$(echo "$CONTENT" | grep "index:" | wc -l 2>&1)"

if [ $INDEXEXIST -gt 0 ]; then
    if [ $INDEXEXIST -eq 1 ]; then
        notify-send -i "${SCRIPT_ICON}" -u normal $SCRIPT_NAME "Stream wird von <$APPLICATION> aufgenommen."
        INDEX="$(pacmd list-sink-inputs | grep "index: " | awk '{print $2}')"
        parec --verbose --monitor-stream=$INDEX --file-format=wav /tmp/audio_record_tmp.wav 2>&1
        notify-send -i "${SCRIPT_ICON}" -u normal $SCRIPT_NAME "Stream Aufnahme beendet"
        if [ -f /tmp/audio_record_tmp.wav ]; then
            if [ -d ~/Musik ]; then
                while ! echo "$NAME" | grep ".* - .*" > /dev/null; do
                    NAME=$(zenity --entry --title="$SCRIPT" --ok-label="OK" --cancel-label="Abbruch" --text="Bitte gebe einen Dateinamen (ohne Endung) für die Aufnahme ein.\n\nIdealerweise: Interpret - Titel\n\n" --entry-text="$NAME")
                    if [ $? = 1 ] || [ -z "$NAME" ]; then
                        notify-send -i "${SCRIPT_ICON}" -u critical $SCRIPT_NAME "Aufnahme abgebrochen. Datei wird verworfen..."
                        rm /tmp/audio_record_tmp.wav
                        exit 1
                    else
                        ARTIST=${NAME% - *}
                        TITLE=${NAME#* - }
                    fi
                done

                zenity --question --title="$SCRIPT" --ok-label="MP3" --cancel-label="WAVE" --text="Soll die Aufnahme direkt in MP3 konvertiert werden?\n\nZiel: ${SCRIPT_DESTINATION}/${NAME}\n\nWenn WAVE ausgewählt wird, wird die Aufnahme als WAV verlustfrei zur Weiterverarbeitung gespeichert."
                if [ $? = 1 ]; then
                    mv /tmp/audio_record_tmp.wav "${SCRIPT_DESTINATION}/${NAME}.wav"
                    notify-send -i "${SCRIPT_ICON}" -u normal $SCRIPT_NAME "Stream Aufnahme wurde als WAV gespeichert. Fertig"
                else
                    notify-send -i "${SCRIPT_ICON}" -u normal $SCRIPT_NAME "Stream wird zu MP3 konvertiert. Bitte warten..."
                    
                    ffmpeg -i /tmp/audio_record_tmp.wav -metadata title="$TITLE" -metadata artist="$ARTIST" -ab 256k -ac 2 /tmp/audio_record_tmp.mp3 2>&1
                    if [ $? = 0 ]; then
                     rm /tmp/audio_record_tmp.wav
                    else
                     notify-send -i "${SCRIPT_ICON}" -u critical $SCRIPT_NAME "Konvertierung fehlgeschlagen"
                     [ -f /tmp/audio_record_tmp.wav ] && rm /tmp/audio_record_tmp.wav
                     [ -f /tmp/audio_record_tmp.mp3 ] && rm /tmp/audio_record_tmp.mp3
                     exit 1
                    fi
                    
                    mp3splt -r -p min=2 /tmp/audio_record_tmp.mp3 > /dev/null 2>&1
                    if [ $? = 0 ]; then
                     [ -f /tmp/audio_record_tmp.mp3 ] && rm /tmp/audio_record_tmp.mp3
                     mv /tmp/audio_record_tmp_trimmed.mp3 "${SCRIPT_DESTINATION}/${NAME}.mp3"
                    else
                     notify-send -i "${SCRIPT_ICON}" -u critical $SCRIPT_NAME "MP3 Stille entfernen fehlgeschlagen"
                     [ -f /tmp/audio_record_tmp_trimmed.mp3 ] && rm /tmp/audio_record_tmp_trimmed.mp3
                     mv /tmp/audio_record_tmp.mp3 "${SCRIPT_DESTINATION}/${NAME}.mp3"
                    fi
                    notify-send -i "${SCRIPT_ICON}" -u normal $SCRIPT_NAME "Stream konvertieren abgeschlossen. Fertig"
                fi
                
            else
                notify-send -i "${SCRIPT_ICON}" -u critical $SCRIPT_NAME "Ordner MUSIK existiert im Benutzerverzeichnis nicht"
            fi
        else
            notify-send -i "${SCRIPT_ICON}" -u critical $SCRIPT_NAME "Die temporäre Aufnahme wurde nicht gefunden"
        fi
    else
        notify-send -i "${SCRIPT_ICON}" -u critical $SCRIPT_NAME "Zu viele Audio Streams zur Soundkarte erkannt"
    fi
else 
    notify-send -i "${SCRIPT_ICON}" -u critical $SCRIPT_NAME "Es wurde kein Audio Stream zur Soundkarte erkannt"
fi

Keine Kommentare: