# Soundtracky

> GET /3/movie/{movie_id}/soundtracks a GET /3/tv/{tv_id}/soundtracks vracejí album soundtracku titulu v seznamu results. Každé album má zdroj, název, interpreta, datum vydání, odkaz a seznam tracks s poli disc, number, title, artist a délka skladby. Přidejte append_to_response=soundtracks a album sloučíte do detailů bez dalšího požadavku.

## Endpoint

`GET /3/movie/{movie_id}/soundtracks`

```bash
curl "https://api.amodb.dev/3/movie/155/soundtracks" \
  -H "Authorization: Bearer $AMODB_KEY"
```

Odpověď:

```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
        }
      ]
    }
  ]
}
```

## Získání soundtracku filmu

`GET /3/movie/{movie_id}/soundtracks` vrací album soundtracku jednoho filmu. Odpověď nese `id` filmu a pole `results`. Každá položka je album s podrobnostmi a seznamem `tracks`.

Ukázka načte The Dark Knight (ID 155) a vypíše album a jeden řádek na skladbu.

```bash
curl -sf "https://api.amodb.dev/3/movie/155/soundtracks" \
  -H "Authorization: Bearer $AMODB_KEY"
```

```js
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}`);
  }
}
```

```python
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
<?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;
    }
}
```

```go
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)
		}
	}
}
```

### Parametry

| Parametr   | Kde   | Povinný       | Popis                                                          |
| ---------- | ----- | ------------- | -------------------------------------------------------------- |
| `movie_id` | path  | ano           | Číselné ID filmu, například `155`.                             |
| `api_key`  | query | jeden ze dvou | Váš klíč. Použijte jej, nebo hlavičku `Authorization: Bearer`. |

### Pole odpovědi

| Pole                             | Typ              | Poznámky                                                                 |
| -------------------------------- | ---------------- | ------------------------------------------------------------------------ |
| `id`                             | integer          | ID filmu. Při použití `append_to_response` chybí.                        |
| `results`                        | array            | Alba. Prázdné, když není známo žádné album. Dnes obsahuje nejvýše jedno. |
| `results[].source`               | string           | Odkud album pochází: `musicbrainz` nebo `deezer`.                        |
| `results[].album`                | string           | Název alba.                                                              |
| `results[].artist`               | string nebo null | Interpret alba, například `Hans Zimmer & James Newton Howard`.           |
| `results[].released`             | string nebo null | Datum vydání jako `YYYY-MM-DD`.                                          |
| `results[].url`                  | string nebo null | Odkaz na stránku alba u zdroje.                                          |
| `results[].track_count`          | integer          | Počet skladeb na albu.                                                   |
| `results[].tracks`               | array            | Skladby v pořadí na albu.                                                |
| `results[].tracks[].disc`        | integer          | Číslo disku, počínaje 1.                                                 |
| `results[].tracks[].number`      | integer          | Číslo skladby na disku.                                                  |
| `results[].tracks[].title`       | string           | Název skladby.                                                           |
| `results[].tracks[].artist`      | string           | Interpret skladby.                                                       |
| `results[].tracks[].duration_ms` | integer          | Délka v milisekundách.                                                   |

Klíče, které používáte, čtěte podle názvu a ostatní přeskočte.

### Příklad odpovědi

```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 }
      ]
    }
  ]
}
```

Seznam skladeb je zkrácen na 3 ze 14. Titul bez známého alba, například Fight Club (ID 550), odpoví prázdným seznamem:

```json
{
  "id": 550,
  "results": []
}
```

## Získání soundtracku seriálu

`GET /3/tv/{tv_id}/soundtracks` vrací stejný tvar pro seriál. Předejte ID seriálu, například `1396`. Breaking Bad nemá známé žádné album, takže jeho pole `results` je prázdné.

| Metoda a cesta                      | Vrací                              | Parametry                                |
| ----------------------------------- | ---------------------------------- | ---------------------------------------- |
| `GET /movie/{movie_id}/soundtracks` | `id` a `results`                   | `movie_id`                               |
| `GET /tv/{tv_id}/soundtracks`       | `id` a `results`                   | `tv_id`                                  |
| `append_to_response=soundtracks`    | Stejné `results` pod `soundtracks` | Přidává se k detailům filmu nebo seriálu |

Chcete-li album získat při načítání stránky filmu, přidejte ho k detailům:

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

Přidaný blok leží pod klíčem `soundtracks` záznamu. Obsahuje `results` a nemá vlastní `id`. Počítá se jako jeden požadavek.

## Sestavení seznamu hudby ve filmu

Seřaďte podle `disc` a `number`, zobrazte název a interpreta a blok skryjte, když je `results` prázdné. Funkce níže vracejí řádky prostého textu, které můžete vložit do prvku seznamu.

```js
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)})`);
}
```

Několik nápadů pro rozhraní, které nepotřebují další data:

| Nápad               | Jak                                                                              |
| ------------------- | -------------------------------------------------------------------------------- |
| Číslovaný seznam    | Použijte `number` jako číslo v seznamu a při více discích seskupte podle `disc`. |
| Odkaz na album      | Název alba propojte s `url`, když není null.                                     |
| Celková délka       | Sečtěte `duration_ms` přes skladby.                                              |
| Spárování s náladou | Zobrazte seznam vedle [měřičů nálady](https://amodb.dev/cs/moods/) téhož titulu. |

## Chyby

Každé selhání vrací `success` jako false s číselným `status_code`, stejně jako TMDB.

| HTTP | status_code | Kdy                                                                                   |
| ---- | ----------- | ------------------------------------------------------------------------------------- |
| 401  | 7           | Klíč chybí nebo je nesprávný.                                                         |
| 402  | 36          | Platnost tarifu skončila.                                                             |
| 429  | 25          | Překročen počet požadavků za minutu. Počkejte tolik sekund, kolik říká `Retry-After`. |

Endpoint soundtracků neodpovídá 404 pro neznámé ID. Odpoví 200 s prázdným polem `results`. U přidání k detailům je neznámé ID 404 z volání detailů. Všechny kódy viz [chyby](https://amodb.dev/cs/errors/) a hlavičky viz [limity požadavků](https://amodb.dev/cs/rate-limits/).

## Praktické poznámky

- Jako ostatní data detailů se soundtracky na edge cachují 6 hodin. Kratší cache u klienta nic nepřináší.
- Používejte `append_to_response=soundtracks` na stránce detailů, kterou už načítáte. Ušetří požadavek z vašich 20, 40 nebo 120 požadavků za minutu.
- Nevyžadujte, aby album existovalo. Hudební blok skryjte, když je `results` prázdné.
- Některá alba pocházejí z MusicBrainz a jiná z Deezeru. Film 27205 (Inception) má album z Deezeru. Tvar je stejný, `source` proto kontrolujte jen tehdy, když ho zobrazujete.
- Názvy skladeb a interpretů jsou prosté řetězce a mohou obsahovat libovolný znak. Ukládejte je jako UTF-8 a při vkládání do HTML je escapujte.
- Trailer téhož titulu najdete na stránce [videa a trailery](https://amodb.dev/cs/videos-trailers/).

## Otázky a odpovědi

### Co obsahuje jedna položka soundtracku?

Jeden objekt alba. Má zdroj, název alba, interpreta, datum vydání, odkaz a track_count. Jeho pole tracks uvádí každou skladbu s disc, number, title, artist a duration_ms. Odpověď nese také ID titulu.

### Dostanu zvukové soubory nebo odkazy na streamování?

Žádný zvuk. Pole url odkazuje na stránku alba na MusicBrainz nebo Deezeru a může být null. Aby si uživatelé mohli album poslechnout, vyhledejte ho v hudební službě, kterou už používáte, a otevřete ho z vlastního rozhraní.

### Má soundtrack každý titul?

Ne. Mnoho titulů, mezi nimi Fight Club, nemá známé žádné album a odpovědí je prázdné pole results. Dnes má titul nejvýše jedno album. Hudební blok navrhněte tak, aby se skryl, když není co zobrazit.

### Mohu získat soundtracky seriálu?

Ano. Zavolejte GET /3/tv/{tv_id}/soundtracks s ID seriálu. Odpověď má stejný tvar jako endpoint pro filmy, takže stačí jeden parser.

## Související stránky

- [API detailu filmu](https://amodb.dev/cs/movies/): API detailu filmu se stejnými cestami a JSON jako TMDB v3. Načtěte film podle ID, přidejte obsazení, hodnocení a nálady přes append_to_response, 14 jazyků.
- [API detailu seriálu](https://amodb.dev/cs/tv-series/): API detailu seriálu se stejnými cestami a JSON jako TMDB v3. Seriál podle ID se sezónami, sítěmi, věkovým hodnocením a poskytovateli streamování.
- [Měřiče nálady](https://amodb.dev/cs/moods/): API nálad filmů s měřiči na stupnici 0 až 10. Načtěte nálady filmu nebo seriálu, sloučte je přes append_to_response=moods a sestavte odznaky či filtry.
- [API videí a trailerů](https://amodb.dev/cs/videos-trailers/): API videí filmů s cestami TMDB v3: vypište trailery, teasery, klipy a featurety filmu nebo seriálu a pak filtrujte podle typu a jazyka ve svém kódu.
- [Hodnocení filmů a seriálů](https://amodb.dev/cs/ratings/): API hodnocení filmů, které vrací skóre z IMDb, Kinopoisk, Metacritic, Rotten Tomatoes a TMDB pro titul jedním voláním, s null u každého neznámého zdroje.
- [Rychlý start](https://amodb.dev/cs/quickstart/): První volání amodb: získejte klíč, vyžádejte detail filmu v curl, JavaScriptu, Pythonu, PHP nebo Go a načtěte plakát z img.amodb.dev. Za méně než 2 minuty.

Aktualizováno: 2026-10-18. Source: https://amodb.dev/cs/soundtracks/
