MCPcopy Create free account
hub / github.com/Dispatcharr/Dispatcharr / _read_stderr

Method _read_stderr

apps/proxy/live_proxy/input/manager.py:835–907  ·  view source on GitHub ↗

Read and log ffmpeg stderr output with real-time stats parsing

(self)

Source from the content-addressed store, hash-verified

833 logger.debug(f"Started stderr reader thread for channel {self.channel_id}")
834
835 def _read_stderr(self):
836 """Read and log ffmpeg stderr output with real-time stats parsing"""
837 import os as _os
838 import select as _select
839 import gevent
840
841 try:
842 stderr = self.transcode_process.stderr
843 if not stderr:
844 return
845 stderr_fd = stderr.fileno()
846 buf = b""
847
848 while self.running and self.transcode_process and self.transcode_process.stderr:
849 try:
850 ready, _, _ = _select.select([stderr_fd], [], [], 1.0)
851 if not ready:
852 if not self.running or not self.transcode_process:
853 break
854 continue
855
856 chunk = _os.read(stderr_fd, 4096)
857 if not chunk:
858 break
859
860 # Yield to the hub after each read so fetch_chunk and other
861 # greenlets can run. Without this, the byte-at-a-time loop
862 # monopolises the event loop during ffmpeg startup output,
863 # starving the data reader and preventing the buffer from filling.
864 gevent.sleep(0)
865
866 buf += chunk
867
868 while True:
869 cr = buf.find(b'\r')
870 nl = buf.find(b'\n')
871 if cr == -1 and nl == -1:
872 if len(buf) > 1024 and b"frame=" not in buf:
873 line_text = buf.decode('utf-8', errors='ignore').strip()
874 if line_text:
875 self._log_stderr_content(line_text)
876 buf = b""
877 break
878 if cr != -1 and (nl == -1 or cr < nl):
879 line, buf = buf[:cr], buf[cr + 1:]
880 else:
881 line, buf = buf[:nl], buf[nl + 1:]
882 line_text = line.decode('utf-8', errors='ignore').strip()
883 if not line_text:
884 continue
885 if "frame=" in line_text:
886 self._parse_ffmpeg_stats(line_text)
887 self._log_stderr_content(line_text)
888
889 except Exception as e:
890 logger.error(f"Error reading stderr for channel {self.channel_id}: {e}")
891 break
892

Callers

nothing calls this directly

Calls 3

_log_stderr_contentMethod · 0.95
_parse_ffmpeg_statsMethod · 0.95
readMethod · 0.80

Tested by

no test coverage detected