Spaces:
Running
on
Zero
Running
on
Zero
File size: 2,745 Bytes
6f9faf9 5f82f10 379cab9 5f82f10 6f9faf9 77185d8 5f82f10 7e0b27a 5f82f10 7e0b27a 5f82f10 ee11946 77185d8 5f82f10 6f9faf9 5f82f10 ee11946 77185d8 ee11946 6f9faf9 77185d8 7e0b27a ee11946 7e0b27a 77185d8 6f9faf9 77185d8 7e0b27a 6f9faf9 ee11946 bd6580c 6f9faf9 5f82f10 77185d8 5f82f10 c551a63 77185d8 6f9faf9 7e0b27a |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 |
import gradio as gr
import numpy as np
import spaces
from fastrtc import WebRTC, get_turn_credentials
# This is the core processing function that will be assigned to the GPU.
# It receives a generator (`frame_stream`) that yields frames from the webcam
# and it yields processed frames back to the output component.
@spaces.GPU
def process_frames_on_gpu(frame_stream):
"""
This function runs as a persistent process on the GPU.
It iterates over incoming frames, processes them, and yields the results.
"""
print("🚀 GPU Frame processing loop started.")
if frame_stream is None:
print("Input stream is None, ending.")
return
# This loop will block until a new frame is available, making it reactive.
for frame in frame_stream:
if frame is not None:
# This is where your GPU-intensive work would happen.
flipped_frame = np.flip(frame, axis=(0, 1))
# Yield the processed frame to the output stream.
yield flipped_frame
print("🛑 GPU Frame processing loop finished.")
# --- Gradio UI Layout ---
with gr.Blocks(theme=gr.themes.Soft(), title="FastRTC ZeroGPU Flipper") as demo:
gr.Markdown("# 🚀 FastRTC Webcam Flipper for ZeroGPU")
gr.Markdown(
"*This version uses a separate button to trigger the stream, correctly using Gradio's streaming iterator pattern for ZeroGPU without conflicting with the `fastrtc` component's internal logic.*"
)
with gr.Row():
with gr.Column(scale=1):
gr.Markdown("### 1. Your Webcam Feed (Input)")
webcam_input = WebRTC(
label="Webcam Input",
modality="video",
mode="send",
width=640,
height=480,
rtc_configuration=get_turn_credentials(),
)
start_button = gr.Button("🚀 Start Processing Stream", variant="primary")
with gr.Column(scale=1):
gr.Markdown("### 2. Flipped Video (Output)")
video_output = WebRTC(
label="Flipped Output Stream",
modality="video",
mode="receive",
width=640,
height=480,
rtc_configuration=get_turn_credentials(),
)
# By using a button's `click` event to start the stream, we use Gradio's
# standard streaming API, which correctly provides the iterator to our
# decorated function without causing a conflict.
start_button.click(
fn=process_frames_on_gpu,
inputs=[webcam_input],
outputs=[video_output]
)
if __name__ == "__main__":
demo.queue().launch() |