Ir al contenido

Sube archivos y añade pistas

El SDK local 0.1.30 ofrece dos recorridos: video principal con una URL de capacidad para el navegador, y pistas adjuntas con helpers de servidor Node.js 22 o posterior. Conserva los IDs de sesión y el archivo original para recuperar interrupciones.

Tu backend crea una subida y guarda su ID:

const upload = await orilla.uploads.create({
cors_origin: "https://app.example",
new_asset_settings: {
playback_policies: ["signed"],
meta: { title: "Mi video" },
},
});
// Entrega upload.url al navegador; guarda upload.id en tu backend.

En el navegador, usa únicamente esa URL temporal y el archivo seleccionado:

import { uploadFile } from "@orilla/sdk/upload";
await uploadFile(uploadURL, file, {
signal: abortController.signal,
onProgress: (bytes, total) => console.log(bytes, total),
});

uploadURL viene del backend, file de un control de archivo y abortController es un AbortController de tu interfaz. El helper consulta el offset y envía fragmentos de 8 MiB por defecto. Tras un fallo puede repetirse con la misma URL y el mismo original; no verifica que los bytes del prefijo ya enviado correspondan a otro archivo elegido por error.

No entregues credenciales administrativas al navegador. Terminar la transferencia no significa que el asset esté listo: consulta uploads.retrieve(upload.id) hasta obtener asset_id y después el estado del asset, o usa webhooks.

En un video o audio listo, abre Subtítulos y capítulos → Añadir pista → Archivo. Selecciona SRT/WebVTT UTF-8 de 1 byte a 5 MiB, tipo, idioma y nombre. Los capítulos usan WebVTT; CC solo se admite para subtítulos. La opción URL sigue disponible.

Una pista inválida falla de forma independiente. Cerrar detiene el trabajo local y conserva una sesión ya aceptada; Subida pendiente → Reanudar subida pide el mismo archivo y verifica nombre, tamaño y SHA-256. Reintentar confirmación recupera el cierre sin repetir el archivo. Cancelar retira solo la pista. Los lectores consultan sin gestionar subidas.

Con orilla configurado en tu backend y assetId de un contenido listo:

import { randomUUID } from "node:crypto";
import { readFile, writeFile } from "node:fs/promises";
const original = await readFile("es.vtt");
const idempotencyKey = randomUUID();
await writeFile("text-request-id.txt", idempotencyKey, { mode: 0o600 });
const result = await orilla.trackUploads.uploadText(
assetId,
original,
{
filename: "es.vtt",
contentType: "text/vtt",
text_type: "subtitles",
language_code: "es",
name: "Español",
},
{
idempotencyKey,
onSession: async (session) => {
await writeFile("text-upload-id.txt", session.uploadId, { mode: 0o600 });
},
},
);
console.log(result.trackId, result.status);

En producción, guarda el UUID y la sesión en tu almacén durable. Reutiliza el UUID al recuperar una reserva sin respuesta. Con el ID persistido y el mismo original:

const uploadId = (await readFile("text-upload-id.txt", "utf8")).trim();
await orilla.trackUploads.resumeText(uploadId, original, {
filename: "es.vtt",
});

Para archivos grandes, usa un Blob respaldado por archivo en tu backend:

import { openAsBlob } from "node:fs";
import { randomUUID } from "node:crypto";
import { writeFile } from "node:fs/promises";
const original = await openAsBlob("es.wav");
const idempotencyKey = randomUUID();
await writeFile("audio-request-id.txt", idempotencyKey, { mode: 0o600 });
const result = await orilla.trackUploads.uploadAudio(
assetId,
original,
{
filename: "es.wav",
contentType: "audio/wav",
language_code: "es",
name: "Español",
},
{
idempotencyKey,
onSession: async (session) => {
await writeFile("audio-upload-id.txt", session.uploadId, { mode: 0o600 });
},
},
);
console.log(result.trackId, result.status);

resumeAudio(uploadId, original, { filename: 'es.wav' }) retoma con el ID persistido. El helper admite Blob/Uint8Array de 1 byte a 5 GiB, calcula SHA-256 completo y transfiere partes secuencialmente. El panel usa una huella distinta para audio: no se promete reanudación cruzada entre panel y SDK. Hay hasta diez audios adicionales por asset; se requiere audio principal y los nombres del grupo deben ser únicos.

Los helpers de pistas devuelven status: 'completed' cuando la subida fue aceptada. Consulta assets.retrieve(assetId).tracks para seguir ready o errored. El estado del contenido principal no se reinicia.

onSession y onProgress pueden ser asíncronos; el SDK espera su resolución. Progreso cuenta bytes aceptados, no avance del worker, y puede llegar al total antes de fallar la confirmación. signal aborta el trabajo local y conserva la sesión. Cancelar exige trackUploads.cancel(uploadId).

No hay reintentos automáticos en segundo plano. timeoutMs limita cada petición; un fetch en las opciones del helper sustituye solo almacenamiento. No añadas Authorization Basic globalmente a un wrapper: S3 recibe únicamente la capacidad firmada, sin cookies ni credenciales administrativas. Se rechazan redirecciones. Las API de bajo nivel createText, createAudio, retrieve, prepare, sign, complete y cancel siguen disponibles.