简体   繁体   English

ffmpeg 在 Java ProcessBuilder 中运行 HLS - 首先是好的,然后停在一个空的 output 文件上

[英]ffmpeg live HLS inside Java ProcessBuilder- OK at first, then stalls on an empty output file

I am operating ffmpeg in live HLS broadcasting mode, executed by a ProcessBuilder under Java 16. We send PCM audio data via a pipe to the process's stdin.我在 HLS 直播模式下操作 ffmpeg,由 Java 16 下的 ProcessBuilder 执行。我们通过 pipe 向进程发送 PCM 音频数据。 Everything seems to run perfectly at first— I can open the resulting.m3u8 file locally in VLC, and the playback sounds perfect.一开始一切似乎都运行得很完美——我可以在 VLC 中本地打开生成的.m3u8 文件,并且播放听起来很完美。

Here's my StreamEncoder.java comprising said functionality.这是我的StreamEncoder.java包含所述功能。

However, after about 10 seconds, the stream stops.但是,大约 10 秒后,stream 停止。 There is no visible failure message from ffmpeg or Java.没有来自 ffmpeg 或 Java 的可见故障消息。 However, I see that the latest file ffmpeg created has 0 bytes.但是,我看到创建的最新文件 ffmpeg 有 0 个字节。

Here's the full log output from my program.这是我程序中的完整日志 output At first, ffmpeg seems to be healthy.起初,ffmpeg 似乎是健康的。 Here are some highlights of what's being sent back from the inner ffmpeg process:以下是从内部 ffmpeg 流程发回的内容的一些亮点:

ffmpeg version 4.2.4-1ubuntu0.1 Copyright (c) 2000-2020 the FFmpeg developers
Output #0, hls, to '/tmp/livemusic.m3u8':
  Metadata:
    encoder         : Lavf58.29.100
    Stream #0:0: Audio: mp2, 48000 Hz, stereo, s16, delay 481, 128 kb/s

...

[hls @ 0x55c9ac4bb300] Opening '/tmp/livemusic-163910309.ts' for writing
[mpegts @ 0x55c9ac475d40] muxrate VBR, pcr every 4 pkts, sdt every 2147483647, pat/pmt every 2147483647 pkts
Output #0, hls, to '/tmp/livemusic.m3u8':
  Metadata:
    encoder         : Lavf58.29.100
    Stream #0:0: Audio: mp2, 48000 Hz, stereo, s16, delay 481, 128 kb/s
    Metadata:
      encoder         : Lavc58.54.100 mp2
[AVIOContext @ 0x55c9ac4e5b00] Statistics: 0 seeks, 1 writeouts
[hls @ 0x55c9ac4bb300] Opening '/tmp/livemusic.m3u8.tmp' for writing
EXT-X-MEDIA-SEQUENCE:163910309

...

EXT-X-MEDIA-SEQUENCE:163910309
[AVIOContext @ 0x55c9ac4a9a00] Statistics: 0 seeks, 1 writeouts
[hls @ 0x55c9ac4bb300] Opening '/tmp/livemusic-163910316.ts' for writing

After successfully writing the first .ts files, there appears an empty file:成功写入第一个.ts文件后,出现一个空文件:

ls /tmp/*.m3u8 /tmp/*.ts -l

-rw-rw-r-- 1 charney charney 168636 Dec  9 18:25 /tmp/livemusic-163910309.ts
-rw-rw-r-- 1 charney charney 168636 Dec  9 18:25 /tmp/livemusic-163910310.ts
-rw-rw-r-- 1 charney charney 168260 Dec  9 18:25 /tmp/livemusic-163910311.ts
-rw-rw-r-- 1 charney charney 168636 Dec  9 18:25 /tmp/livemusic-163910312.ts
-rw-rw-r-- 1 charney charney 168636 Dec  9 18:25 /tmp/livemusic-163910313.ts
-rw-rw-r-- 1 charney charney 168260 Dec  9 18:25 /tmp/livemusic-163910314.ts
-rw-rw-r-- 1 charney charney 168636 Dec  9 18:25 /tmp/livemusic-163910315.ts
-rw-rw-r-- 1 charney charney      0 Dec  9 18:25 /tmp/livemusic-163910316.ts
-rw-rw-r-- 1 charney charney    387 Dec  9 18:25 /tmp/livemusic.m3u8

The ffmpeg process is still running: ffmpeg 进程仍在运行:

ps -aef | grep ffmpeg

charney    22819   22621  0 18:25 ?        00:00:00 ffmpeg -v verbose -i pipe:0 -f hls -ac 2 -c:a mp2 -b:a 128k -minrate 128k -maxrate 128k -hls_playlist_type event -hls_segment_filename /tmp/livemusic-%d.ts -hls_time 10 -initial_offset 163910309 -start_number 163910309 /tmp/livemusic.m3u8

And, ffmpeg appears to be holding on to a filehandle for that empty file:而且,ffmpeg 似乎保留了该空文件的文件句柄:

lsof -p 22819

COMMAND   PID    USER   FD   TYPE DEVICE SIZE/OFF     NODE NAME                                            
ffmpeg  22819 charney  cwd    DIR  253,1     4096 30412671 /home/charney/livemusicproject
ffmpeg  22819 charney  rtd    DIR  253,1     4096        2 /                                                                   
ffmpeg  22819 charney  txt    REG  253,1   280880 24916709 /usr/bin/ffmpeg                                     
(...skipping items like /usr/lib/x86_64-linux-gnu/ ...)
ffmpeg  22819 charney    0r  FIFO   0,12      0t0   319126 pipe                                                        
ffmpeg  22819 charney    1w  FIFO   0,12      0t0   319127 pipe                                                
ffmpeg  22819 charney    2w  FIFO   0,12      0t0   319128 pipe                                                  
ffmpeg  22819 charney    3w   REG  253,1        0 19146562 /tmp/livemusic-163910316.ts                           

When I close my program, which sends a.destroy() to the process, then suddenly and without fanfare, that last file appears at the correct size:当我关闭我的程序时,它将 a.destroy() 发送到进程,然后突然而没有大张旗鼓地,最后一个文件以正确的大小出现:

ls /tmp/*.m3u8 /tmp/*.ts -l

(...skipping same same files...)
-rw-rw-r-- 1 charney charney 168636 Dec  9 18:33 /tmp/livemusic-163910316.ts

This is not a proper answer but a rather long comment.这不是一个正确的答案,而是一个相当长的评论。 The loop looks a bit suspicious as it would be possible for bytes = queue.poll() to be set when .ffmpeg.isAlive() so discarding some input:该循环看起来有点可疑,因为在 .ffmpeg.isAlive() 时可能会设置bytes = queue.poll() .ffmpeg.isAlive()从而丢弃一些输入:

while (active) {
    var bytes = queue.poll();
    if (Objects.isNull(bytes)) continue;
    if (!ffmpeg.isAlive()) {
        LOG.error("Exited with code {}", ffmpeg.exitValue());
        active = false;
        continue;
    }

It's hard to help without seeing more of the code including the code feeding queue and what determines end of stream.如果没有看到更多代码,包括代码馈送queue以及决定 stream 结束的因素,就很难提供帮助。 You need another way to signal end of processing (such as a pre-defined EOF value in the queue - if (bytes == MYEOF) break; . When you determine that no more data is being sent to ffmpeg queue , you could try signalling the end of ffmpeg STD input stream by calling ffmpeg.getOutputStream().close() .您需要另一种方式来表示处理结束(例如queue中的预定义 EOF 值 - if (bytes == MYEOF) break; 。当您确定没有更多数据发送到 ffmpeg queue时,您可以尝试发信号通过调用ffmpeg.getOutputStream().close()结束 ffmpeg STD 输入 stream 。

Also you don't call ffmpeg.waitFor() to confirm that the ffmpeg sub-process has ended.此外,您不要调用ffmpeg.waitFor()来确认ffmpeg子流程已结束。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM