Enviar un catálogo
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
Enviar un catálogo
Presenta el token de sincronización como un token bearer:
POST https://api.lets.dj/providers/sync
Authorization: Bearer <sync token>
Content-Type: application/json
{
"baseUrl": "https://0123456789abcdef.letsdj.io:8443",
"mediaToken": "<secret you generate>",
"capabilities": {
"canTransposeKey": false,
"canSeek": true,
"allowsSharing": true,
"allowsCommercialUse": false
},
"tracks": [
{
"externalId": "5ec27f0af401a3ab",
"title": "Diễm Xưa",
"artist": "Trịnh Công Sơn",
"durationSeconds": 254,
"thumbnailUrl": "https://...",
"playable": true
}
],
"final": true
}
baseUrl es obligatorio y debe ser https. El Stage es una página HTTPS y se negará a cargar contenido por HTTP plano, así que esto se rechaza en el momento de sincronizar en lugar de fallar en silencio más tarde en la pantalla. Solo se usa su origen para construir las direcciones del contenido, como se describe en Servir el contenido multimedia, y el certificado que hay detrás tiene que ser uno en el que un navegador ya confíe.
mediaToken es obligatorio, y lo generas tú, no nosotros. Eres quien tiene que hacerlo cumplir, así que debes ser quien lo posea. Usa algo impredecible y seguro en una cadena de consulta; sirve hexadecimal aleatorio o base64url de al menos 128 bits. Rotarlo en cada reinicio está bien, con la consecuencia descrita en Servir el contenido multimedia.
capabilities dice qué eres y qué vas a hacer. Véase Capacidades. Cada sincronización lo reemplaza entero, así que envíalo completo cada vez. Un indicador que omitas vuelve a su valor por defecto, y los valores por defecto no son todos false.
limits y consoleUrl se describen en Responder bajo demanda. También se reemplazan enteros: una sincronización que omita consoleUrl quita el enlace a tu consola.
tracks es obligatorio y puede estar vacío. Envía como máximo 500 pistas por petición; más es un 400.
final es opcional, y su valor por defecto es true. Véase Reemplazar y añadir.
Pistas
externalIdes obligatorio. Es tuyo, cualquier cadena no vacía, y único dentro de tu biblioteca. También da nombre al contenido de la pista: es la última parte de la dirección del contenido, codificada con porcentaje.titlees obligatorio.artist,durationSeconds(en segundos, cualquier número finito) ythumbnailUrlson opcionales.playablees opcional. Solo unfalseliteral dice algo. Véase Formatos.
externalId debe ser estable entre escaneos. Una canción en la cola se resuelve a través de él, así que un id derivado de un estado mutable romperá canciones en plena fiesta. El bridge deriva sus ids del tamaño del archivo y de los bytes de cada extremo, no de su ruta, para que mover o renombrar un archivo no deje huérfanas las correcciones que alguien le haya hecho.
Una pista sin externalId o sin title no se puede encontrar ni reproducir, y se omite sin hacer fallar el lote. La respuesta dice cuántas se conservaron, así que compáralo con cuántas enviaste.
Reemplazar y añadir
Una sincronización hace una de dos cosas, y final es lo que elige.
Reemplazar el catálogo. Envíalo en lotes de como máximo 500, con final: false en todos menos el último. El último lote elimina toda pista que ninguno de los lotes de ese reemplazo haya mencionado. Una corrección que haya hecho el dueño sobrevive a la eliminación, y vuelve si vuelve la pista. Una pista que está esperando a descargarse nunca se elimina así: véase Responder bajo demanda.
Añadir o actualizar. Envía final: false, y no se elimina nada. Así se informa de una pista descargada, y así puede un proveedor que sabe exactamente qué cambió decir solo eso.
Como final vale true por defecto, una sincronización que lo omite es un reemplazo. Una sola pista enviada así elimina el resto del catálogo. Un lote vacío con final: true lo elimina todo. Por eso, cuando un escaneo falla, por ejemplo porque se ha desenchufado una unidad o un recurso compartido está dormido, no envíes lo que encontró el escaneo fallido. Deja el último catálogo como está y díselo a la persona, que es lo que hace el bridge.
La respuesta
{ "ok": true, "accepted": 312, "trackCount": 812 }
accepted es cuántas pistas de esta petición se conservaron. trackCount es cuántas pistas tiene la biblioteca después. La biblioteca queda lista la primera vez que aterriza una sincronización.
- 400 con un
errorque dice qué:body must be JSON,baseUrl is required,baseUrl must be https,consoleUrl must be https,tracks must be an array,at most 500 tracks per batchomediaToken is required. - 401 y 403 como se describe en Convenciones.
- 503 significa que el servicio no pudo guardar un secreto en este momento. Es cosa nuestra y merece reintentarse más tarde.
Portadas
Opcionales, y en capas igual que una corrección: lo que nosotros tenemos siempre gana, pero nada de esto toca jamás el archivo de tu lado.
Hay dos maneras de aportarlas:
Una URL, en el cuerpo de la sincronización: thumbnailUrl en cada pista, como se ve arriba. Vale cualquier cosa que pueda recoger el navegador del móvil de un invitado. Es la elección equivocada si la URL solo se resuelve en tu propia red o caduca a las pocas horas; usa el endpoint de abajo.
Bytes, enviados a un endpoint específico. Es el camino que tiene que seguir un proveedor en una red privada, ya que no puede dar una URL a la que llegue nadie más:
POST https://api.lets.dj/providers/art?externalId=<externalId>
Authorization: Bearer <sync token>
Content-Type: image/jpeg
<raw image bytes>
externalId debe corresponder a una pista ya comunicada por /providers/sync, así que envía primero el catálogo y después la portada. Una pista que el servicio no conoce es un 404 con unknown track. Content-Type debe empezar por image/, y el cuerpo no debe estar vacío. Envía JPEG, PNG o WebP: lo que un navegador no sepa dibujar se guardará y se mostrará como una imagen rota.
El límite es 1 MB, es decir, 1.048.576 bytes. No decodificamos ni redimensionamos lo que envías, así que una imagen demasiado grande es un 400 rotundo y no un remuestreo silencioso. Envía algo ya dimensionado como miniatura. Un JPEG de 1280×720 de 70 KB, lo que ya produce un móvil o una copia de DVD, queda muy por debajo del límite.
Enviar de nuevo la portada de una pista reemplaza la imagen anterior. La portada sobrevive a sincronizaciones posteriores de la misma pista, y se borra con la pista cuando un reemplazo la elimina.
Una portada enviada así tiene prioridad sobre un thumbnailUrl de la misma pista, porque unos bytes que ya tenemos ganan a un enlace que puede quedarse viejo o dar 404 más adelante. Ambas pierden ante una corrección hecha en la app: tu catálogo es una fuente, no la última palabra.
Qué puede cambiar el dueño
El dueño puede corregir en la app el título, el artista y la imagen de una pista. Una corrección gana a lo que tú envíes, campo por campo, y sobrevive a cada sincronización posterior, porque se guarda aparte del catálogo y se identifica por externalId. Nunca se te avisa de una. Por eso un externalId estable importa dos veces: una pista cuyo id cambia es una pista distinta, y empieza de nuevo sin ellas.