import numpy as np import gradio as gr import spaces from fastrtc import WebRTC, get_turn_credentials @spaces.GPU def flip_frame_handler(video_frame): """ Flips the incoming video frame vertically and yields it. This needs to be a generator function because the output is a receive-only stream. """ if video_frame: yield np.flip(video_frame, axis=0) # --- Gradio UI Layout --- with gr.Blocks(theme=gr.themes.Soft(), title="FastRTC Webcam Frame Flipper") as demo: gr.Markdown("# 🚀 FastRTC Webcam Frame Flipper (Side-by-Side)") gr.Markdown("*This demo takes your webcam feed from the left panel, flips each frame vertically on the server, and streams it back to the right panel in real-time.*") with gr.Row(): with gr.Column(): gr.Markdown("### 1. Your Webcam Feed (Input)") # This component only sends video to the server webcam_input = WebRTC( label="Webcam Input", modality="video", mode="send", rtc_configuration=get_turn_credentials(), ) with gr.Column(): gr.Markdown("### 2. Flipped Video (Output)") # This component only receives video from the server video_output = WebRTC( label="Flipped Output Stream", modality="video", mode="receive", rtc_configuration=get_turn_credentials(), ) # The `stream` event is triggered by the input component webcam_input.stream( fn=flip_frame_handler, inputs=[webcam_input], # Input is the webcam feed outputs=[video_output], # Output is the separate receive-only component time_limit=60, ) if __name__ == "__main__": demo.queue().launch()