我们需要从用户或从调用者到我们的 API 的流中获取视频文件/数据,在处理它时,我们需要使用 HLS 生成实时流
FFMPEG 支持使用以下命令创建 HLS 格式的直播流
String cmd[] = new String[]{
"ffmpeg",
"-re",
"-i", src,
"-c:v:0", "copy",
"-b:v:1", "512k",
"-b:a:0", "64k",
"-b:a:1", "32k",
"-map", "0:v",
"-map", "0:a",
"-map", "0:v",
"-map", "0:a",
"-f", "hls",
"-var_stream_map", "v:0,a:0 v:1,a:1",
"-hls_time", "5",
"-hls_segment_filename", folder+"/stream_%v/data%02d.ts",
"-hls_list_size", "5",
"-hls_delete_threshold", "2",
"-hls_flags", "delete_segments",
"-master_pl_name", "playlist.m3u8",
folder+"/stream_%v/sub-playlist.m3u8"};
来源可以在哪里
- 磁盘上的文件 /path/file.mp4
- UDP url udp://localhost:port
我们得到了我们需要在这样的函数中编码的字节:
handleFileStream(HttpServletRequest request)
然后我们可以循环输入流并使用UDP将其发送到FFMPEG
ServletInputStream inputStream = request.getInputStream();
byte[] buffer = new byte[8 * 1024];
int bytesRead;
while ((bytesRead = inputStream.read(buffer)) != -1) {
DatagramPacket packet = new DatagramPacket(buffer, bytesRead, address, udpCurPort);
socket.send(packet);
}
但是这种方法有两个我们可以看到的问题
我们需要使用 udp 与 FFMPEG 通信,并且每次转换都需要一个新端口,并且我们假设我们将同时运行多个转换
我们看到 ffmpeg 只在流的末尾创建 HLS 播放列表,我们在流过程中要创建什么流
有没有更好的方法将流字节传递给 FFMPEG?
我们在 java 环境中运行,我们像这样启动 FFMPEG:
Runtime rt = Runtime.getRuntime();
Process pr = rt.exec(cmd);