前端audio资源从后端接口获取,后端实现:
/**
* 播放音频
*
* @param request 请求
* @param response 响应
* @param path 音频地址
* @return
*/
@GetMapping("/player")
public void getMusic(HttpServletRequest request, HttpServletResponse response, @RequestParam String path) {
File file = new File(path);
if (!file.exists()) {
throw new RuntimeException("音频文件不存在");
}
WaveFormat waveFormat = chunkAnalyzer.getWaveFormat(path);
try (FileInputStream fis = new FileInputStream(file)) {
String range = request.getHeader("Range");
int start;
long end;
long length = waveFormat.getDataLength() + 44;
if (StringUtils.isEmpty(range)) {
start = 0;
end = 32000;
} else {
String[] rs = range.split("\\=");
String[] split = rs[1].split("\\-");
range = split[0];
start = Integer.parseInt(range);
if (split.length <= 1 && start == 0) {
end = 32000;
} else {
end = length - 1;
}
}
response.addHeader("Accept-Ranges", "bytes");
response.addHeader("Cache-control", "no-cache");
response.addHeader("Content-Length", end - start + 1 + "");
response.addHeader("Content-Range", "bytes " + start + "-" + end + "/" + new BigDecimal(waveFormat.getDataLength()).add(new BigDecimal(44)));
response.addHeader("Content-Type", "audio/x-wav;charset=UTF-8");
response.setStatus(206);
ServletOutputStream os = response.getOutputStream();
fis.skip(start);
copyWithLength(fis, os, end - start+1);
// copy(fis, os);
} catch (Exception e) {
LOG.error(e.getMessage());
e.printStackTrace();
}
}
/**
* 进行字节流拷贝
*
* @param in
* @param out
* @param length 拷贝的长度
* @return
* @throws IOException
*/
public static int copyWithLength(InputStream in, ServletOutputStream out, long length) throws IOException {
Assert.notNull(in, "No InputStream specified");
Assert.notNull(out, "No OutputStream specified");
int byteCount = 0;
int size = 4096;
byte[] buffer = new byte[size];
int bytesRead = -1;
try {
while ((bytesRead = in.read(buffer, 0, ((length - byteCount) >= size ? size : (int) (length - byteCount)))) != -1 && ((length - byteCount) >= size ? size : (int) (length - byteCount)) > 0) {
/**
* 捕获io异常,outputstream抛出异常断开问题,捕获处理
*/
out.write(buffer, 0, bytesRead);
byteCount += bytesRead;
}
out.flush();
LOG.info("总字节:{}", byteCount);
} catch (IOException e) {
/**
* 捕获io异常,outputstream抛出异常断开问题,捕获处理
*/
LOG.error(e.getMessage());
}
return byteCount;
}```
```java
在这里插入代码片
注意:
1.浏览器返回状态为206
2.返回的流的字节数量要和response中的header的content-length数量完全一致;
3.需要处理request头中的range字段,解析range字段获取start和end值,并读读取相对应的文件字节,返回;
4.代码中的获取音频头的代码未贴出;