Bandas sonoras

GET /3/movie/{movie_id}/soundtracks y GET /3/tv/{tv_id}/soundtracks devuelven el álbum de banda sonora de un título en una lista results. Cada álbum trae fuente, nombre, artista, fecha de lanzamiento, enlace y una lista tracks con disco, número, título, artista y duración. Añade append_to_response=soundtracks para incorporarlo a los detalles.

Actualizado el Ver en Markdown

Obtén la banda sonora de una película

GET /3/movie/{movie_id}/soundtracks devuelve el álbum de banda sonora de una película. La respuesta incluye el id de la película y un array results. Cada entrada es un álbum con sus datos y una lista tracks.

El ejemplo carga The Dark Knight (id 155) e imprime el álbum y una línea por pista.

bashjspyphpgo
curl -sf "https://api.amodb.dev/3/movie/155/soundtracks" \
  -H "Authorization: Bearer $AMODB_KEY"
const res = await fetch('https://api.amodb.dev/3/movie/155/soundtracks', {
  headers: { Authorization: `Bearer ${process.env.AMODB_KEY}` },
});
if (!res.ok) throw new Error(`amodb returned ${res.status}`);
const { results } = await res.json();
if (results.length === 0) console.log('no soundtrack album known');
for (const album of results) {
  console.log(`${album.album} by ${album.artist} (${album.track_count} tracks)`);
  for (const t of album.tracks) {
    console.log(`${t.number}. ${t.title} by ${t.artist}`);
  }
}
import os
import requests

r = requests.get(
    "https://api.amodb.dev/3/movie/155/soundtracks",
    headers={"Authorization": f"Bearer {os.environ['AMODB_KEY']}"},
    timeout=10,
)
r.raise_for_status()
results = r.json()["results"]
if not results:
    print("no soundtrack album known")
for album in results:
    print(f"{album['album']} by {album['artist']} ({album['track_count']} tracks)")
    for t in album["tracks"]:
        print(f"{t['number']}. {t['title']} by {t['artist']}")
<?php
$ch = curl_init('https://api.amodb.dev/3/movie/155/soundtracks');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_TIMEOUT => 10,
    CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('AMODB_KEY')],
]);
$body = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($status !== 200) {
    throw new RuntimeException("amodb returned $status");
}
$results = json_decode($body, true)['results'];
if (!$results) {
    echo 'no soundtrack album known', PHP_EOL;
}
foreach ($results as $album) {
    echo $album['album'], ' by ', $album['artist'] ?? 'unknown', ' (', $album['track_count'], ' tracks)', PHP_EOL;
    foreach ($album['tracks'] as $t) {
        echo $t['number'], '. ', $t['title'], ' by ', $t['artist'], PHP_EOL;
    }
}
package main

import (
	"encoding/json"
	"fmt"
	"net/http"
	"os"
	"time"
)

type Track struct {
	Disc       int    `json:"disc"`
	Number     int    `json:"number"`
	Title      string `json:"title"`
	Artist     string `json:"artist"`
	DurationMs int    `json:"duration_ms"`
}

type Album struct {
	Source     string  `json:"source"`
	Album      string  `json:"album"`
	Artist     string  `json:"artist"`
	Released   string  `json:"released"`
	URL        string  `json:"url"`
	TrackCount int     `json:"track_count"`
	Tracks     []Track `json:"tracks"`
}

func main() {
	req, _ := http.NewRequest("GET", "https://api.amodb.dev/3/movie/155/soundtracks", nil)
	req.Header.Set("Authorization", "Bearer "+os.Getenv("AMODB_KEY"))
	client := &http.Client{Timeout: 10 * time.Second}
	res, err := client.Do(req)
	if err != nil {
		panic(err)
	}
	defer res.Body.Close()
	if res.StatusCode != http.StatusOK {
		panic(res.Status)
	}
	var body struct {
		Results []Album `json:"results"`
	}
	if err := json.NewDecoder(res.Body).Decode(&body); err != nil {
		panic(err)
	}
	if len(body.Results) == 0 {
		fmt.Println("no soundtrack album known")
	}
	for _, a := range body.Results {
		fmt.Printf("%s by %s (%d tracks)\n", a.Album, a.Artist, a.TrackCount)
		for _, t := range a.Tracks {
			fmt.Printf("%d. %s by %s\n", t.Number, t.Title, t.Artist)
		}
	}
}

Parámetros

  • movie_idrutaobligatorio
    ID numérico de la película, por ejemplo 155.
  • api_keyconsultauno de los dos
    Tu clave. Usa esta o el encabezado Authorization: Bearer.

Campos de la respuesta

CampoTipoNotas
identeroID de la película. No aparece cuando usas append_to_response.
resultsarrayÁlbumes. Vacío cuando no se conoce ningún álbum. Hoy contiene como máximo uno.
results[].sourcetextoDe dónde viene el álbum: musicbrainz o deezer.
results[].albumtextoTítulo del álbum.
results[].artisttexto o nullArtista del álbum, por ejemplo Hans Zimmer & James Newton Howard.
results[].releasedtexto o nullFecha de lanzamiento como YYYY-MM-DD.
results[].urltexto o nullEnlace a la página del álbum en la fuente.
results[].track_countenteroNúmero de pistas del álbum.
results[].tracksarrayPistas en el orden del álbum.
results[].tracks[].discenteroNúmero de disco, a partir de 1.
results[].tracks[].numberenteroNúmero de pista en el disco.
results[].tracks[].titletextoTítulo de la pista.
results[].tracks[].artisttextoArtista de la pista.
results[].tracks[].duration_msenteroDuración en milisegundos.

Lee por nombre las claves que uses e ignora las demás.

Ejemplo de respuesta

JSON
{
  "id": 155,
  "results": [
    {
      "source": "musicbrainz",
      "album": "The Dark Knight",
      "artist": "Hans Zimmer & James Newton Howard",
      "released": "2008-07-15",
      "url": "https://musicbrainz.org/release/814b2f7b-c27c-451e-abac-a316d2e6cea9",
      "track_count": 14,
      "tracks": [
        { "disc": 1, "number": 1, "title": "Why So Serious?", "artist": "Hans Zimmer", "duration_ms": 554000 },
        { "disc": 1, "number": 2, "title": "I'm Not a Hero", "artist": "Hans Zimmer", "duration_ms": 395000 },
        { "disc": 1, "number": 3, "title": "Harvey Two-Face", "artist": "James Newton Howard", "duration_ms": 377000 }
      ]
    }
  ]
}

La lista de pistas se recortó a 3 de 14. Un título sin álbum conocido, como Fight Club (id 550), responde con una lista vacía:

JSON
{
  "id": 550,
  "results": []
}

Obtén la banda sonora de una serie

GET /3/tv/{tv_id}/soundtracks devuelve la misma estructura para una serie. Pasa el id de la serie, por ejemplo 1396. Breaking Bad no tiene ningún álbum conocido, así que su array results está vacío.

Método y rutaDevuelveParámetros
GET /movie/{movie_id}/soundtracksid y resultsmovie_id
GET /tv/{tv_id}/soundtracksid y resultstv_id
append_to_response=soundtracksLos mismos results bajo soundtracksSe añade a los detalles de películas o de TV

Para obtener el álbum mientras cargas la página de una película, añádelo a los detalles:

curl
curl -sf "https://api.amodb.dev/3/movie/155?append_to_response=credits,soundtracks" \
  -H "Authorization: Bearer $AMODB_KEY"

El bloque añadido queda bajo la clave soundtracks del registro. Contiene results y no tiene id propio. Cuenta como una sola solicitud.

Crea una lista de música de la película

Ordena por disc y number, muestra el título y el artista, y oculta el bloque cuando results esté vacío. Las funciones siguientes devuelven líneas de texto plano que puedes colocar en un elemento de lista.

JavaScript
function clock(ms) {
  const s = Math.round(ms / 1000);
  return `${Math.floor(s / 60)}:${String(s % 60).padStart(2, '0')}`;
}

function musicLines(results) {
  const album = results[0];
  if (!album) return [];
  return [...album.tracks]
    .sort((a, b) => a.disc - b.disc || a.number - b.number)
    .map((t) => `${t.title} by ${t.artist} (${clock(t.duration_ms)})`);
}

Algunas ideas de interfaz que no necesitan datos adicionales:

IdeaCómo
Lista numeradaUsa number como número de la lista y agrupa por disc cuando haya varios discos.
Enlace al álbumEnlaza el nombre del álbum con url cuando no sea null.
Duración totalSuma duration_ms de todas las pistas.
Combinación con moodMuestra la lista junto a los medidores de mood del mismo título.

Errores

Todo fallo devuelve success en false con un status_code numérico, como hace TMDB.

HTTPstatus_codeCuándo
4017Falta la clave o es incorrecta.
40236El periodo del plan ha terminado.
42925Superaste tus solicitudes por minuto. Espera los segundos indicados en Retry-After.

El endpoint de soundtracks no responde 404 ante un id desconocido. Responde 200 con un array results vacío. Cuando se añade a los detalles, un id desconocido da un 404 en la llamada de detalles. Consulta errores para ver todos los códigos y límites de solicitudes para los encabezados.

Notas prácticas

  • Como los demás datos de detalles, las bandas sonoras se guardan en la caché perimetral 6 horas. Una caché de cliente más corta no aporta nada.
  • Usa append_to_response=soundtracks en una página de detalles que ya cargas. Ahorra una solicitud de tus 20, 40 o 120 solicitudes por minuto.
  • No des por hecho que existe un álbum. Oculta el bloque de música cuando results esté vacío.
  • Algunos álbumes vienen de MusicBrainz y otros de Deezer. La película 27205 (Inception) tiene un álbum de Deezer. La estructura es la misma, así que comprueba source solo si lo muestras.
  • Los nombres de pistas y artistas son textos simples y pueden contener cualquier carácter. Guárdalos como UTF-8 y escápalos al colocarlos en HTML.
  • Para el tráiler del mismo título, consulta vídeos y tráilers.