Потоковое аудио не будет воспроизводиться с использованием тега audio

#java #http #audio #streaming

Вопрос:

Я пытаюсь создать службу потоковой передачи аудио, для этого я создал сервер, который обрабатывает запросы аудиотегов и отвечает соответствующим запрошенным фрагментом. Однако, когда я пытаюсь воспроизвести его в браузере, хотя я вижу запросы, выполняемые браузером, я все равно не могу воспроизвести его. Есть идеи, что случилось?

Серверный код для предоставления фрагментов

 @GetOperation(endpoint = "/stream/song")  public HttpResponse getChunkAudioTag(@RequestHeader(RANGE_HEADER_KEY) String range, @QueryParameter("id") String songId) throws Exception {  JSONObject songInfo = fakeDbDAO.getSongById(songId);  String fileName = (String) songInfo.get("filename");   try (FileInputStream fileInputStream = new FileInputStream(  new File(String.format(RESOURCES_FOLDER_PATH_TEMPLATE, fileName, FileFormat.MP3.getExtension()))  )) {  Headers headers = new Headers(  ACCEPT_RANGES_HEADER_KEY, BYTES,  Headers.CONTENT_TYPE, "audio/mpeg",  Headers.CONNECTION, ConnectionType.KEEP_ALIVE.getValue()  );  int fileSize = fileInputStream.available();   if (range == null) {  return HttpResponse  .builder()  .headers(headers)  .requestStatus(RequestStatus.OK)  .build();  }   String rangeString = range.split(AUDIO_TAG_RANGE_SEPARATOR)[1]; // Splits "bytes=x-y" and returns the actual range  ChunkRange chunkRange = new ChunkRange(rangeString, fileSize);  byte[] audioChunk = getAudioChunk(fileInputStream, chunkRange);   headers.addHeader(CONTENT_RANGE_HEADER_KEY, String.format(CONTENT_RANGE_TEMPLATE, chunkRange.getFrom(), chunkRange.getTo() - 1, fileSize));  headers.addHeader(Headers.CONTENT_LENGTH, String.valueOf(audioChunk.length));   return HttpResponse  .builder()  .requestStatus(RequestStatus.PARTIAL_CONTENT)  .headers(headers)  .body(convertByteArrayToString(audioChunk))  .build();  }  }   private byte[] getAudioChunk(FileInputStream fileInputStream, ChunkRange chunkRange) throws IOException {  byte[] result = new byte[chunkRange.getLength()];   fileInputStream.skip(chunkRange.getFrom());  fileInputStream.read(result);   return result;  }   private String convertByteArrayToString(byte[] chunkByteArray) {  return Base64  .getEncoder()  .encodeToString(chunkByteArray);  }  

Аудиотег (я использую React)

 lt;audio src={`http://localhost:6543/stream/song?id=${currentSong.id}`} controls ref={audioRef} /gt;  

Пример HTTP-запроса

 GET /stream/song?id=1 HTTP/1.1 Host: localhost:6543 Connection: keep-alive Pragma: no-cache Cache-Control: no-cache sec-ch-ua: "Google Chrome";v="95", "Chromium";v="95", ";Not A Brand";v="99" Accept-Encoding: identity;q=1, *;q=0 sec-ch-ua-mobile: ?0 User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36 sec-ch-ua-platform: "macOS" Accept: */* Sec-Fetch-Site: same-site Sec-Fetch-Mode: no-cors Sec-Fetch-Dest: audio Referer: http://localhost:3000/ Accept-Language: en-US,en;q=0.9 Range: bytes=0-  

Пример HTTP-ответа

 HTTP/1.1 206 Partial Content Accept-Ranges: bytes Access-Control-Allow-Origin: * Connection: keep-alive Content-Type: audio/mpeg Content-Range: bytes 0-99999/4127452 Content-Length: 100000  */ base64 encoded chunk /*