[英]ffmpeg live HLS inside Java ProcessBuilder- OK at first, then stalls on an empty output file
我在 HLS 直播模式下操作 ffmpeg,由 Java 16 下的 ProcessBuilder 執行。我們通過 pipe 向進程發送 PCM 音頻數據。 一開始一切似乎都運行得很完美——我可以在 VLC 中本地打開生成的.m3u8 文件,並且播放聽起來很完美。
這是我的StreamEncoder.java包含所述功能。
但是,大約 10 秒后,stream 停止。 沒有來自 ffmpeg 或 Java 的可見故障消息。 但是,我看到創建的最新文件 ffmpeg 有 0 個字節。
這是我程序中的完整日志 output 。 起初,ffmpeg 似乎是健康的。 以下是從內部 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
成功寫入第一個.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
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
而且,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
當我關閉我的程序時,它將 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
這不是一個正確的答案,而是一個相當長的評論。 該循環看起來有點可疑,因為在 .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;
}
如果沒有看到更多代碼,包括代碼饋送queue
以及決定 stream 結束的因素,就很難提供幫助。 您需要另一種方式來表示處理結束(例如queue
中的預定義 EOF 值 - if (bytes == MYEOF) break;
。當您確定沒有更多數據發送到 ffmpeg queue
時,您可以嘗試發信號通過調用ffmpeg.getOutputStream().close()
結束 ffmpeg STD 輸入 stream 。
此外,您不要調用ffmpeg.waitFor()
來確認ffmpeg
子流程已結束。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.