Fixing an issue with bufferedwriter
This commit is contained in:
@@ -1,4 +1,5 @@
|
|||||||
import logging
|
import logging
|
||||||
|
import io
|
||||||
import shutil
|
import shutil
|
||||||
import subprocess
|
import subprocess
|
||||||
import threading
|
import threading
|
||||||
@@ -23,22 +24,23 @@ SEGMENT_COUNT = 5 # segments to keep in playlist
|
|||||||
BITRATE = 2_000_000 # 2 Mbps — adjust for bandwidth needs
|
BITRATE = 2_000_000 # 2 Mbps — adjust for bandwidth needs
|
||||||
|
|
||||||
|
|
||||||
class PipeOutput:
|
class PipeOutput(io.RawIOBase):
|
||||||
"""Accepts H.264 bytes from picamera2 and writes to a subprocess stdin pipe."""
|
"""Wraps ffmpeg stdin pipe as a BufferedIOBase-compatible stream."""
|
||||||
|
|
||||||
def __init__(self, proc: subprocess.Popen[bytes]) -> None:
|
def __init__(self, proc: subprocess.Popen[bytes]) -> None:
|
||||||
self._proc = proc
|
self._proc = proc
|
||||||
|
|
||||||
def write(self, data: bytes) -> None:
|
def write(self, data: bytes) -> int: # type: ignore[override]
|
||||||
if self._proc.stdin:
|
if self._proc.stdin and not self._proc.stdin.closed:
|
||||||
try:
|
try:
|
||||||
self._proc.stdin.write(data)
|
self._proc.stdin.write(data)
|
||||||
|
return len(data)
|
||||||
except BrokenPipeError:
|
except BrokenPipeError:
|
||||||
pass
|
pass
|
||||||
|
return 0
|
||||||
|
|
||||||
def close(self) -> None:
|
def writable(self) -> bool:
|
||||||
if self._proc.stdin:
|
return True
|
||||||
self._proc.stdin.close()
|
|
||||||
|
|
||||||
|
|
||||||
class Camera:
|
class Camera:
|
||||||
@@ -104,7 +106,8 @@ class Camera:
|
|||||||
)
|
)
|
||||||
self._picam.configure(config)
|
self._picam.configure(config)
|
||||||
self._encoder = H264Encoder(bitrate=BITRATE)
|
self._encoder = H264Encoder(bitrate=BITRATE)
|
||||||
self._picam.start_recording(self._encoder, FileOutput(self._output))
|
buffered = io.BufferedWriter(self._output)
|
||||||
|
self._picam.start_recording(self._encoder, FileOutput(buffered))
|
||||||
|
|
||||||
# watch for the playlist to appear — signals first segment is ready
|
# watch for the playlist to appear — signals first segment is ready
|
||||||
self._stop_event.clear()
|
self._stop_event.clear()
|
||||||
@@ -145,6 +148,9 @@ class Camera:
|
|||||||
if self._output:
|
if self._output:
|
||||||
self._output.close()
|
self._output.close()
|
||||||
|
|
||||||
|
if self._ffmpeg and self._ffmpeg.stdin:
|
||||||
|
self._ffmpeg.stdin.close()
|
||||||
|
|
||||||
if self._ffmpeg:
|
if self._ffmpeg:
|
||||||
try:
|
try:
|
||||||
self._ffmpeg.wait(timeout=5)
|
self._ffmpeg.wait(timeout=5)
|
||||||
|
|||||||
Reference in New Issue
Block a user