Almacenamiento en la nube, y por qué no solo S3
Esta página es una traducción. El texto en inglés es el que prevalece: si ambos difieren, sigue el inglés. La traducción se ofrece por comodidad. Leer esta página en inglés
Traer un catálogo
Esta es la otra mitad de «nosotros lo traemos, según un calendario, con las credenciales que nos dio el dueño»: para un bucket que el dueño ya tiene, en cualquier almacenamiento compatible con S3. No se nombra ningún proveedor en ninguna parte de esto: ni en el esquema, ni en el formulario de conexión, ni en este documento más allá de la propia expresión «compatible con S3».
Conectar es verificar, no predecir. El formulario pide un endpoint, un bucket, un access key id y un secreto, más un prefijo de carpeta opcional. La región y el direccionamiento path-style o virtual-hosted quedan tras un apartado «avanzado», porque ambos suelen poder deducirse del endpoint y solo de vez en cuando necesitan que una persona los fuerce. Al guardar se ejecuta un ListBucket real y se informa de lo que haya devuelto, incluido el texto de error del propio almacenamiento, en lugar de intentar predecir si los datos son correctos.
Solo lectura, siempre. La clave se pide y se usa únicamente como GetObject y ListBucket. No hay ningún camino en el código que escriba en el bucket de nadie, ni borre de él, ni lo modifique de otro modo. Llenarlo se hace con las herramientas del propio proveedor de almacenamiento, igual que llenar la carpeta del bridge se hace con el gestor de archivos del ordenador.
Catalogar es un barrido programado, no algo que se hace una vez. Cada diez minutos, y una vez inmediatamente después de conectar un bucket, lo listamos (respetando el prefijo) y reconocemos el contenido por la extensión: .mp4, .m4v, .webm, .mov, .mp3 y .m4a son reproducibles, y .mkv, .avi, .wmv y .flv también se catalogan y se marcan playable: false, por la razón que se da en Formatos. Extraemos «Artist - Title» del nombre del archivo igual que lo hace el bridge (véase más abajo), y volcamos el resultado por la misma vía interna que usa el endpoint de sincronización, de modo que hay exactamente un lugar donde aterriza un catálogo, venga de la dirección que venga.
El nombre del archivo es el título. Se quita la extensión y los guiones bajos pasan a ser espacios. Si lo que queda contiene un espacio, un guion y un espacio, Artist - Title, lo que va antes del primero es el artista y lo que va después es el título, y un título que contenga otra vez el separador lo conserva. Si no, no hay artista y todo el nombre es el título. Un guion sin espacios alrededor no es un separador. Las etiquetas dentro del archivo no se leen. Es la misma regla que sigue el bridge para un archivo en un disco, y está descrita para personas en una noche de karaoke.
Las portadas siguen la convención propia del bridge: una imagen junto a cada archivo, con el mismo nombre base, con cualquiera de las extensiones .jpg, .jpeg, .png o .webp, sin distinguir mayúsculas. Como el servicio puede llegar al bucket directamente, la imagen se recoge una vez y se guarda como bytes, por el mismo camino que un envío a /providers/art (véase Portadas), en lugar de como un enlace, que caducaría en el catálogo mucho antes de que nadie lo mirase. El ETag del propio objeto sirve para omitir la nueva descarga de una imagen que no ha cambiado desde el último barrido, y se aplica el mismo límite de 1 MB.
La clave del objeto es el externalId. A diferencia de la huella de contenido del bridge, esto significa que renombrar un objeto en el bucket pierde cualquier corrección asociada a él. El esquema no tiene otro sitio donde guardar un id estable para algo que solo listamos y nunca tomamos la huella nosotros mismos.
Resolver el contenido genera un enlace, no un token. Mientras que la dirección de un bridge lleva un secreto bearer sin caducidad, una pista en la nube se resuelve a un enlace GetObject prefirmado válido unos minutos: lo bastante largo para una canción normal, lo bastante corto para que un enlace filtrado no valga mucho. El propio Stage lo pide cuando una canción está a punto de sonar, lo conserva, y lo pide de nuevo antes de que caduque, o al reanudar una canción que estuvo en pausa más allá de la vida de su enlace.
canSeek se mide. En cada barrido le pedimos al bucket un rango de uno de sus archivos reproducibles y anotamos si lo respetó, en lugar de suponerlo. Un bucket nunca se declara canAnalyseAudio.
Por qué esto no es simplemente S3
Una sugerencia recurrente: descartar todo lo anterior y decir «un proveedor es un bucket compatible con S3». Es un buen instinto — un solo protocolo, servidores de serie, un enlace prefirmado en lugar de un token de media — y se consideró y se rechazó. Las razones, para que no haya que discutirlo de nuevo desde cero:
La mitad cara no se comparte. Hablar S3 significa verificar SigV4 en cada petición: peticiones canónicas, cabeceras firmadas, hashes de la carga, desfase de reloj. Es código crítico para la seguridad que sustituye a una comparación de tokens, y un firmador del lado cliente, que escribiríamos de todos modos para consumir buckets, no ayuda en nada con eso.
No unifica lo que realmente está dividido. El catálogo se mueve en direcciones opuestas según podamos o no llegar hasta ti, y eso es cuestión de alcance, no de protocolo. Un bucket en un NAS doméstico sigue sin poder consultarse desde fuera. S3 no cambia nada de eso.
Amplía lo que expone un proveedor. Hoy el contrato es un verbo en una ruta. Un endpoint S3 de verdad invita a ListObjects, que es un catálogo que cualquiera en la red puede recorrer.
Sube el listón para todos los demás. «Sirve un GET con soporte de rangos» son veinte líneas en cualquier lenguaje, que es justo el objetivo. «Implementa S3» no lo es, y el contrato existe para que un proveedor pueda escribirlo alguien que nunca ha oído hablar de nosotros.
Un bucket sigue siendo una fuente perfectamente buena. Simplemente consume este contrato en lugar de sustituirlo, con el enlace generado en lugar de concatenado, como se describe arriba. Firmar es cómputo puro, así que ese enlace puede incluso apuntar a una dirección a la que nosotros mismos no podemos llegar: a un NAS le podría enviar su catálogo algo de su propia red mientras el contenido se resuelve mediante un enlace prefirmado al que llama directamente el Stage. El problema del certificado es el mismo que tiene el bridge, y tiene la misma respuesta, descrita en Un nombre y un certificado.