Compare commits

..

2 Commits

Author SHA1 Message Date
awe
3a4d9fe45d fix block 2025-11-21 16:48:51 +03:00
awe
eeec3582c9 fix? 2025-11-21 16:31:38 +03:00
2 changed files with 44 additions and 14 deletions

View File

@ -60,15 +60,18 @@ async def init_video_fifo():
return return
try: try:
print(f"Opening FIFO {VIDEO_FIFO_PATH} for reading (will block until C++ opens for writing)...") print(f"Opening FIFO {VIDEO_FIFO_PATH} for reading (non-blocking mode)...")
loop = asyncio.get_event_loop() loop = asyncio.get_event_loop()
# Open file in BLOCKING mode - this will unblock C++ when it opens for writing # Open file in NON-BLOCKING mode to prevent deadlock
# GStreamer filesink opens FIFO lazily (only when first frame arrives)
# Using O_NONBLOCK prevents Python from blocking while waiting for C++ writer
def open_fifo(): def open_fifo():
return open(VIDEO_FIFO_PATH, 'rb', buffering=0) fd = os.open(VIDEO_FIFO_PATH, os.O_RDONLY | os.O_NONBLOCK)
return os.fdopen(fd, 'rb', buffering=0)
video_fifo_file = await loop.run_in_executor(None, open_fifo) video_fifo_file = await loop.run_in_executor(None, open_fifo)
print(f"FIFO opened successfully - C++ should now be writing") print(f"FIFO opened successfully in non-blocking mode")
except Exception as e: except Exception as e:
print(f"Failed to open video FIFO: {e}") print(f"Failed to open video FIFO: {e}")
@ -294,9 +297,11 @@ async def stream_video_from_fifo():
# -c:v copy: copy video codec without re-encoding (use hardware-encoded H.264) # -c:v copy: copy video codec without re-encoding (use hardware-encoded H.264)
# -f hls: output HLS format # -f hls: output HLS format
# -hls_time 1: 1 second per segment (low latency) # -hls_time 1: 1 second per segment (low latency)
# -hls_list_size 5: keep 5 segments in playlist # -hls_list_size 10: keep 10 segments in playlist (more buffer for clients)
# -hls_delete_threshold 3: delete segments only after 3 new ones created
# -hls_flags delete_segments+append_list+omit_endlist: live streaming flags # -hls_flags delete_segments+append_list+omit_endlist: live streaming flags
# -hls_segment_type mpegts: use MPEG-TS segments # -hls_segment_type mpegts: use MPEG-TS segments
# -hls_segment_filename: use %d for unlimited numbering
# -start_number 0: start segment numbering from 0 # -start_number 0: start segment numbering from 0
ffmpeg_process = subprocess.Popen( ffmpeg_process = subprocess.Popen(
['ffmpeg', ['ffmpeg',
@ -308,10 +313,11 @@ async def stream_video_from_fifo():
'-c:v', 'copy', '-c:v', 'copy',
'-f', 'hls', '-f', 'hls',
'-hls_time', '1', '-hls_time', '1',
'-hls_list_size', '5', '-hls_list_size', '10',
'-hls_delete_threshold', '3',
'-hls_flags', 'delete_segments+append_list+omit_endlist', '-hls_flags', 'delete_segments+append_list+omit_endlist',
'-hls_segment_type', 'mpegts', '-hls_segment_type', 'mpegts',
'-hls_segment_filename', f'{hls_dir}/segment_%03d.ts', '-hls_segment_filename', f'{hls_dir}/segment_%d.ts',
'-start_number', '0', '-start_number', '0',
f'{hls_dir}/playlist.m3u8'], f'{hls_dir}/playlist.m3u8'],
stdin=subprocess.PIPE, stdin=subprocess.PIPE,
@ -330,16 +336,39 @@ async def stream_video_from_fifo():
async def read_from_fifo(): async def read_from_fifo():
"""Read from FIFO and pipe to ffmpeg stdin""" """Read from FIFO and pipe to ffmpeg stdin"""
nonlocal bytes_written nonlocal bytes_written
writer_connected = False
try: try:
while streaming_active: while streaming_active:
def read_chunk(): def read_chunk():
return fifo.read(chunk_size) try:
return fifo.read(chunk_size)
except BlockingIOError:
# No data available yet (writer not connected or no data)
return None
data = await loop.run_in_executor(None, read_chunk) data = await loop.run_in_executor(None, read_chunk)
if data is None:
# BlockingIOError: no data available, wait a bit
if not writer_connected:
print("Waiting for C++ to start writing to FIFO...")
await asyncio.sleep(0.1)
continue
if not data: if not data:
print("FIFO EOF reached") # Empty data: EOF (writer closed the FIFO)
if writer_connected:
print("FIFO EOF reached - C++ stopped writing")
else:
print("FIFO closed before C++ started writing")
break break
# Got data! Mark writer as connected
if not writer_connected:
writer_connected = True
print("C++ started writing to FIFO successfully")
if ffmpeg_process and ffmpeg_process.stdin: if ffmpeg_process and ffmpeg_process.stdin:
try: try:
ffmpeg_process.stdin.write(data) ffmpeg_process.stdin.write(data)

View File

@ -367,13 +367,14 @@
if (Hls.isSupported()) { if (Hls.isSupported()) {
hls = new Hls({ hls = new Hls({
// Low latency configuration // Low latency configuration with increased buffer
lowLatencyMode: true, lowLatencyMode: true,
backBufferLength: 90, backBufferLength: 90,
maxBufferLength: 3, maxBufferLength: 10, // Increased from 3 to 10 seconds
maxBufferSize: 1 * 1024 * 1024, // 1MB maxBufferSize: 3 * 1024 * 1024, // Increased from 1MB to 3MB
liveSyncDurationCount: 1, liveSyncDurationCount: 3, // Keep 3 segments in sync
liveMaxLatencyDurationCount: 2, liveMaxLatencyDurationCount: 5, // Max 5 segments latency before catchup
maxMaxBufferLength: 30, // Maximum buffer length
enableWorker: true, enableWorker: true,
debug: false debug: false
}); });