Ir al contenido

Subir un video

Un job parte de una fuente: un archivo que subes, o uno en una URL que el job copia. En los dos casos se convierte en una subida (upload) de tu organización, que otros jobs pueden reutilizar durante 7 días sin enviarla de nuevo. Después se borra.

POST /v1/uploads
{ "file_name": "video.mov", "content_type": "video/quicktime", "size": 2176298566 }
Campo
file_name Se muestra en el panel.
content_type Se envía otra vez como Content-Type en cada PUT. Por defecto application/octet-stream.
size En bytes. Hasta el tamaño máximo de tu plan (por encima, 402 quota_exceeded).
progressive true para una subida progresiva.

El mode de la respuesta dice cómo enviar el archivo. Las URLs de subida duran una hora.

mode: "single". Haz PUT del archivo entero a url, con las headers indicadas, y complétala:

Ventana de terminal
curl -X PUT "$URL" -H "Content-Type: video/quicktime" --data-binary @video.mov
curl -X POST https://api.iomza.com/v1/uploads/$ID/complete -H "Authorization: Bearer $IOMZA_API_KEY"

mode: "multipart". El archivo se corta en partes de part_size bytes (la última, más corta), y parts trae una URL para cada una. Haz PUT de cada parte, varias a la vez si quieres, y guarda la cabecera ETag de cada respuesta. Después completa la subida con todas las partes:

POST /v1/uploads/{id}/complete
{ "parts": [{ "part_number": 1, "etag": "\"9b2cf535f27731c974343645a3985328\"" }, { "part_number": 2, "etag": "\"…\"" }] }

Si las URLs caducan antes de terminar, pide nuevas para las partes que faltan:

POST /v1/uploads/{id}/parts
{ "part_numbers": [7, 8] }

Una parte que falla se puede enviar otra vez a la misma URL. Completar dos veces no hace daño: la segunda llamada devuelve la subida tal como está.

Con "progressive": true, cada parte es un objeto propio, legible en cuanto llega, y no hay complete. Crea el job en cuanto empieces a subir (input.upload_id): se transcodifica mientras llega el archivo, así que la espera tras el último byte es una fracción de la de un job normal.

  • Haz PUT de cada parte con las headers indicadas.
  • Envía primero la primera y la última parte (los contenedores guardan ahí su cabecera e índice) y luego el resto en orden.
  • La tarea upload del job muestra lo recibido (bytes / total_bytes).
  • Si no llega nada en 30 minutos, el job falla con upload_incomplete.
  • Si el job falla antes de que termines (por ejemplo, el archivo no se puede leer), deja de subir: el resto no se usará. Atiende el webhook job.failed o consulta el job.
  • Hasta completarse, la subida solo alimenta a su propio job; después, otros jobs pueden usarla como cualquier otra.

Así es como sube el panel.

En vez de subir, crea el job con "input": { "url": "https://…" }. El job copia primero el video; su tarea import muestra el avance. Cuando el servidor acepta rangos de bytes (S3, Google Cloud Storage, Azure, CDNs y casi cualquier servidor web), la copia es rápida y el video se transcodifica mientras se descarga; si no, se copia entero y luego se procesa.

La URL debe:

  • ser https, pública o prefirmada (una prefirmada debe seguir válida hasta que termine la copia);
  • llegar al archivo en como mucho 5 redirecciones; las direcciones privadas e internas se rechazan;
  • apuntar a un archivo no mayor que el máximo de tu plan.

Para buckets de S3 cuyo nombre lleva puntos, usa la URL con la ruta (https://s3.<región>.amazonaws.com/<bucket>/<clave>): la de subdominio no coincide con el certificado del bucket.

La copia se convierte en una subida (mode: "url") que otros jobs pueden usar por upload_id durante 7 días. Si falla, el job termina con source_import_failed y el motivo (HTTP 404, tiempo agotado, demasiado grande…).

Para elegir pistas de audio o subtítulos, o rechazar un archivo a tiempo, lee qué contiene una fuente. Solo se lee su cabecera: un segundo aproximadamente, incluso para 20 GB.

GET /v1/uploads/{id}/tracks
POST /v1/probe { "url": "https://…" }
{
"object": "source_tracks",
"duration": 7216.8,
"bitrate": 21129954,
"video": { "codec": "hevc", "width": 3840, "height": 1600, "frame_rate": 24, "interlaced": false, "hdr": "pq", "unsupported": null },
"audio_tracks": [
{ "index": 0, "language": "spa", "title": null, "codec": "eac3", "channels": 8, "default": true, "atmos": false, "bitrate": 768000 },
{ "index": 1, "language": "eng", "title": null, "codec": "eac3", "channels": 6, "default": false, "atmos": true, "bitrate": 640000 }
],
"subtitle_tracks": [
{ "index": 0, "language": "spa", "title": null, "codec": "subrip", "default": true, "forced": true, "convertible": true }
]
}
  • video.hdr: pq (HDR10 y Dolby Vision) o hlg. Las fuentes HDR se convierten a SDR, que toda pantalla muestra bien.
  • video.unsupported: un video que no podemos procesar, para que lo rechaces antes de que alguien espere un job. Hoy el único caso es dolby_vision_no_compatible_layer: Dolby Vision perfiles 5 y 20, cuyos colores no se pueden reproducir con fidelidad. Expórtalos como HDR10, HLG, SDR o Dolby Vision perfil 8.
  • subtitle_tracks[].convertible: los subtítulos de texto (SRT, ASS, WebVTT, mov_text…) se convierten a WebVTT; los de imagen (PGS, VobSub), no.

Cualquier contenedor y códec habitual: MP4, MOV, MKV, WebM, AVI, MPEG-TS, MXF…, con H.264, HEVC, ProRes, VP9, AV1, MPEG-2 y otros. El video entrelazado se desentrelaza, las frecuencias variables se estabilizan, se aplica la rotación de los móviles y se corrigen los píxeles anamórficos: los adjustments del job dicen qué se hizo.