File size: 3,578 Bytes
236ab38
d0b0e4e
 
5e4718f
d0b0e4e
5e4718f
236ab38
5e4718f
d0b0e4e
 
5e4718f
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
d0b0e4e
 
5e4718f
 
 
 
 
 
 
d0b0e4e
 
5e4718f
6cd26b2
5e4718f
 
 
 
 
 
236ab38
5e4718f
 
 
 
 
 
 
 
 
 
 
 
 
 
a7b3ae3
5e4718f
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
236ab38
5e4718f
 
d0b0e4e
5e4718f
d0b0e4e
0dd1a29
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
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
import gradio as gr
from fastapi import FastAPI, Request
from starlette.responses import JSONResponse
import subprocess
import uvicorn
import threading

# Inicializar la aplicaci贸n FastAPI
app = FastAPI()

# Estado para almacenar el proceso de FFmpeg
app.state.ffmpeg_process = None

# Funci贸n para iniciar FFmpeg
def start_ffmpeg(rtmp_server, stream_key):
    # Comando FFmpeg para recibir video desde stdin y transmitir a RTMP
    command = [
        "ffmpeg",
        "-re",
        "-i", "-",  # Leer desde stdin
        "-c:v", "libx264",
        "-b:v", "1000k",
        "-f", "flv",
        f"{rtmp_server}/{stream_key}"
    ]
    process = subprocess.Popen(command, stdin=subprocess.PIPE)
    return process

# Ruta de FastAPI para recibir el stream de video
@app.post("/save_stream")
async def save_stream(request: Request):
    data = await request.body()
    if app.state.ffmpeg_process:
        try:
            app.state.ffmpeg_process.stdin.write(data)
            app.state.ffmpeg_process.stdin.flush()
        except BrokenPipeError:
            return JSONResponse({"status": "ffmpeg process not available"}, status_code=500)
    return JSONResponse({"status": "ok"})

# Funci贸n de Gradio para iniciar la transmisi贸n
def start_streaming(rtmp_server, stream_key):
    if app.state.ffmpeg_process is None:
        process = start_ffmpeg(rtmp_server, stream_key)
        app.state.ffmpeg_process = process
        return "Transmisi贸n en vivo iniciada"
    else:
        return "La transmisi贸n ya est谩 en curso"

# Crear la interfaz de Gradio
with gr.Blocks() as demo:
    gr.Markdown("# Transmisi贸n en Vivo")
    
    with gr.Row():
        rtmp_server = gr.Textbox(label="Servidor RTMP (YouTube, Twitch, etc.)", placeholder="rtmp://servidor/live", lines=1)
        stream_key = gr.Textbox(label="Clave de transmisi贸n", placeholder="Ingresa tu clave de transmisi贸n", type="password", lines=1)
    
    start_button = gr.Button("Iniciar Transmisi贸n")
    output = gr.Textbox(label="Estado", interactive=False)
    
    start_button.click(start_streaming, inputs=[rtmp_server, stream_key], outputs=output)
    
    # Agregar HTML y JavaScript para capturar la pantalla
    gr.HTML("""
    <video id="screenPreview" style="display:none;"></video>
    <button onclick="startScreenCapture()">Compartir Pantalla</button>
    <script>
    async function startScreenCapture() {
        try {
            const stream = await navigator.mediaDevices.getDisplayMedia({
                video: { cursor: "always" },
                audio: false
            });
    
            const videoElement = document.getElementById('screenPreview');
            if (videoElement) {
                videoElement.srcObject = stream;
                videoElement.play();
            }
    
            const mediaRecorder = new MediaRecorder(stream, { mimeType: 'video/webm; codecs=vp8' });
            mediaRecorder.ondataavailable = function(event) {
                if (event.data.size > 0) {
                    fetch('/save_stream', {
                        method: 'POST',
                        body: event.data
                    });
                }
            };
            mediaRecorder.start(1000); // Enviar datos cada segundo
        } catch (err) {
            console.error("Error capturando pantalla: ", err);
        }
    }
    </script>
    """)

# Montar la aplicaci贸n de Gradio en FastAPI
app = gr.mount_gradio_app(app, demo, path="/")

# Ejecutar la aplicaci贸n con Uvicorn
if __name__ == "__main__":
    uvicorn.run(app, host="0.0.0.0", port=7860)