576 lines
12 KiB
Markdown
576 lines
12 KiB
Markdown
# 🐳 Comandos Docker - Ejecución por Separado
|
||
|
||
## 📋 Índice
|
||
|
||
1. [Ejecutar Servicios por Separado](#ejecutar-servicios-por-separado)
|
||
2. [Uso del Endpoint /stream/](#uso-del-endpoint-stream)
|
||
3. [Comandos FFmpeg con RTMP](#comandos-ffmpeg-con-rtmp)
|
||
4. [Flujo Completo](#flujo-completo)
|
||
|
||
---
|
||
|
||
## 🚀 Ejecutar Servicios por Separado
|
||
|
||
### 1️⃣ Solo API FastAPI (Backend)
|
||
|
||
```bash
|
||
# Construir imagen
|
||
docker build -t tubescript-api .
|
||
|
||
# Ejecutar solo la API
|
||
docker run -d \
|
||
--name tubescript_api \
|
||
-p 8080:8000 \
|
||
-v $(pwd)/cookies.txt:/app/cookies.txt:ro \
|
||
tubescript-api
|
||
|
||
# Ver logs
|
||
docker logs -f tubescript_api
|
||
|
||
# Detener
|
||
docker stop tubescript_api
|
||
docker rm tubescript_api
|
||
```
|
||
|
||
**Acceder:**
|
||
- API: http://localhost:8080
|
||
- Docs: http://localhost:8080/docs
|
||
- Endpoint stream: http://localhost:8080/stream/VIDEO_ID
|
||
|
||
---
|
||
|
||
### 2️⃣ Solo Panel Streamlit (Frontend)
|
||
|
||
```bash
|
||
# Construir imagen (si no está construida)
|
||
docker build -t tubescript-streamlit .
|
||
|
||
# Ejecutar solo Streamlit
|
||
docker run -d \
|
||
--name streamlit_panel \
|
||
-p 8501:8501 \
|
||
-v $(pwd)/cookies.txt:/app/cookies.txt:ro \
|
||
-v $(pwd)/stream_config.json:/app/stream_config.json \
|
||
-v $(pwd)/streams_state.json:/app/streams_state.json \
|
||
-e API_URL=http://host.docker.internal:8080 \
|
||
streamlit run streamlit_app.py --server.port=8501 --server.address=0.0.0.0 --server.headless=true
|
||
|
||
# Ver logs
|
||
docker logs -f streamlit_panel
|
||
|
||
# Detener
|
||
docker stop streamlit_panel
|
||
docker rm streamlit_panel
|
||
```
|
||
|
||
**Acceder:**
|
||
- Panel: http://localhost:8501
|
||
|
||
**Nota:** Usa `host.docker.internal` para que Streamlit pueda conectarse a la API si ambos corren por separado.
|
||
|
||
---
|
||
|
||
### 3️⃣ Ambos Servicios (con docker-compose)
|
||
|
||
```bash
|
||
# Construir
|
||
docker-compose build
|
||
|
||
# Iniciar ambos
|
||
docker-compose up -d
|
||
|
||
# Ver logs de ambos
|
||
docker-compose logs -f
|
||
|
||
# Ver logs de uno solo
|
||
docker-compose logs -f streamlit-panel
|
||
docker-compose logs -f tubescript-api
|
||
|
||
# Detener ambos
|
||
docker-compose down
|
||
```
|
||
|
||
---
|
||
|
||
## 📡 Uso del Endpoint /stream/
|
||
|
||
### Obtener URL m3u8 de un Video en Vivo
|
||
|
||
#### Método 1: cURL
|
||
|
||
```bash
|
||
# Obtener stream URL
|
||
curl http://localhost:8080/stream/VIDEO_ID
|
||
|
||
# Ejemplo con video real
|
||
curl http://localhost:8080/stream/dQw4w9WgXcQ
|
||
```
|
||
|
||
**Respuesta:**
|
||
```json
|
||
{
|
||
"video_id": "dQw4w9WgXcQ",
|
||
"stream_url": "https://manifest.googlevideo.com/api/manifest/hls_playlist/...",
|
||
"url_type": "m3u8/hls",
|
||
"youtube_url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ",
|
||
"ffmpeg_example": "ffmpeg -re -i \"URL\" -c copy -f flv rtmp://destino/stream_key",
|
||
"usage": {
|
||
"description": "Usa stream_url con FFmpeg para retransmitir",
|
||
"command_template": "ffmpeg -re -i \"{stream_url}\" -c copy -f flv {rtmp_url}/{stream_key}",
|
||
"platforms": {
|
||
"youtube": "rtmp://a.rtmp.youtube.com/live2/YOUR_STREAM_KEY",
|
||
"facebook": "rtmps://live-api-s.facebook.com:443/rtmp/YOUR_STREAM_KEY",
|
||
...
|
||
}
|
||
}
|
||
}
|
||
```
|
||
|
||
#### Método 2: Python
|
||
|
||
```python
|
||
import requests
|
||
|
||
# Obtener stream URL
|
||
video_id = "VIDEO_ID"
|
||
response = requests.get(f"http://localhost:8080/stream/{video_id}")
|
||
data = response.json()
|
||
|
||
stream_url = data["stream_url"]
|
||
print(f"URL m3u8: {stream_url}")
|
||
```
|
||
|
||
#### Método 3: JavaScript/Node.js
|
||
|
||
```javascript
|
||
// Obtener stream URL
|
||
const videoId = "VIDEO_ID";
|
||
const response = await fetch(`http://localhost:8080/stream/${videoId}`);
|
||
const data = await response.json();
|
||
|
||
console.log("URL m3u8:", data.stream_url);
|
||
```
|
||
|
||
---
|
||
|
||
## 🎬 Comandos FFmpeg con RTMP
|
||
|
||
### Flujo Básico
|
||
|
||
1. **Obtener URL m3u8** desde el endpoint `/stream/`
|
||
2. **Usar FFmpeg** para retransmitir a RTMP
|
||
|
||
### Template General
|
||
|
||
```bash
|
||
ffmpeg -re \
|
||
-i "URL_M3U8_DEL_ENDPOINT" \
|
||
-c copy \
|
||
-f flv \
|
||
RTMP_URL/STREAM_KEY
|
||
```
|
||
|
||
---
|
||
|
||
### Ejemplo 1: Transmitir a YouTube
|
||
|
||
```bash
|
||
# 1. Obtener URL m3u8
|
||
VIDEO_ID="dQw4w9WgXcQ"
|
||
STREAM_URL=$(curl -s http://localhost:8080/stream/$VIDEO_ID | jq -r '.stream_url')
|
||
|
||
# 2. Transmitir a YouTube
|
||
ffmpeg -re \
|
||
-i "$STREAM_URL" \
|
||
-c copy \
|
||
-f flv \
|
||
rtmp://a.rtmp.youtube.com/live2/TU_STREAM_KEY_YOUTUBE
|
||
```
|
||
|
||
---
|
||
|
||
### Ejemplo 2: Transmitir a Facebook
|
||
|
||
```bash
|
||
# 1. Obtener URL m3u8
|
||
VIDEO_ID="VIDEO_EN_VIVO"
|
||
STREAM_URL=$(curl -s http://localhost:8080/stream/$VIDEO_ID | jq -r '.stream_url')
|
||
|
||
# 2. Transmitir a Facebook
|
||
ffmpeg -re \
|
||
-i "$STREAM_URL" \
|
||
-c copy \
|
||
-f flv \
|
||
rtmps://live-api-s.facebook.com:443/rtmp/TU_STREAM_KEY_FACEBOOK
|
||
```
|
||
|
||
---
|
||
|
||
### Ejemplo 3: Transmitir a Twitch
|
||
|
||
```bash
|
||
# 1. Obtener URL m3u8
|
||
VIDEO_ID="VIDEO_EN_VIVO"
|
||
STREAM_URL=$(curl -s http://localhost:8080/stream/$VIDEO_ID | jq -r '.stream_url')
|
||
|
||
# 2. Transmitir a Twitch
|
||
ffmpeg -re \
|
||
-i "$STREAM_URL" \
|
||
-c copy \
|
||
-f flv \
|
||
rtmp://live.twitch.tv/app/TU_STREAM_KEY_TWITCH
|
||
```
|
||
|
||
---
|
||
|
||
### Ejemplo 4: Transmitir a X (Twitter)
|
||
|
||
```bash
|
||
# 1. Obtener URL m3u8
|
||
VIDEO_ID="VIDEO_EN_VIVO"
|
||
STREAM_URL=$(curl -s http://localhost:8080/stream/$VIDEO_ID | jq -r '.stream_url')
|
||
|
||
# 2. Transmitir a Twitter/X
|
||
ffmpeg -re \
|
||
-i "$STREAM_URL" \
|
||
-c copy \
|
||
-f flv \
|
||
rtmps://fa.contribute.live-video.net/app/TU_STREAM_KEY_TWITTER
|
||
```
|
||
|
||
---
|
||
|
||
### Ejemplo 5: Transmitir a Múltiples Plataformas Simultáneamente
|
||
|
||
```bash
|
||
# 1. Obtener URL m3u8
|
||
VIDEO_ID="VIDEO_EN_VIVO"
|
||
STREAM_URL=$(curl -s http://localhost:8080/stream/$VIDEO_ID | jq -r '.stream_url')
|
||
|
||
# 2. Transmitir a YouTube
|
||
ffmpeg -re -i "$STREAM_URL" -c copy -f flv \
|
||
rtmp://a.rtmp.youtube.com/live2/YOUTUBE_KEY &
|
||
|
||
# 3. Transmitir a Facebook
|
||
ffmpeg -re -i "$STREAM_URL" -c copy -f flv \
|
||
rtmps://live-api-s.facebook.com:443/rtmp/FACEBOOK_KEY &
|
||
|
||
# 4. Transmitir a Twitch
|
||
ffmpeg -re -i "$STREAM_URL" -c copy -f flv \
|
||
rtmp://live.twitch.tv/app/TWITCH_KEY &
|
||
|
||
# Esperar a que todos terminen
|
||
wait
|
||
```
|
||
|
||
---
|
||
|
||
## 🔄 Flujo Completo
|
||
|
||
### Opción A: Usando la API Manualmente
|
||
|
||
```bash
|
||
# 1. Iniciar solo la API
|
||
docker run -d --name tubescript_api -p 8080:8000 \
|
||
-v $(pwd)/cookies.txt:/app/cookies.txt:ro \
|
||
tubescript-api
|
||
|
||
# 2. Obtener URL m3u8 de un video en vivo
|
||
VIDEO_ID="VIDEO_EN_VIVO"
|
||
curl http://localhost:8080/stream/$VIDEO_ID > stream_data.json
|
||
|
||
# 3. Extraer la URL
|
||
STREAM_URL=$(cat stream_data.json | jq -r '.stream_url')
|
||
echo "URL m3u8: $STREAM_URL"
|
||
|
||
# 4. Transmitir con FFmpeg a YouTube
|
||
ffmpeg -re -i "$STREAM_URL" -c copy -f flv \
|
||
rtmp://a.rtmp.youtube.com/live2/TU_STREAM_KEY
|
||
|
||
# 5. Detener API cuando termines
|
||
docker stop tubescript_api
|
||
```
|
||
|
||
---
|
||
|
||
### Opción B: Usando el Panel Streamlit
|
||
|
||
```bash
|
||
# 1. Iniciar API
|
||
docker run -d --name tubescript_api -p 8080:8000 \
|
||
-v $(pwd)/cookies.txt:/app/cookies.txt:ro \
|
||
tubescript-api
|
||
|
||
# 2. Iniciar Streamlit
|
||
docker run -d --name streamlit_panel -p 8501:8501 \
|
||
-v $(pwd)/cookies.txt:/app/cookies.txt:ro \
|
||
-v $(pwd)/stream_config.json:/app/stream_config.json \
|
||
-v $(pwd)/streams_state.json:/app/streams_state.json \
|
||
-e API_URL=http://host.docker.internal:8080 \
|
||
tubescript-streamlit \
|
||
streamlit run streamlit_app.py --server.port=8501 --server.address=0.0.0.0
|
||
|
||
# 3. Abrir panel
|
||
open http://localhost:8501
|
||
|
||
# 4. Usar la interfaz gráfica para configurar y transmitir
|
||
|
||
# 5. Detener cuando termines
|
||
docker stop streamlit_panel tubescript_api
|
||
```
|
||
|
||
---
|
||
|
||
### Opción C: Usando docker-compose
|
||
|
||
```bash
|
||
# 1. Iniciar ambos servicios
|
||
docker-compose up -d
|
||
|
||
# 2. Opción A: Usar el panel web
|
||
open http://localhost:8501
|
||
|
||
# 2. Opción B: Usar la API directamente
|
||
curl http://localhost:8080/stream/VIDEO_ID
|
||
|
||
# 3. Detener
|
||
docker-compose down
|
||
```
|
||
|
||
---
|
||
|
||
## 🧪 Testing Individual
|
||
|
||
### Test 1: Probar Solo la API
|
||
|
||
```bash
|
||
# Iniciar API
|
||
docker run -d --name test_api -p 8080:8000 tubescript-api
|
||
|
||
# Probar endpoint de salud
|
||
curl http://localhost:8080/
|
||
|
||
# Probar endpoint de stream
|
||
curl http://localhost:8080/stream/dQw4w9WgXcQ
|
||
|
||
# Ver logs
|
||
docker logs test_api
|
||
|
||
# Limpiar
|
||
docker stop test_api && docker rm test_api
|
||
```
|
||
|
||
---
|
||
|
||
### Test 2: Probar Solo Streamlit
|
||
|
||
```bash
|
||
# Iniciar Streamlit (sin API)
|
||
docker run -d --name test_streamlit -p 8501:8501 \
|
||
tubescript-streamlit \
|
||
streamlit run streamlit_app.py --server.port=8501 --server.address=0.0.0.0
|
||
|
||
# Abrir en navegador
|
||
open http://localhost:8501
|
||
|
||
# Ver logs
|
||
docker logs test_streamlit
|
||
|
||
# Limpiar
|
||
docker stop test_streamlit && docker rm test_streamlit
|
||
```
|
||
|
||
---
|
||
|
||
### Test 3: Probar FFmpeg Localmente (Sin Docker)
|
||
|
||
```bash
|
||
# 1. Obtener URL m3u8 manualmente
|
||
yt-dlp -g -f best "https://www.youtube.com/watch?v=VIDEO_EN_VIVO"
|
||
|
||
# 2. Copiar la URL obtenida
|
||
|
||
# 3. Probar transmisión de 10 segundos a YouTube
|
||
ffmpeg -re -t 10 \
|
||
-i "URL_M3U8_COPIADA" \
|
||
-c copy \
|
||
-f flv \
|
||
rtmp://a.rtmp.youtube.com/live2/TU_STREAM_KEY
|
||
```
|
||
|
||
---
|
||
|
||
## 📊 Resumen de Puertos
|
||
|
||
| Servicio | Puerto Host | Puerto Container | URL |
|
||
|----------|-------------|------------------|-----|
|
||
| FastAPI | 8080 | 8000 | http://localhost:8080 |
|
||
| Streamlit | 8501 | 8501 | http://localhost:8501 |
|
||
|
||
---
|
||
|
||
## 🔧 Variables de Entorno
|
||
|
||
### Para Streamlit:
|
||
|
||
```bash
|
||
-e API_URL=http://host.docker.internal:8080 # Conectar a API en host
|
||
-e API_URL=http://tubescript-api:8000 # Conectar a API en Docker network
|
||
```
|
||
|
||
### Para API:
|
||
|
||
```bash
|
||
-e PYTHONUNBUFFERED=1 # Logs en tiempo real
|
||
-e PYTHONIOENCODING=utf-8 # Encoding correcto
|
||
```
|
||
|
||
---
|
||
|
||
## 🎯 Casos de Uso Prácticos
|
||
|
||
### Caso 1: Desarrollo Local de la API
|
||
|
||
```bash
|
||
# Solo API para desarrollo
|
||
docker run -d --name dev_api -p 8080:8000 \
|
||
-v $(pwd):/app \
|
||
-v $(pwd)/cookies.txt:/app/cookies.txt:ro \
|
||
tubescript-api
|
||
|
||
# Hacer cambios en main.py localmente
|
||
# Reiniciar para ver cambios
|
||
docker restart dev_api
|
||
```
|
||
|
||
---
|
||
|
||
### Caso 2: Testing de Streamlit con API Externa
|
||
|
||
```bash
|
||
# Streamlit apuntando a API en producción
|
||
docker run -d --name test_streamlit -p 8501:8501 \
|
||
-e API_URL=https://api-produccion.com \
|
||
tubescript-streamlit \
|
||
streamlit run streamlit_app.py --server.port=8501 --server.address=0.0.0.0
|
||
```
|
||
|
||
---
|
||
|
||
### Caso 3: Transmisión Automática con Script
|
||
|
||
```bash
|
||
#!/bin/bash
|
||
# script-transmision.sh
|
||
|
||
VIDEO_ID="VIDEO_EN_VIVO"
|
||
YOUTUBE_KEY="tu_stream_key_youtube"
|
||
FACEBOOK_KEY="tu_stream_key_facebook"
|
||
|
||
# Obtener URL m3u8
|
||
echo "Obteniendo URL m3u8..."
|
||
STREAM_URL=$(curl -s http://localhost:8080/stream/$VIDEO_ID | jq -r '.stream_url')
|
||
|
||
if [ -z "$STREAM_URL" ]; then
|
||
echo "Error: No se pudo obtener la URL"
|
||
exit 1
|
||
fi
|
||
|
||
echo "URL obtenida: $STREAM_URL"
|
||
|
||
# Transmitir a YouTube
|
||
echo "Iniciando transmisión a YouTube..."
|
||
ffmpeg -re -i "$STREAM_URL" -c copy -f flv \
|
||
rtmp://a.rtmp.youtube.com/live2/$YOUTUBE_KEY &
|
||
|
||
# Transmitir a Facebook
|
||
echo "Iniciando transmisión a Facebook..."
|
||
ffmpeg -re -i "$STREAM_URL" -c copy -f flv \
|
||
rtmps://live-api-s.facebook.com:443/rtmp/$FACEBOOK_KEY &
|
||
|
||
echo "Transmisiones iniciadas. Presiona Ctrl+C para detener."
|
||
wait
|
||
```
|
||
|
||
---
|
||
|
||
## 📚 Documentación de la API
|
||
|
||
### GET /
|
||
|
||
Endpoint de salud.
|
||
|
||
**Respuesta:**
|
||
```json
|
||
{
|
||
"message": "TubeScript API Pro is running!"
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
### GET /stream/{video_id}
|
||
|
||
Obtiene la URL m3u8 de un video en vivo de YouTube.
|
||
|
||
**Parámetros:**
|
||
- `video_id` (path): ID del video de YouTube
|
||
|
||
**Respuesta exitosa (200):**
|
||
```json
|
||
{
|
||
"video_id": "dQw4w9WgXcQ",
|
||
"stream_url": "https://manifest.googlevideo.com/...",
|
||
"url_type": "m3u8/hls",
|
||
"youtube_url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ",
|
||
"ffmpeg_example": "ffmpeg -re -i \"URL\" -c copy -f flv rtmp://destino/key",
|
||
"usage": { ... }
|
||
}
|
||
```
|
||
|
||
**Respuesta de error (400):**
|
||
```json
|
||
{
|
||
"detail": "Error de yt-dlp: ..."
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
### GET /transcript/{video_id}
|
||
|
||
Obtiene la transcripción de un video.
|
||
|
||
**Parámetros:**
|
||
- `video_id` (path): ID del video
|
||
- `lang` (query, opcional): Idioma (default: "es")
|
||
|
||
---
|
||
|
||
## 🎉 Resumen
|
||
|
||
### Comandos Esenciales:
|
||
|
||
```bash
|
||
# Solo API
|
||
docker run -d --name api -p 8080:8000 tubescript-api
|
||
|
||
# Solo Streamlit
|
||
docker run -d --name panel -p 8501:8501 \
|
||
-e API_URL=http://host.docker.internal:8080 \
|
||
tubescript-streamlit streamlit run streamlit_app.py --server.port=8501 --server.address=0.0.0.0
|
||
|
||
# Ambos (docker-compose)
|
||
docker-compose up -d
|
||
|
||
# Obtener URL m3u8
|
||
curl http://localhost:8080/stream/VIDEO_ID | jq -r '.stream_url'
|
||
|
||
# Transmitir con FFmpeg
|
||
ffmpeg -re -i "URL_M3U8" -c copy -f flv rtmp://destino/key
|
||
```
|
||
|
||
---
|
||
|
||
¡Todo listo para usar! 🚀📺
|