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

如何基于Spring Boot(Java11)实现HTTP/HLS视频直播上传端点?

Spring Boot(Java 11)接收客户端直播视频流的可行方案

核心思路

你的需求是接收客户端持续推送的直播流而非单个文件,因此不能依赖传统的MultipartFile(针对整文件上传),需要直接处理HTTP请求的二进制流,让服务端能持续读取并实时处理字节数据。以下是两种落地实现方案,以及客户端推送的具体方式。


方案一:传统Spring MVC流式接收

通过直接获取HttpServletRequest的输入流,持续读取客户端推送的二进制数据,适合同步处理场景。

控制器实现

@RestController
@RequestMapping("/live-stream")
public class VideoStreamController {

    // 线程池用于异步处理视频流,避免阻塞控制器线程
    private final ExecutorService processingPool = Executors.newFixedThreadPool(4);

    @PostMapping(value = "/upload", consumes = MediaType.APPLICATION_OCTET_STREAM_VALUE)
    public ResponseEntity<Void> receiveLiveStream(HttpServletRequest request) throws IOException {
        try (InputStream inputStream = request.getInputStream()) {
            byte[] buffer = new byte[4096]; // 按4KB分片读取
            int bytesRead;
            
            // 持续读取直到客户端断开连接
            while ((bytesRead = inputStream.read(buffer)) != -1) {
                // 异步提交处理任务,避免阻塞IO线程
                byte[] chunk = Arrays.copyOfRange(buffer, 0, bytesRead);
                processingPool.submit(() -> processVideoChunk(chunk));
            }
        } catch (Exception e) {
            // 处理客户端断开等异常
            e.printStackTrace();
        }
        return ResponseEntity.ok().build();
    }

    // 自定义视频片段处理逻辑(AI检测、帧解析等)
    private void processVideoChunk(byte[] chunk) {
        // 示例:打印片段长度,实际替换为业务逻辑
        System.out.println("处理直播片段,字节数:" + chunk.length);
        // 如需解析视频帧,可引入FFmpeg绑定库(如Jaffree)解码H.264等编码格式
    }
}

配置注意事项

需在application.properties中调整连接超时,避免长连接被提前断开:

server.servlet.connection-timeout=3600000 # 1小时超时

方案二:Spring WebFlux响应式流式接收

适合高并发、非阻塞场景,利用Reactor的Flux处理流式数据,更贴合直播流的持续推送特性。

控制器实现

@RestController
@RequestMapping("/live-stream")
public class ReactiveStreamController {

    @PostMapping(value = "/upload-reactive", consumes = MediaType.APPLICATION_OCTET_STREAM_VALUE)
    public Mono<ResponseEntity<Void>> receiveReactiveStream(@RequestBody Flux<DataBuffer> dataBuffers) {
        return dataBuffers
                .doOnNext(buffer -> {
                    // 读取当前分片数据
                    byte[] chunk = new byte[buffer.readableByteCount()];
                    buffer.read(chunk);
                    DataBufferUtils.release(buffer); // 及时释放内存

                    // 异步处理片段
                    CompletableFuture.runAsync(() -> processVideoChunk(chunk));
                })
                .then(Mono.just(ResponseEntity.ok().build()));
    }

    private void processVideoChunk(byte[] chunk) {
        // 同MVC方案的处理逻辑
        System.out.println("响应式处理直播片段,字节数:" + chunk.length);
    }
}

客户端推送方式

不需要用分片MultiPartFile,直接以二进制流形式推送即可,以下是两种常用工具的示例:

1. FFmpeg推摄像头/本地视频流

适合真实直播场景,将摄像头或本地视频编码后推送到服务端:

# 推送本地摄像头流(Linux示例)
ffmpeg -f v4l2 -i /dev/video0 -c:v libx264 -f mpegts http://localhost:8080/live-stream/upload

# 推送本地视频文件模拟直播流
ffmpeg -i local-video.mp4 -c:v libx264 -f mpegts http://localhost:8080/live-stream/upload

2. CURL模拟流式推送

用于快速测试端点:

curl -X POST -H "Content-Type: application/octet-stream" --data-binary "@test-video.mp4" http://localhost:8080/live-stream/upload

HLS协议适配说明

HLS本身是拉流协议(客户端从服务端拉取TS分片),如果要让客户端推送HLS流,本质是客户端逐个上传TS分片文件。此时可以实现一个接收TS文件的端点,实时处理每个分片:

@PostMapping("/upload-hls-ts")
public ResponseEntity<Void> receiveHLSTs(@RequestParam("ts") MultipartFile tsFile) throws IOException {
    processTSFile(tsFile.getBytes());
    return ResponseEntity.ok().build();
}

private void processTSFile(byte[] tsData) {
    // 解析TS分片,提取视频帧进行处理
    System.out.println("处理HLS TS分片,大小:" + tsData.length);
}

客户端可通过FFmpeg将直播流切分为TS分片后逐个上传,或使用专门的HLS推流工具。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 20:50:36