原声配乐
GET /3/movie/{movie_id}/soundtracks 返回电影或剧集的原声专辑,含来源、名称、艺人、发行日期、链接和曲目列表。用 append_to_response=soundtracks 并入详情。
获取电影的原声配乐
GET / 返回一部电影的原声专辑。响应带有电影 id 和 results 数组。每个条目是一张专辑,包含其详情和 tracks 列表。
示例加载《黑暗骑士》(ID 155),打印专辑信息和每首曲目一行。
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)
}
}
}参数
movie_id路径必填数字形式的电影 ID,例如155。api_key查询二选一你的密钥。使用它,或使用Authorization: Bearer请求头。
响应字段
| 字段 | 类型 | 说明 |
|---|---|---|
id | integer | 电影 ID。使用 append_to_response 时不存在。 |
results | array | 专辑。没有已知专辑时为空。目前最多一张。 |
results[].source | string | 专辑的来源:musicbrainz 或 deezer。 |
results[].album | string | 专辑标题。 |
results[].artist | string 或 null | 专辑艺人,例如 Hans Zimmer &。 |
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_ | integer | 时长,单位为毫秒。 |
请按名称读取你用到的键,并跳过其他键。
示例响应
{
"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 }
]
}
]
}曲目列表缩减为 14 首中的 3 首。没有已知专辑的作品,例如《搏击俱乐部》(ID 550),会返回空列表:
{
"id": 550,
"results": []
}获取剧集的原声配乐
GET / 对剧集返回同样的结构。传入剧集 ID,例如 1396。《绝命毒师》没有已知专辑,所以其 results 数组为空。
| 方法和路径 | 返回内容 | 参数 |
|---|---|---|
GET / | id 和 results | movie_id |
GET / | id 和 results | tv_id |
append_ | soundtracks 下相同的 results | 添加到电影或剧集详情 |
要在加载电影页面时一并获得专辑,请把它追加到详情中:
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 为空时隐藏该区块。下面的函数返回纯文本行,可以放进列表元素。
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 相加。 |
| 搭配情绪 | 把列表放在同一作品的情绪指数旁边。 |
错误
每次失败都像 TMDB 一样返回 success 为 false 和数字 status_code。
| HTTP | status_code | 何时出现 |
|---|---|---|
| 401 | 7 | 密钥缺失或错误。 |
| 402 | 36 | 套餐周期已结束。 |
| 429 | 25 | 超过每分钟请求数。请等待 Retry-After 秒。 |
原声配乐接口对未知 ID 不返回 404,而是返回 200 和空的 results 数组。追加到详情时,未知 ID 由详情调用返回 404。所有代码见错误,响应头见速率限制。
实用说明
- 与其他详情数据一样,原声配乐在边缘缓存 6 小时。更短的客户端缓存没有好处。
- 在你本来就要加载的详情页上使用
append_。它能为你每分钟 20、40 或 120 个请求节省一个请求。to_ response= soundtracks - 不要要求专辑必须存在。
results为空时隐藏音乐区块。 - 有些专辑来自 MusicBrainz,其他来自 Deezer。电影 27205(《盗梦空间》)有一张 Deezer 专辑。结构相同,所以只有要展示来源时才需要检查
source。 - 曲目和艺人名称是普通字符串,可以包含任何字符。请以 UTF-8 存储,并在放进 HTML 时转义。
- 同一作品的预告片见视频与预告片。