You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让Flutter的just_audio兼容Amazon Polly驱动的Spring Boot服务?

问题:Flutter just_audio无法播放Spring Boot生成的Polly音频

我正在开发一款Flutter应用,使用just_audio库播放短语音提示。手动通过AWS控制台用Amazon Polly生成MP3并上传到S3后,just_audio可以正常播放,代码如下:

final AudioPlayer audioPlayer = AudioPlayer();
audioPlayer.setUrl('https://bucketname.s3.eu-west-2.amazonaws.com/say_someting.mp3');
audioPlayer.play();

但需要根据运行时动态文本实时生成语音,因此搭建了Java Spring Boot微服务调用Polly并暴露接口。音频时长3秒内、大小约15KB,服务代码如下:

@GetMapping(path = "/mp3", produces = "audio/mpeg")
public byte[] getAudio()
{
    // 运行时动态文本
    final String whatToSay = "The time is now " + System.currentTimeMillis();

    // 构造Polly语音合成请求
    final SynthesizeSpeechRequest synthesizeSpeechRequest = new SynthesizeSpeechRequest()
            .withOutputFormat(OutputFormat.Mp3)
            .withVoiceId(VoiceId.Amy)
            .withText(whatToSay);

    // 可启用SSML控制语调
    // synthesizeSpeechRequest.setTextType(TextType.Ssml);

    final SynthesizeSpeechResult synthesizeSpeechResult = amazonPolly.synthesizeSpeech(synthesizeSpeechRequest);

    // 将音频流转为字节数组返回
    final ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
    IOUtils.copy(synthesizeSpeechResult.getAudioStream(), outputStream);
    return outputStream.toByteArray();
}

服务部署到Elastic Beanstalk后,浏览器访问接口能正常播放,下载的MP3也能在Quicktime播放,但just_audio调用时抛出source error异常,代码如下:

final AudioPlayer audioPlayer = AudioPlayer();
audioPlayer.setUrl('https://my-domain/mp3');
audioPlayer.play();

已尝试的排查动作:

  • 调试just_audio源码,但异步Future的错误无法追踪
  • 尝试设置空请求头调用接口
  • 试用flutter_tts但无法控制语调
  • 改为流式输出Polly音频,问题仍存在

测试接口响应头:

HTTP/1.1 200
Server: nginx
Date: Thu, 08 Feb 2024 07:59:14 GMT
Content-Type: audio/mpeg
Content-Length: 50043
Connection: keep-alive
解决方案

1. 直接转发Polly原始音频流

just_audio对音频格式校验严格,字节流转换可能丢失关键文件头信息。修改Spring Boot接口,直接将Polly的原始音频流写入响应输出流:

@GetMapping(path = "/mp3", produces = "audio/mpeg")
public void getAudio(HttpServletResponse response) throws IOException {
    String whatToSay = "The time is now " + System.currentTimeMillis();
    SynthesizeSpeechRequest request = new SynthesizeSpeechRequest()
            .withOutputFormat(OutputFormat.Mp3)
            .withVoiceId(VoiceId.Amy)
            .withText(whatToSay);

    SynthesizeSpeechResult result = amazonPolly.synthesizeSpeech(request);
    InputStream audioStream = result.getAudioStream();

    response.setContentType("audio/mpeg");
    response.setContentLength((int) result.getContentLength());
    IOUtils.copy(audioStream, response.getOutputStream());
    response.getOutputStream().flush();
}

2. 为just_audio添加请求头并等待异步操作

部分服务器会限制缺少特定头的请求,且需确保音频加载完成后再播放:

final AudioPlayer audioPlayer = AudioPlayer();
await audioPlayer.setUrl(
  'https://my-domain/mp3',
  headers: {
    'Accept': 'audio/mpeg',
  },
);
await audioPlayer.play();

3. 配置跨域(CORS)

Flutter应用可能存在跨域限制,在Spring Boot中添加CORS配置:

@Configuration
public class CorsConfig implements WebMvcConfigurer {
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
                .allowedOrigins("*")
                .allowedMethods("GET", "POST")
                .allowedHeaders("*");
    }
}

也可直接在Controller方法上添加@CrossOrigin(origins = "*")注解。

4. 验证音频格式标准性

下载Spring Boot接口返回的音频,用ffmpeg检查格式是否符合just_audio兼容的MP3标准:

ffmpeg -i downloaded.mp3 -v info

若存在格式问题,可在服务端添加简单转码步骤确保格式合规。


内容的提问来源于stack exchange,提问作者Paul Wells

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 19:17:02