# פסקולים

> GET /3/movie/{movie_id}/soundtracks ו-GET /3/tv/{tv_id}/soundtracks מחזירים את אלבום הפסקול של כותר אחד ברשימת results. לכל אלבום יש מקור, שם, אמן, תאריך יציאה, קישור ורשימת tracks עם דיסק, מספר, שם, אמן ומשך. הוסיפו append_to_response=soundtracks כדי למזג אותו לפרטי הכותר. כך הפסקול מגיע יחד עם הפרטים בבקשה אחת.

## נקודת קצה

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

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

תגובה:

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

## קבלת הפסקול של סרט

`GET /3/movie/{movie_id}/soundtracks` מחזיר את אלבום הפסקול של סרט אחד. התגובה נושאת את ה-`id` של הסרט ומערך `results`. כל פריט הוא אלבום עם הפרטים שלו ורשימת `tracks`.

הדוגמה טוענת את The Dark Knight (מזהה 155) ומדפיסה את האלבום ושורה אחת לכל רצועה.

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

### פרמטרים

| פרמטר      | מיקום  | חובה       | תיאור                                                    |
| ---------- | ------ | ---------- | -------------------------------------------------------- |
| `movie_id` | נתיב   | כן         | מזהה סרט מספרי, למשל `155`.                              |
| `api_key`  | שאילתה | אחד משניים | המפתח שלכם. השתמשו בו או בכותרת `Authorization: Bearer`. |

### שדות התגובה

| שדה                              | סוג            | הערות                                                   |
| -------------------------------- | -------------- | ------------------------------------------------------- |
| `id`                             | integer        | מזהה הסרט. לא קיים כשמשתמשים ב-`append_to_response`.    |
| `results`                        | array          | אלבומים. ריק כשלא ידוע אלבום. כיום יש בו לכל היותר אחד. |
| `results[].source`               | string         | מאיפה האלבום מגיע: `musicbrainz` או `deezer`.           |
| `results[].album`                | string         | כותרת האלבום.                                           |
| `results[].artist`               | string או null | אמן האלבום, למשל `Hans Zimmer & James Newton Howard`.   |
| `results[].released`             | string או null | תאריך יציאה בצורה `YYYY-MM-DD`.                         |
| `results[].url`                  | string או null | קישור לעמוד האלבום במקור.                               |
| `results[].track_count`          | integer        | מספר הרצועות באלבום.                                    |
| `results[].tracks`               | array          | רצועות לפי סדר האלבום.                                  |
| `results[].tracks[].disc`        | integer        | מספר הדיסק, מתחיל ב-1.                                  |
| `results[].tracks[].number`      | integer        | מספר הרצועה בדיסק.                                      |
| `results[].tracks[].title`       | string         | כותרת הרצועה.                                           |
| `results[].tracks[].artist`      | string         | אמן הרצועה.                                             |
| `results[].tracks[].duration_ms` | integer        | האורך באלפיות שנייה.                                    |

קראו את המפתחות שאתם משתמשים בהם לפי שם ודלגו על מפתחות אחרים.

### תגובה לדוגמה

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

רשימת הרצועות קוצרה ל-3 מתוך 14. כותר בלי אלבום ידוע, כמו Fight Club (מזהה 550), מחזיר רשימה ריקה:

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

## קבלת הפסקול של סדרה

`GET /3/tv/{tv_id}/soundtracks` מחזיר את אותו מבנה לסדרה. העבירו את מזהה הסדרה, למשל `1396`. ל-Breaking Bad אין אלבום ידוע, ולכן מערך `results` שלה ריק.

| שיטה ונתיב                          | מה מוחזר                         | פרמטרים                |
| ----------------------------------- | -------------------------------- | ---------------------- |
| `GET /movie/{movie_id}/soundtracks` | `id` ו-`results`                 | `movie_id`             |
| `GET /tv/{tv_id}/soundtracks`       | `id` ו-`results`                 | `tv_id`                |
| `append_to_response=soundtracks`    | אותו `results` תחת `soundtracks` | נוסף לפרטי סרט או סדרה |

כדי לקבל את האלבום בזמן טעינת עמוד סרט, צרפו אותו לפרטים:

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

הבלוק המצורף יושב תחת המפתח `soundtracks` ברשומה. הוא מחזיק `results` ואין לו `id` משלו. הוא נספר כבקשה אחת.

## בניית רשימת המוזיקה בסרט

מיינו לפי `disc` ו-`number`, הציגו את הכותרת ואת האמן, והסתירו את הבלוק כש-`results` ריק. הפונקציות שלמטה מחזירות שורות טקסט פשוט שאפשר לשים באלמנט רשימה.

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

כמה רעיונות לממשק שלא צריכים נתונים נוספים:

| רעיון            | איך                                                                           |
| ---------------- | ----------------------------------------------------------------------------- |
| רשימה ממוספרת    | השתמשו ב-`number` כמספר הפריט ברשימה, וקבצו לפי `disc` כשיש כמה דיסקים.       |
| קישור לאלבום     | קשרו את שם האלבום ל-`url` כשהוא לא null.                                      |
| אורך כולל        | חברו את `duration_ms` של כל הרצועות.                                          |
| שילוב עם מצב רוח | הציגו את הרשימה ליד [מדדי מצב רוח](https://amodb.dev/he/moods/) של אותו כותר. |

## שגיאות

כל כשל מחזיר `success` שהוא false ו-`status_code` מספרי, כמו ב-TMDB.

| HTTP | status_code | מתי                                               |
| ---- | ----------- | ------------------------------------------------- |
| 401  | 7           | המפתח חסר או שגוי.                                |
| 402  | 36          | תקופת המסלול הסתיימה.                             |
| 429  | 25          | מעל הבקשות שלכם לדקה. המתינו `Retry-After` שניות. |

נקודת הקצה של הפסקולים לא עונה 404 למזהה לא מוכר. היא עונה 200 עם מערך `results` ריק. כשמצרפים לפרטים, מזהה לא מוכר הוא 404 מקריאת הפרטים. כל הקודים בעמוד [שגיאות](https://amodb.dev/he/errors/), והכותרות בעמוד [מגבלות קצב](https://amodb.dev/he/rate-limits/).

## הערות מעשיות

- כמו נתוני פרטים אחרים, פסקולים נשמרים בקצה במטמון 6 שעות. מטמון קצר יותר בצד הלקוח לא מועיל.
- השתמשו ב-`append_to_response=soundtracks` בעמוד פרטים שאתם כבר טוענים. זה חוסך בקשה אחת מתוך 20, 40 או 120 הבקשות שלכם לדקה.
- אל תדרשו שאלבום יהיה קיים. הסתירו את בלוק המוזיקה כש-`results` ריק.
- חלק מהאלבומים מגיעים מ-MusicBrainz ואחרים מ-Deezer. לסרט 27205 (Inception) יש אלבום ב-Deezer. המבנה זהה, ולכן בדקו את `source` רק אם אתם מציגים אותו.
- שמות רצועות ואמנים הם מחרוזות רגילות ויכולים להכיל כל תו. שמרו אותם כ-UTF-8 ובצעו להם escape כשאתם מציבים אותם ב-HTML.
- לטריילר של אותו כותר ראו [סרטונים וטריילרים](https://amodb.dev/he/videos-trailers/).

## שאלות ותשובות

### מה מכיל פריט פסקול אחד?

אובייקט אלבום אחד. יש בו מקור, שם אלבום, אמן, תאריך יציאה, קישור ו-track_count. המערך tracks שלו מונה כל רצועה עם disc, number, title, artist ו-duration_ms. התגובה נושאת גם את מזהה הכותר.

### האם מקבלים קבצי שמע או קישורי סטרימינג?

אין שמע. השדה url מקשר לעמוד האלבום ב-MusicBrainz או ב-Deezer, והוא יכול להיות null. כדי לאפשר למשתמשים להאזין, חפשו את האלבום בשירות המוזיקה שאתם כבר משתמשים בו ופתחו אותו מהממשק שלכם.

### האם יש פסקול לכל כותר?

לא. לכותרים רבים, ביניהם Fight Club, אין אלבום ידוע, והתגובה היא מערך results ריק. כיום לכותר יש לכל היותר אלבום אחד. תכננו את בלוק המוזיקה כך שיסתיר את עצמו כשאין מה להציג.

### אפשר לקבל פסקולים של סדרה?

כן. קראו ל-GET /3/tv/{tv_id}/soundtracks עם מזהה הסדרה. לתגובה אותו מבנה כמו בנקודת הקצה של סרטים, ולכן מנתח אחד מכסה את שתיהן.

## עמודים קשורים

- [API פרטי סרט](https://amodb.dev/he/movies/): API פרטי סרט עם אותם נתיבים ו-JSON כמו TMDB v3. קבלו סרט לפי מזהה, הוסיפו קרדיטים, דירוגים, מצבי רוח ופסקולים עם append_to_response, ב-14 שפות.
- [API סדרות טלוויזיה](https://amodb.dev/he/tv-series/): API סדרות טלוויזיה עם אותם נתיבים ו-JSON כמו TMDB v3. קבלו סדרה לפי מזהה ב-GET /3/tv/{series_id} עם עונות, רשתות והפרק הבא, וגם סיווגי גיל וספקי צפייה.
- [מדדי מצב רוח](https://amodb.dev/he/moods/): API מצב רוח בסרטים עם מדדים בסולם 0 עד 10 לכל כותר. קראו מצבי רוח של סרט או סדרה, מזגו אותם עם append_to_response=moods ובנו תגים או מסננים.
- [API סרטונים וטריילרים](https://amodb.dev/he/videos-trailers/): API סרטונים עם נתיבי TMDB v3, כמו GET /3/movie/{movie_id}/videos: רשימת טריילרים, טיזרים, קטעים ופיצ'רטים של סרט או סדרה, ואז סינון לפי סוג ושפה בקוד שלכם.
- [דירוגי סרטים וסדרות](https://amodb.dev/he/ratings/): API דירוגי סרטים וסדרות שמחזיר ציוני IMDb, Kinopoisk, Metacritic, Rotten Tomatoes ו-TMDB לכותר בקריאה אחת, עם value ו-votes ו-null לכל מקור שאינו ידוע.
- [מדריך למתחילים](https://amodb.dev/he/quickstart/): בצעו את הקריאה הראשונה ל-amodb: קבלו מפתח, בקשו פרטי סרט ב-curl, JavaScript, Python, PHP או Go, ואז טענו את הפוסטר מ-img.amodb.dev. פחות מ-2 דקות.

עודכן: 2026-10-18. Source: https://amodb.dev/he/soundtracks/
