I'm working on a way to capture multichannel audio with OBS video capture, working around some inherent problems (I need PCM 32-bit float, not AAC audio). I've created a nice bash script that monitors changes in a directory and starts recording when a new file is created there. Then monitors that files's size and if it doesn't change for 1 second, it stops the recording.
Everything seems like working like a charm, except fro the most important part. jack_capture quits every time when the script runs it, immediatly after or a second later. It managed to capture a tiny amount of audio (18 kB, 6 kB) but then immediately quits.
Looks like something is calling it to stop, but I've checked and I don't see anything that could do it in my script.
Here's the full script:
Code: Select all
#!/bin/bash
#define the root dir of the project
BASE_DIR="/unfa/Projects/YouTube/Studio"
audio_capture(){
cd "$BASE_DIR/Capture" # go to the Capture directory
while [ True ]; do
# wait until a new mkv file is created in the Capture directory
echo "waiting for capture to start"
watch -n0,1 -g "ls -t *.mkv | head -n 1"
# once it is, start recording to a WAV file with the same name as the newest mkv file
#channels:
# 1 - raw mic input
# 2 - processed mic input
# 3,4 - raw audio
# 5,6 - master, before the limiter
echo "starting capture"
jack_capture -V -c 6 -b 32 -f wav -p "system:capture_1" -p "Non-Mixer/Vox:out-1" -p "Non-Mixer/Audio:out-*" -p "Non-Mixer/MASTER:out-*" -fn "$(ls -t *.mkv | head -n 1 | cut -d'.' -f-1).wav" &
pid_cap=$! # store the capture process PID
echo "capture PID is $pid_cap"
A="10000" # initilize with 0
while [ True ]; do
echo "checking if capture has stopped"
B=$A
sleep 5s # wait - this will let the process skip smome hard disk write hiccups and also give us some backup post-roll
A=$(du "$(ls -t *.mkv | head -n 1)" | cut -f 1) # get teh size in bytes of the newest MKV file in dir
if [ $A -eq $B ]; then #if the sizedidn't change recently
echo "stopping capture"
kill $pid_cap
break
fi;
done
done
}
# find out the location of the webcam by it's name
webcam="/dev/"$(file /dev/v4l/by-id/*C920* | cut -d ' ' -f 5 | cut -c 7-)
echo "Logitech C920 is $webcam"
#recall webcam settings
uvcdynctrl -d $webcam -L "$BASE_DIR/Configuration/uvdynctrl/C920.uvcdynctrl"
# run Non Mixer for audio controls
non-mixer "$BASE_DIR/Configuration/Non Mixer/Capture Mixer 01" &
pid_non=$!
# run Carla for audio processing
carla "$BASE_DIR/Configuration/Carla/Carla 01.carxp" &
pid_carla=$!
# run Open Broadcasting Software
obs &
pid_obs=$!
echo "OBS PID: $pid_obs"
# run guvcview in control panel mode
guvcview -z -d $webcam &
pid_guvc=$!
sleep 3s # wait until all windows are already created
# get windows IDs
wid_obs=$(xdotool search --onlyvisible --name "OBS")
wid_non=$(xdotool search --onlyvisible --name "Non Mixer")
wid_guvc=$(xdotool search --onlyvisible --name "Guvcview")
wid_carla=$(xdotool search --onlyvisible --name "Carla")
# set window states
wmctrl -r "OBS" -b remove,maximized_vert
wmctrl -r "OBS" -b add,maximized_horz
wmctrl -r "Non Mixer" -b add,below
wmctrl -r "Guvcview" -b add,below
# rearange windows
xdotool windowmove $wid_obs 0 0; xdotool windowsize $wid_obs 1920 650
xdotool windowmove $wid_non 0 750; xdotool windowsize $wid_non 800 300
xdotool windowmove $wid_non 0 750
xdotool windowmove $wid_guvc 807 465; xdotool windowsize $wid_guvc 800 600
xdotool windowmove $wid_guvc 807 465
xdotool windowminimize $wid_carla # minimize Carla window
xdotool windowfocus $wid_obs # focus OBS window
# capture audio
audio_capture &
pid_audio=$!
wait $pid_obs
# Once OBS exits, all other will be killed
kill $pid_audio
kill $pid_non
kill $pid_guvc
kill $pid_carla
Code: Select all
audio_capture(){
cd "$BASE_DIR/Capture" # go to the Capture directory
while [ True ]; do
# wait until a new mkv file is created in the Capture directory
echo "waiting for capture to start"
watch -n0,1 -g "ls -t *.mkv | head -n 1"
# once it is, start recording to a WAV file with the same name as the newest mkv file
#channels:
# 1 - raw mic input
# 2 - processed mic input
# 3,4 - raw audio
# 5,6 - master, before the limiter
echo "starting capture"
jack_capture -V -c 6 -b 32 -f wav -p "system:capture_1" -p "Non-Mixer/Vox:out-1" -p "Non-Mixer/Audio:out-*" -p "Non-Mixer/MASTER:out-*" -fn "$(ls -t *.mkv | head -n 1 | cut -d'.' -f-1).wav" &
pid_cap=$! # store the capture process PID
echo "capture PID is $pid_cap"
A="10000" # initilize with 0
while [ True ]; do
echo "checking if capture has stopped"
B=$A
sleep 5s # wait - this will let the process skip soem hard disk write hiccups and also give us some backup post-roll
A=$(du "$(ls -t *.mkv | head -n 1)" | cut -f 1) # get teh size in bytes of the newest MKV file in dir
if [ $A -eq $B ]; then #if the sizedidn't change recently
echo "stopping capture"
kill $pid_cap
break
fi;
done
done
}
Code: Select all
jack_capture -V -c 6 -b 32 -f wav -p "system:capture_1" -p "Non-Mixer/Vox:out-1" -p "Non-Mixer/Audio:out-*" -p "Non-Mixer/MASTER:out-*" -fn "$(ls -t *.mkv | head -n 1 | cut -d'.' -f-1).wav" &
It exits without reporting any specific errors right after writing a header to the WAV file and behaves like someone pressed Enter or Ctrl+C in the terminal. It once managed to capture a few seconds before closing, but that's it.
I wondered if this isn't somehow OBS console output feeding to that shell (crazy idea, but that's something), so I tried redirecting /dev/null to jack_capture stdin to avoid something like this, but still no go. Verbose output makes jack_capture say this:
Code: Select all
main() find default file format
main() find filename
main() init jack 1
buf_size_in_bytes: 6152
main() init buffers
bufinit1. sizeof(long): 8, sizeof(float): 4, sizeof(double):8, sizeof(int):4, sizeof(void*):8
>>> Warning. Could not set higher priority for a SCHED_FIFO process using setpriority().
main() Open soundfile and setup disk callback.
main() Init waiting.
main() Init jack 2.
main() Everything initialized. 8
main() Start meterbridge.
main() Print some info. 42
>>> Recording to "2017-06-15 21-28-37.wav". Press <Return> or <Ctrl-C> to stop.
main() Start helper thread. 7
main() Wait.
main() Stop recording and clean up. 52
connection thread finished
disk thread finished 7
|"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""|
00:|- | 9:02 00:| ||
01:| | 7
02:| |
03:| |
04:| |
05:| |
Buffer: 4.01s./4.01s Time: 0.00m. DHP: [ ] Overruns: 0 Xruns: 0
Finished.
Code: Select all
jack_capture
I wonder why this isn't working.
PS: I've now run it in it's own terminal by accident adding the "&" symbol from the script and it also failed. Could it be that jack_captured can't stand being a background process?