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

基于Spring MVC实现外部HLS流的后端Basic Auth代理播放

代理带HTTP Basic Auth的HLS流:Spring MVC实现方案

我在开发一个基于Spring MVC的Java Web应用时,需要代理访问外部HLS服务器(rtsp-simple-server/mediamtx)——这个服务器仅启用HLS协议,流地址示例为https://mediaserver.url:port/stream1,且受HTTP Basic Auth保护。核心需求是后端完成认证,前端用hls.js播放视频时不弹出登录框、不暴露凭证。

之前踩的坑

一开始试过用WebFilter和RestTemplate处理:用RestTemplate能成功获取m3u8清单,但浏览器请求分片时会触发文件保存提示,根本没法正常播放。

最终可行方案:Controller代理请求

通过编写Spring Controller实现请求转发,让后端注入认证信息并流式转发HLS数据,完美解决了分片播放的问题。

1. 配置带认证的RestTemplate

给RestTemplate添加BasicAuthorizationInterceptor,一次性注入HLS服务器的账号密码,不用每次请求手动构造Auth头:

@Bean
public RestTemplate hlsRestTemplate() {
    RestTemplate restTemplate = new RestTemplate();
    String username = "your-username";
    String password = "your-password";
    restTemplate.getInterceptors().add(new BasicAuthorizationInterceptor(username, password));
    return restTemplate;
}

2. 编写代理Controller

用StreamingResponseBody流式转发外部服务器的响应,保证分片数据能被浏览器正常解析:

@Controller
@RequestMapping("/streams")
public class HlsStreamProxyController {

    private final RestTemplate hlsRestTemplate;
    private static final String HLS_SERVER_BASE_URL = "https://mediaserver.url:port";

    public HlsStreamProxyController(RestTemplate hlsRestTemplate) {
        this.hlsRestTemplate = hlsRestTemplate;
    }

    @GetMapping("/{streamName}/**")
    public ResponseEntity<StreamingResponseBody> proxyStream(@PathVariable String streamName,
                                                             HttpServletRequest request) {
        // 拼接外部HLS服务器的完整请求路径
        String requestPath = request.getRequestURI().replace("/streams/" + streamName, "");
        String externalUrl = HLS_SERVER_BASE_URL + "/" + streamName + requestPath;

        // 获取外部响应的头信息,原样返回给前端(确保Content-Type等正确)
        HttpHeaders headers = hlsRestTemplate.headForHeaders(externalUrl);

        // 流式转发响应体,避免内存占用过大
        StreamingResponseBody responseBody = outputStream -> {
            ResponseEntity<Resource> response = hlsRestTemplate.getForEntity(externalUrl, Resource.class);
            try (InputStream inputStream = response.getBody().getInputStream()) {
                IOUtils.copy(inputStream, outputStream);
            }
        };

        return ResponseEntity.ok()
                .headers(headers)
                .body(responseBody);
    }
}

提示:需要导入org.apache.commons.io.IOUtils(或用Java原生的InputStream.transferTo(outputStream)替代)处理流复制。

3. 前端播放方式

前端可以直接用hls.js加载代理后的流地址,或者用iframe嵌入:

<!-- 方式1:hls.js直接播放 -->
<video id="videoPlayer" controls width="640" height="480"></video>
<script src="https://cdn.jsdelivr.net/npm/hls.js@latest"></script>
<script>
  const video = document.getElementById('videoPlayer');
  if (Hls.isSupported()) {
    const hls = new Hls();
    hls.loadSource('./streams/camera1/index.m3u8');
    hls.attachMedia(video);
  }
</script>

<!-- 方式2:iframe嵌入 -->
<iframe src="./streams/camera1/" width="640" height="480" frameborder="0"></iframe>

这套方案里,后端自动完成与外部HLS服务器的认证,前端完全不用接触凭证,也不会弹出登录弹窗,分片数据能被hls.js正常解析播放。

内容的提问来源于stack exchange,提问作者Stefano Colla

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 23:55:37