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