将音频从Kotlin / Spring后端流到前端

时间:2018-07-21 14:49:39

标签: javascript java spring audio kotlin

我正在做的项目的想法是:

  • N个用户(通过网络浏览器)加入“会议室”
  • Java后端控制将在前端播放的歌曲
  • 房间里的每个人都在同时听这首歌。就像直播音频流
  • 如果某人稍后加入,它将在其他人收听的同一时间收听歌曲。

问题是:

  

I)到目前为止,当JS执行GET时,我可以将mp3字节从Java后端发送到前端。但是下载时,它总是从一开始就播放歌曲。如何让js下载一个块并在uis下载时播放它?

     

II)如果这不是保持相同音频时间流逝的最佳方法,那么我该如何让所有获取我的Backend API的人同时接收相同的音频字节?

     

III)如何确保以后加入的用户收听相同的音频?

     

IV)RESTful API是我获得的最佳选择吗? WebSockets将是更好的选择吗?到目前为止,使用“恒定流字节GET”的REST方法似乎不错。


到目前为止,我有:

一个带有弹簧反应器后端的Kotlin,其GET映射返回一个Flux并将音频字节写入HttpServletResponse(我知道不是100%反应的)。 我的JS首先下载整个字节,然后为下载它的任何人播放。

由于我从未使用过诸如媒体流之类的东西,所以我不确定我可以使用什么框架来帮助会议室中的所有用户在同一时间播放相同的音频。

到目前为止,我的控制器代码:

@RestController
class TestController {

    @RequestMapping(path = ["/"], produces = [TEXT_EVENT_STREAM_VALUE])
    fun streamAudioBytes(response: HttpServletResponse): Flux<String> {

        val out = response.outputStream

        val fileIn = ResourceUtils.getFile("classpath:tetris-mp3.mp3")

        val bytes = fileIn.readBytes()

        return Flux.create {
            out.write(bytes)
        }
    }
}

我第一次尝试播放音频:

<button id="but" onclick="play();">Clica</button>
<audio id="music" preload="all">
    <source src="http://localhost:8080/">
</audio>  

EDIT1:

我必须将字节从后端“流”到前端,现在的交易是: 我的Javascript每T毫秒接收N个字节的MP3文件,并在它们出现时对其进行播放,因此当接收到N个字节时,它们就会被播放。我为JS寻找一种“缓冲”方法,但是根据它的工作方式,我失去了从后端接收字节的每个人的同步性。

  

我该如何避免音频被剪切或自身播放(同时播放2个缓冲收入)?   从后端接收传入字节的JS代码:

function fetchBytes() {
    fetch("http://localhost:8080/").then(response => {
        var reader = response.body.getReader();
        var bytesReceived = 0;

        // read() returns a promise that resolves
        // when a value has been received
        return reader.read().then(function processResult(result) {
            if (result.done) {
                console.log("Fetch complete");
                return;
            }

            playByteArray(result.value)
            bytesReceived += result.value.length;
            console.log('Received', bytesReceived, 'bytes of data so far');

            // Read some more, and call this function again
            return reader.read().then(processResult);
        });
    });
}

0 个答案:

没有答案