Issue
I have a Java program which record audio using mixer on a Raspberry Pi. I am using ProcessBuilder to achieve this and was working fine last year. Now it doesn't however, and I get the following error when running the application as root:
Starting Starting recording /tmp/test.wav - 19:14:36.64 /usr/bin/arecord -f dat /tmp/test.wav Exception: Command exited with code: 1 with output: arecord: main:830: audio open error: No such file or directory
java.lang.Exception: Command exited with code: 1 with output: arecord: main:830: audio open error: No such file or directory
at Main.record(Main.java:38) at Main.main(Main.java:11)
When I run as the default 'pi' user (java -jar audioTest.jar) it runs fine.
The only difference between last year is that I am now compiling to Java 11 instead of 8 and possibly running on a newer version of Raspbian OS (11 bullseye).
I have it running with nohup through an init.d script so it is running as the root user. This is also required to access the GPIO of the Raspberry as far as I know.
This is my test code:
import java.io.BufferedReader;
import java.io.File;
import java.io.InputStreamReader;
import java.text.SimpleDateFormat;
import java.util.Date;
public class Main {
public static void main(String[] args) {
System.out.println("Starting");
record(new File("/tmp/test.mp3"));
}
public static void record(File file) {
try {
String wavFile = file.getAbsolutePath().substring(0, file.getAbsolutePath().lastIndexOf(".")) + ".wav";
try {
String player = "/usr/bin/arecord";
ProcessBuilder pb = new ProcessBuilder(player, "-f", "dat", wavFile);
pb.redirectErrorStream(true);
System.out.println("Starting recording " + wavFile + " - " + new SimpleDateFormat("HH:mm:ss.S").format(new Date()));
System.out.println(String.join(" ",pb.command().toArray(new String[0])));
//Process pr = pb.start();
Process recorderProcess = pb.start();
BufferedReader error = new BufferedReader(new InputStreamReader(recorderProcess.getInputStream()));
String errorLine;
StringBuilder accErrorString = new StringBuilder();
while ((errorLine = error.readLine()) != null) {
accErrorString.append(errorLine).append("\n");
}
int exitVal = recorderProcess.waitFor();
if (exitVal != 0) {
throw new Exception("Command exited with code: " + exitVal + " with output: " + accErrorString);
}
} catch (java.io.IOException ioex) {
// This would be the normal exit it seems.
}
} catch (Exception ex){
System.out.println("Exception: " + ex.getMessage());
ex.printStackTrace(System.out);
}
}
}
Any idea why this is happening would be greatly appreciated.
[Edit] The output of record -l:
**** List of CAPTURE Hardware Devices ****
card 3: Device [USB Audio Device], device 0: USB Audio [USB Audio]
Subdevices: 1/1
Subdevice #0: subdevice #0
But adding -D hw:0,0 now gives the error on both. So for th e'pi' user it might select it correctly and not for the root. With hw:3,0 it works, and then add the -c 1 flag to select the channel.
Solution
The error may not be related to the file being recorded, but rather to the sound device that arecord is using.
To resolve this issue, consider the following steps:
Verify if you need to pass -D hw:1,0 (change the device id) as a device parameter to arecord.
Ensure that the audio device files (located under /dev/) are accessible by the root user.
Check if the arecord command is in the $PATH for the root user. You can verify this by running “which arecord” as root.
You can add the root user to the audio group to grant access to audio devices.
You may also find these links helpful:
https://github.com/synesthesiam/voice2json/issues/28
aplay: main:831: audio open error: No such file or directory
Answered By - Borislav Gizdov Answer Checked By - Cary Denson (WPSolving Admin)