下载完成前如何播放音频?

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

我有一个 Angular 客户端和一个 SpringBoot 服务器。在服务器上,我有一个端点,可以从文本生成音频文件。音频文件的生成依赖于另一个需要太长时间(5 秒以上)的 API,我不想让用户等待超过 5 秒才能开始音频。

为了解决时间问题,我在从 API 接收字节时返回一个 Flux(支持流式传输)。到这里为止,一切都很好。端点代码:

    @PostMapping(value = "/speech")
    public Flux<DataBuffer> generateSpeechAudio(@RequestBody @Valid SpeechRequest speechRequest) {
        return audioService.generateSpeech(speechRequest);
    }

在客户端(Angular),我想在字节下载完成之前调用 API 并启动音频。为此,我正在使用 reportProgress 并观察客户端调用中的事件:

    transcribeTextToAudio(toAudio: ITranscript): Observable<HttpEvent<string>> {
        return this.httpClient.post<string>(`${this.transcriptionLink}/speech`, toAudio, {
            observe: 'events',
            responseType: 'arrayBuffer' as 'json',
            reportProgress: true,
        });
    }

我不确定如何获取字节并“播放它们”,或者即使这样的事情是可能的。使用 MediaSource 可以,但只有我等待整个文件下载。

angular spring-boot audio-streaming
1个回答
0
投票

使用 MediaSource 是一种方法,但它仅适用于几个编解码器和容器,并且可能很棘手。

更好的方法是让浏览器处理播放和流式传输。 为此,请不要发出 POST 请求,而是发出 GET 请求。 尝试这样的事情:

const audioUrl = new URL('speech', this.transcriptionLink);
audioUrl.searchParams.set('text', 'text to speak goes here');

const audio = new Audio(audioUrl);
audio.play(); // Do this on-click or some similar user action, at least at first to avoid autoplay policy issues.

在这种情况下,浏览器通过音频元素为您发出 GET 请求。 一旦它认为有足够的缓冲,它就会开始播放。

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