AudioSystem,isAudioLineSupported возвращает falseJAVA

Программисты JAVA общаются здесь
Ответить
Anonymous
 AudioSystem,isAudioLineSupported возвращает false

Сообщение Anonymous »

Я пытаюсь использовать аудиокод Java, который работал еще в 2019 году. Сейчас я использую Eclipse IDE с JavaSE-21, работающим в Windows 11. Следующий код не работает:

Код: Выделить всё

    AudioFormat af = makeAudioFormat();
DataLine.Info info = new DataLine.Info(TargetDataLine.class, af);
if (!AudioSystem.isLineSupported(info)) {
System.out.println("Unsupported audio format");
System.out.println(info);
}
println выводит следующую информацию:

Код: Выделить всё

Unsupported audio format interface
TargetDataLine supporting format PCM_SIGNED 44100.0 Hz, 16 bit, mono, 2 bytes/frame, big-endian
Я пробовал моно/стерео и с прямым порядком байтов/с прямым порядком байтов: все они терпят неудачу.
Посмотрев документацию Oracle, я попробовал этот код:

Код: Выделить всё

    if (AudioSystem.isLineSupported(Port.Info.MICROPHONE)) {
Он также не работает с Port.Info.LINE_IN.
Аудиовход определенно работает с Audacity и с программой C, которую я хочу заменить. Программа C использует настройки линии, которые я указал здесь.
В настройках/Конфиденциальность и безопасность/Микрофон включен параметр «Разрешить приложениям доступ к вашему микрофону», и я могу видеть записи Audacity и моей программы C с помощью микрофона, но нет ссылка на приложение Java.
Если я все равно попытаюсь использовать TargetDataLine, я получу следующую трассировку стека:

Код: Выделить всё

Exception in thread "AWT-EventQueue-0" java.lang.IllegalArgumentException: No line matching interface TargetDataLine supporting format PCM_SIGNED 44100.0 Hz, 16 bit, mono, 2 bytes/frame, big-endian is supported.
at java.desktop/javax.sound.sampled.AudioSystem.getLine(AudioSystem.java:423)
at foo.recorder.AudioIn.(AudioIn.java:75)
at foo.recorder.RecorderTab.startRecord(RecorderTab.java:379)
at foo.recorder.RecorderTab$6.buttonPressed(RecorderTab.java:364)
at foo.recorder.NoteClickImage$Listener.onClick(NoteClickImage.java:23)
at foo.recorder.ClickListener.mouseClicked(ClickListener.java:12)
at java.desktop/java.awt.AWTEventMulticaster.mouseClicked(AWTEventMulticaster.java:280)
at java.desktop/java.awt.Component.processMouseEvent(Component.java:6624)
at java.desktop/javax.swing.JComponent.processMouseEvent(JComponent.java:3398)
at java.desktop/java.awt.Component.processEvent(Component.java:6386)
at java.desktop/java.awt.Container.processEvent(Container.java:2266)
at java.desktop/java.awt.Component.dispatchEventImpl(Component.java:4996)
at java.desktop/java.awt.Container.dispatchEventImpl(Container.java:2324)
at java.desktop/java.awt.Component.dispatchEvent(Component.java:4828)
at java.desktop/java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4948)
at java.desktop/java.awt.LightweightDispatcher.processMouseEvent(Container.java:4584)
at java.desktop/java.awt.LightweightDispatcher.dispatchEvent(Container.java:4516)
at java.desktop/java.awt.Container.dispatchEventImpl(Container.java:2310)
at java.desktop/java.awt.Window.dispatchEventImpl(Window.java:2780)
at java.desktop/java.awt.Component.dispatchEvent(Component.java:4828)
at java.desktop/java.awt.EventQueue.dispatchEventImpl(EventQueue.java:775)
at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:720)
at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:714)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:400)
at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:87)
at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:98)
at java.desktop/java.awt.EventQueue$5.run(EventQueue.java:747)
at java.desktop/java.awt.EventQueue$5.run(EventQueue.java:745)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:400)
at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:87)
at java.desktop/java.awt.EventQueue.dispatchEvent(EventQueue.java:744)
at java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:203)
at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:124)
at java.desktop/java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:113)
at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:109)
at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
at java.desktop/java.awt.EventDispatchThread.run(EventDispatchThread.java:90)
Я читал, что это исключение также может быть вызвано проблемой безопасности.

Следуя совету @greg-449, я добавил код для вывода списка доступных строк исходных данных, что привело к следующему:

Код: Выделить всё

Mixer: Primary Sound Driver
interface SourceDataLine supporting 8 audio formats, and buffers of at least 32 bytes
PCM_UNSIGNED unknown sample rate, 8 bit, mono, 1 bytes/frame
PCM_SIGNED unknown sample rate, 8 bit, mono, 1 bytes/frame
PCM_SIGNED unknown sample rate, 16 bit, mono, 2 bytes/frame, little-endian
PCM_SIGNED unknown sample rate, 16 bit, mono, 2 bytes/frame, big-endian
PCM_UNSIGNED unknown sample rate, 8 bit, stereo, 2 bytes/frame
PCM_SIGNED unknown sample rate, 8 bit, stereo, 2 bytes/frame
PCM_SIGNED unknown sample rate, 16 bit, stereo, 4 bytes/frame, little-endian
PCM_SIGNED unknown sample rate, 16 bit, stereo, 4 bytes/frame, big-endian
В нем перечислено множество строк SourceDataLine, но нет строк TargetDataLines. Насколько я понимаю, источник — это (довольно нелогично) выход, а цель — вход, поэтому у меня есть выбор из множества выходных форматов, но нет входных форматов. Это подтверждает мое мнение о том, что это проблема безопасности.

Я добавил этот код, чтобы проверить, есть ли у меня разрешение на запись:

Код: Выделить всё

    javax.sound.sampled.AudioPermission ap = new javax.sound.sampled.AudioPermission("record");
System.out.println ("audio permission " + ap.toString());

try {
// Check if the current execution context has the permission
AccessController.checkPermission(ap);
System.out.println("Permission is granted. The app can record audio.");
// Proceed with the action
} catch (SecurityException e) {
System.out.println("Permission denied. The app cannot rrecord audio.");
// Handle the lack of permission gracefully
e.printStackTrace();
}
И вот результат:

Код: Выделить всё

audio permission ("javax.sound.sampled.AudioPermission" "record")
Permission denied. The app cannot rrecord audio.
java.security.AccessControlException: access denied ("javax.sound.sampled.AudioPermission" "record")
at java.base/java.security.AccessControlContext.checkPermission(AccessControlContext.java:488)
at java.base/java.security.AccessController.checkPermission(AccessController.java:1071)
Я попытался создать файл app.policy с разрешениями на воспроизведение и запись звука и добавил его в качестве параметра виртуальной машины в Eclipse.
  • Приведенный выше код теперь сообщает, что у меня есть разрешение на запись.
  • Я получаю сообщение о том, что Security Manager устарел.
  • Я получаю исключение безопасности при попытке прочитать файл.
  • Я по-прежнему вижу «нет». TargetDataLines, и я не могу его открыть.


Подробнее здесь: https://stackoverflow.com/questions/798 ... urns-false
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «JAVA»