#
# The third form waits for a new sink-input to appear, and will record that.
#
-# Copyright © 2020 martin f. krafft <madduck@madduck.net>
+# Copyright © 2020–2021 martin f. krafft <madduck@madduck.net>
# Released under the teams of the Artistic Licence 2.0
#
set -eu
+cleanup_commands=
+cleanup() {
+ set +e
+ eval $cleanup_commands 2>/dev/null
+ trap - 1 2 3 4 5 6 7 8 10 11 12 13 14 15
+}
+trap cleanup 1 2 3 4 5 6 7 8 10 11 12 13 14 15
+cleanup_hook() {
+ cleanup_commands="$@${cleanup_commands:+; $cleanup_commands}"
+}
+
if [ -z "${TMPDIR:-}" ]; then
TMPDIR=/tmp
fi
done
export TMPDIR
TMPDIR=$(mktemp -dp "$TMPDIR" parec.XXXXXXXXXX)
+cleanup_hook rm -r $TMPDIR
-cleanup_commands="rm -r $TMPDIR"
-cleanup() {
- set +e
- eval $cleanup_commands 2>/dev/null
- trap - 1 2 3 4 5 6 7 8 10 11 12 13 14 15
-}
-trap cleanup 1 2 3 4 5 6 7 8 10 11 12 13 14 15
-cleanup_hook() {
- cleanup_commands="$@${cleanup_commands:+; $cleanup_commands}"
-}
+if command -v systemd-inhibit >/dev/null; then
+ systemd-inhibit --who=pulserecorder --why=recording sleep 99d 2>/dev/null &
+ cleanup_hook kill $!
+fi
state= outfile= index= clobber=0
for arg in "$@"; do
type="${1:-*}" event="${2:-*}" id="${3:-*}"
pa_subscribe | (
read pid
- #echo >&2 pa_subscribe started with PID $pid
+ #echo >&2 pa_subscribe started with PID $pid, waiting for $type/$event/$id
while read lead xevent on xtype xid; do
xid=${xid#\#}
#echo >&2 "pa_subscribe: $xtype/$xevent/$xid ($type/$event/$id)"
}
}
+uuidgen() {
+ hascmd() { command -v "$@" >/dev/null;}
+ if hascmd uuid; then uuid
+ elif hascmd uuidgen; then uuidgen
+ elif hascmd python3; then
+ python3 -c 'import uuid; print(uuid.uuid1())'
+ elif hascmd python; then
+ python -c 'import uuid; print(uuid.uuid1())'
+ else
+ dd if=/dev/urandom bs=16 count=1 status=none | base64
+ fi
+}
+
+if [ -z "$outfile" ]; then
+ uuid=$(uuidgen)
+ outfile="${uuid}.ogg"
+fi
+
+if [ -f "$outfile" ] && [ $clobber -eq 0 ]; then
+ echo >&2 "E: file exists, and -f not given: $outfile"
+ exit 1
+fi
case "$index" in
(last)
exit 1
fi
-uuidgen() {
- hascmd() { command -v "$@" >/dev/null;}
- if hascmd uuid; then uuid
- elif hascmd uuidgen; then uuidgen
- elif hascmd python3; then
- python3 -c 'import uuid; print(uuid.uuid1())'
- elif hascmd python; then
- python -c 'import uuid; print(uuid.uuid1())'
- else
- dd if=/dev/urandom bs=16 count=1 status=none | base64
- fi
-}
-
-uuid=$(uuidgen)
-
-[ -n "$outfile" ] || outfile="${uuid}.ogg"
-
-if [ -f "$outfile" ] && [ $clobber -eq 0 ]; then
- echo >&2 "E: file exists, and -f not given: $outfile"
- exit 1
-fi
-
-devname="record-to-file-${uuid}"
+devname="record-to-file-$(echo -n ${outfile%.*} | tr -c '[:alnum:]' '_')"
echo >&2 "Recording source $index to $outfile …"
}
move_source_to_sink() {
- local c;
+ local c d;
c=$(pactl list short sink-inputs | sed -rne "s,^${1}[[:space:]]+([[:digit:]]+).+,\1,p")
+ d="$(pactl list short sinks | sed -rne "s,^${c}[[:space:]]+([^[:space:]]+).+,\1,p")"
+ case "$d" in
+ (record-to-file-*)
+ # Never restore to a record-to-file destination, or it could botch
+ # another recording
+ c="@DEFAULT_SINK@"
+ ;;
+ (*) :;;
+ esac
+ echo >&2 "Moving input $1 to sink $2 (restore to $c) …"
cleanup_hook pactl move-sink-input $1 $c
pactl move-sink-input $1 $2
}
-if false; then
+if [ -n "${PAREC_PIPE:-}" ]; then
# This would be great, but it does not work. For instance, trying this on
# audible meant that audible would play at maximum speed (3h played in 3
# minutes), but the result would be full of skips, making me think that
load_module module-pipe-sink "$devname" "$devname" file="$TMPDIR/outfifo"
move_source_to_sink $index "$devname"
- oggenc --raw -q5 -o "$outfile" "$TMPDIR/outfifo" || :
- #pv -pterb "$TMPDIR/outfifo" > $TMPDIR/outfile.wav || :
+ #oggenc --raw -q5 -o "$outfile" "$TMPDIR/outfifo" || :
+ pv -pterb "$TMPDIR/outfifo" > $TMPDIR/outfile.wav &
+ pid=$!
+ pa_wait_for_event sink-input remove $index >/dev/null
+ kill $pid
else
# More traditional approach, which just takes 1:1 time.