Spaces:
Sleeping
Sleeping
| import cv2 | |
| from .processor import MediaProcessor | |
| import subprocess | |
| class LiveStreamProcessor: | |
| def __init__(self, detector, censor): | |
| self.detector = detector | |
| self.censor = censor | |
| self.processor = MediaProcessor(detector, censor) | |
| def process_stream(self, | |
| source, | |
| output_type=None, | |
| output_dest=None, | |
| conf_thresh=0.4, | |
| preview_stream=False): | |
| capture = cv2.VideoCapture(source) | |
| if not capture.isOpened(): | |
| raise ValueError(f"Could not open video source {source}") | |
| width = int(capture.get(cv2.CAP_PROP_FRAME_WIDTH)) | |
| height = int(capture.get(cv2.CAP_PROP_FRAME_HEIGHT)) | |
| fps = int(capture.get(cv2.CAP_PROP_FPS)) | |
| output = self.initialize_output(output_type, output_dest, width, height, fps) | |
| try: | |
| while True: | |
| ret, frame = capture.read() | |
| if not ret: | |
| break | |
| detections = self.detector.detect(frame) | |
| for bbox in detections: | |
| if bbox[4] >= conf_thresh: | |
| frame = self.censor.apply(frame, bbox) | |
| if output_type == "rtmp": | |
| output.stdin.write(frame.tobytes()) | |
| else: | |
| raise ValueError(f"Invalid output_type: {output_type}, try 'rtmp'?") | |
| if preview_stream: | |
| cv2.imshow("Stream Preview", frame) | |
| if cv2.waitKey(1) & 0xFF == ord("q"): | |
| break | |
| finally: | |
| capture.release() | |
| if output: | |
| self.cleanup_output(output, output_type) | |
| cv2.destroyAllWindows() | |
| def initialize_output(self, output_type, output_dest, width, height, fps): | |
| if output_dest == None: | |
| raise ValueError("output_dest cannot be None, provide valid output destination.") | |
| if output_type == "rtmp": | |
| command = [ | |
| "ffmpeg", | |
| "-y", # Overwrite output files | |
| "-f", "rawvideo", | |
| "-vcodec", "rawvideo", | |
| "-pix_fmt", "bgr24", | |
| "-s", f"{width}x{height}", | |
| "-r", str(fps), | |
| "-i", "-", # Input from pipe | |
| "-c:v", "libx264", | |
| "-pix_fmt", "yuv420p", | |
| "-preset", "ultrafast", | |
| "-f", "flv", | |
| output_dest # RTMP URL | |
| ] | |
| return subprocess.Popen(command, stdin=subprocess.PIPE) | |
| return None | |
| def cleanup_output(self, output, output_type): | |
| if output_type == "rtmp": | |
| output.stdin.close() | |
| output.wait() | |