Java 8 - JBoss 服务器上的 javax.sound.sampled.UnsupportedAudioFileException 错误

问题描述 投票:0回答:1

在我使用 Java 8 开发的应用程序中,我尝试将以 Base64 格式接收的 .wav 音频文件转换为 PCM_SIGNED 格式。该代码在本地环境中运行良好,但在 JBoss EAP 6.4 上出现以下错误:

java.lang.RuntimeException: Audio processing failed
       at com.assistt.voicecloneservice.service.AudioConverter.convertBase64ToPcmSigned(AudioConverter.java:42)
       at com.assistt.voicecloneservice.service.AudioProcessingService.processAndUploadAndInsert(AudioProcessingService.java:35)
       at com.assistt.voicecloneservice.api.TtsTextCheckService.doPost(TtsTextCheckService.java:57)
       at javax.servlet.http.HttpServlet.service(HttpServlet.java:754)
       at javax.servlet.http.HttpServlet.service(HttpServlet.java:847)
       at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:295)
       at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:214)
       at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:231)
       at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:149)
       at org.jboss.as.web.security.SecurityContextAssociationValve.invoke(SecurityContextAssociationValve.java:169)
       at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:150)
       at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:97)
       at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:559)
       at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:102)
       at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:344)
       at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:854)
       at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:653)
       at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:926)
       at java.lang.Thread.run(Thread.java:750)
Caused by: javax.sound.sampled.UnsupportedAudioFileException: could not get audio input stream from input stream
       at javax.sound.sampled.AudioSystem.getAudioInputStream(AudioSystem.java:1121)
       at com.assistt.voicecloneservice.service.AudioConverter.convertBase64ToPcmSigned(AudioConverter.java:20)
       ... 18 more

我遇到错误的方法如下:

public void convertBase64ToPcmSigned(String base64Audio) throws Exception {
    byte[] audioByte = Base64.getDecoder().decode(base64Audio);

    try (InputStream inputStream = new ByteArrayInputStream(audioByte);
         ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) {

        // Get AudioInputStream from the input stream
        AudioInputStream inputAudioStream = AudioSystem.getAudioInputStream(inputStream);

        // Define the target audio format
        AudioFormat sourceFormat = inputAudioStream.getFormat();
        AudioFormat targetFormat = new AudioFormat(
                AudioFormat.Encoding.PCM_SIGNED,  // PCM_SIGNED format
                8000.0f,                          // Sample rate
                16,                               // Sample size in bits
                1,                                // Channels (Mono)
                2,                                // Frame size
                8000.0f,                          // Frame rate
                false                             // Big-endian
        );

        AudioInputStream convertedAudioStream = AudioSystem.getAudioInputStream(targetFormat, inputAudioStream);

        File outputFile = new File("output.wav");
        AudioSystem.write(convertedAudioStream, AudioFileFormat.Type.WAVE, outputFile);

    } catch (UnsupportedAudioFileException | IOException e) {
        throw new RuntimeException("Audio processing failed", e);
    }
}

我的pom.xml文件:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.assistt</groupId>
    <artifactId>VoiceCloneService</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>war</packaging>
    <properties>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <dependencies>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>4.0.1</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.postgresql</groupId>
            <artifactId>postgresql</artifactId>
            <version>42.3.1</version>
        </dependency>

        <dependency>
            <groupId>org.json</groupId>
            <artifactId>json</artifactId>
            <version>20210307</version>
        </dependency>
        <dependency>
            <groupId>com.jcraft</groupId>
            <artifactId>jsch</artifactId>
            <version>0.1.55</version>
        </dependency>


    </dependencies>

</project>

我自己手动将base64部分转换为wav文件,它具有以下属性。

Encoding       : PCM_SIGNED  
Sample Rate    : 40000.0 Hz  
Sample Size    : 16 bits  
Channels       : 1  
Frame Size     : 2 bytes  
Frame Rate     : 40000.0 frames/second  
Big Endian     : false  

该错误仅发生在 JBoss EAP 6.4 环境中。当我在本地测试时,文件被正确处理和转换。

我应该检查哪些点或应该尝试哪些替代解决方案来解决此问题?在JBoss环境下处理音频文件需要什么特殊配置吗?

我尝试了以下代码,首先将 Base64 格式数据转换为 .wav 文件,然后基于文件进行处理:

File file = new File(sourceFilePath);
InputStream inputStream = new BufferedInputStream(new FileInputStream(file));

if (!inputStream.markSupported()) {
    return;
}

AudioInputStream audioInputStream = AudioSystem.getAudioInputStream(inputStream);
AudioFormat sourceFormat = audioInputStream.getFormat();

AudioFormat targetFormat = new AudioFormat(
        AudioFormat.Encoding.ALAW,
        8000,
        8,
        sourceFormat.getChannels(),
        1,
        8000,
        false
);

AudioInputStream convertedAudioInputStream = AudioSystem.getAudioInputStream(targetFormat, audioInputStream);

AudioSystem.write(convertedAudioInputStream, AudioFileFormat.Type.WAVE, new File(destinationFilePath));

inputStream.close();
audioInputStream.close();
convertedAudioInputStream.close();

我在这一行收到以下错误:

AudioInputStream audioInputStream = AudioSystem.getAudioInputStream(inputStream);

javax.sound.sampled.UnsupportedAudioFileException: could not get audio input stream from input file
    at javax.sound.sampled.AudioSystem.getAudioInputStream(AudioSystem.java:1189)
    at com.assistt.voicecloneservice.service.AudioConverter.convertBase64ToPcmSigned(AudioConverter.java:34)
    ...
java java-8 jboss jboss6.x javasound
1个回答
0
投票

AudioSystem.getAudioInputStream()
是一个被重写的方法。您可以使用类型为
File
URL
InputStream
的参数来调用它。您使用的版本在API

中有以下注释

此方法的实现可能需要多个解析器来检查流以确定它们是否支持它。这些解析器必须能够标记流,读取足够的数据以确定它们是否支持该流,如果不支持,则将流的读取指针重置为其原始位置。如果输入流不支持这些操作,此方法可能会失败并出现 IOException。

我认为这里的关键事实是“实现...可能需要...”这行可以解释为什么这个命令在某些情况下有效,而在其他情况下无效。

作为解决方法,我建议使用带有

URL
的重载作为参数。 javasound 的 stackoverflow wiki 有示例。

在我看来,

URL
可以在最广泛的情况下工作。例如,有些人使用
File
作为重载,但是当他们将代码部署在 jar 中时(如果
File
是 jar 的一部分),就会失败。此外,还绕过了标记/重置功能测试。

© www.soinside.com 2019 - 2024. All rights reserved.