情绪指数
电影和电视剧的 moods 接口返回 source 和 results 列表。每条结果有情绪名(如 fear)、0 到 10 的 avg 以及 values。在详情调用中加 append_to_response=moods,无需第二次请求。
获取电影的情绪指数
GET / 返回一部电影的情绪指数。情绪指数由名称和 0 到 10 的平均值组成。响应带有电影 id、source 和 results 数组。每条结果包含 name、avg 和 values。
示例加载《蝙蝠侠:黑暗骑士》(ID 155)的指数,并从强到弱打印。
curl -sf "https://api.amodb.dev/3/movie/155/moods" \
-H "Authorization: Bearer $AMODB_KEY"const res = await fetch('https://api.amodb.dev/3/movie/155/moods', {
headers: { Authorization: `Bearer ${process.env.AMODB_KEY}` },
});
if (!res.ok) throw new Error(`amodb returned ${res.status}`);
const { source, results } = await res.json();
console.log('source:', source);
for (const m of [...results].sort((a, b) => b.avg - a.avg)) {
console.log(m.name.padEnd(10), m.avg);
}import os
import requests
r = requests.get(
"https://api.amodb.dev/3/movie/155/moods",
headers={"Authorization": f"Bearer {os.environ['AMODB_KEY']}"},
timeout=10,
)
r.raise_for_status()
data = r.json()
print("source:", data.get("source"))
for m in sorted(data["results"], key=lambda m: m["avg"], reverse=True):
print(f"{m['name']:<10} {m['avg']}")<?php
$ch = curl_init('https://api.amodb.dev/3/movie/155/moods');
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");
}
$data = json_decode($body, true);
echo 'source: ', $data['source'] ?? 'none', PHP_EOL;
$results = $data['results'];
usort($results, fn ($a, $b) => $b['avg'] <=> $a['avg']);
foreach ($results as $m) {
printf("%-10s %.1f\n", $m['name'], $m['avg']);
}package main
import (
"encoding/json"
"fmt"
"net/http"
"os"
"sort"
"time"
)
type Mood struct {
Name string `json:"name"`
Avg float64 `json:"avg"`
Values []float64 `json:"values"`
}
func main() {
req, _ := http.NewRequest("GET", "https://api.amodb.dev/3/movie/155/moods", 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 {
Source string `json:"source"`
Results []Mood `json:"results"`
}
if err := json.NewDecoder(res.Body).Decode(&body); err != nil {
panic(err)
}
fmt.Println("source:", body.Source)
sort.Slice(body.Results, func(i, j int) bool { return body.Results[i].Avg > body.Results[j].Avg })
for _, m := range body.Results {
fmt.Printf("%-10s %.1f\n", m.Name, m.Avg)
}
}参数
movie_id路径必填数字形式的电影 ID,例如155。api_key查询二选一你的密钥。使用它,或使用Authorization: Bearer请求头。
响应字段
| 字段 | 类型 | 说明 |
|---|---|---|
id | integer | 电影 ID。 |
source | string 或 null | 来自观众数据时为 measured,由类型推算时为 estimated,作品没有数据时为 null。 |
results | array | 按 name 排序的情绪指数。什么都不知道时为空。 |
results[].name | string | 简短的小写单词,例如 fear。 |
results[].avg | number | 0 到 10 刻度的平均值。实测作品保留一位小数,推算作品为整数。 |
results[].values | array of numbers | 同一 0 到 10 刻度上的最多 24 个读数。目前所见实测作品有 6 个,推算作品有 5 个。 |
目前见到的名称有 action、fear、humor、pace、profanity、romance、sadness、sex 和 violence。并非每部作品都有这九个,所以请根据数据渲染名称,而不是写死一份列表。
示例响应
{
"id": 155,
"source": "measured",
"results": [
{ "name": "action", "avg": 3.9, "values": [3.6, 3.4, 4.2, 4.2, 4.8, 3] },
{ "name": "fear", "avg": 5.2, "values": [3.6, 6, 4.8, 6.4, 6.4, 3.8] },
{ "name": "humor", "avg": 0.9, "values": [2.4, 1.8, 0.4, 0.4, 0, 0.5] }
]
}列表缩减为 9 条结果中的 3 条。
实测与推算的作品
《搏击俱乐部》(ID 550)还没有观众数据,所以它的指数由类型推算得出。每个 avg 都是整数,values 有 5 项。
{
"id": 550,
"source": "estimated",
"results": [
{ "name": "action", "avg": 4, "values": [3, 4, 5, 4, 3] },
{ "name": "fear", "avg": 7, "values": [6, 7, 8, 7, 6] }
]
}如果想把推算的指数与实测的区别对待,请检查 source。
获取剧集的情绪指数
GET / 的响应结构相同,id 中是剧集 ID。《绝命毒师》请用 1396。
| 方法和路径 | 返回内容 | 参数 |
|---|---|---|
GET / | id、source 和 results | movie_id |
GET /tv/{tv_id}/moods | id、source 和 results | tv_id |
append_ | moods 下的 source 和 results | 加在电影或电视剧详情上 |
curl -sf "https://api.amodb.dev/3/tv/1396?append_to_response=moods" -H "Authorization: Bearer $AMODB_KEY"把 moods 追加到详情调用时,moods 键位于记录的顶层,与 title 或 name 并列。它包含 source 和 results,自己没有 id。这只花一次请求,而两次单独调用要花两次。
如何解读刻度
avg 字段是 0 到 10 的强度。数字越大,说明这种情绪在作品中越强。
| 范围 | 解读 |
|---|---|
| 0 到 2.9 | 这种情绪很弱或不存在。 |
| 3 到 5.9 | 这种情绪存在。 |
| 6 到 7.9 | 这种情绪很明显。 |
| 8 到 10 | 这种情绪决定了作品的基调。 |
这些区间只是对你的界面的建议,不是响应中的字段。values 数组保存平均值背后的读数,刻度相同。
构建徽章和筛选
情绪适用于三种常见的界面模式。请根据你的目录选择阈值并加以调整。
| 模式 | 规则 | 说明 |
|---|---|---|
| 徽章 | 最多显示 3 个 avg 为 6 或更高的情绪 | 先按 avg 排序。 |
| 指数条 | 把条的宽度设为 avg 乘以 10 的百分比 | 刻度是 0 到 10。 |
| 筛选标签 | 匹配所选情绪为 7 或更高的作品 | 先按作品获取指数,再在本地筛选。 |
function topMoods(results, min = 6, limit = 3) {
return results
.filter((m) => m.avg >= min)
.sort((a, b) => b.avg - a.avg)
.slice(0, limit)
.map((m) => m.name);
}
function matchesMood(results, name, min = 7) {
return results.some((m) => m.name === name && m.avg >= min);
}空的 results 数组应渲染为没有徽章,而不是错误。
错误
错误响应体包含 success、status_code 和 status_message,与 TMDB 使用的字段相同。
| HTTP | status_code | 何时出现 |
|---|---|---|
| 401 | 7 | 密钥缺失或错误。 |
| 402 | 36 | 套餐周期已结束。 |
| 429 | 25 | 超过每分钟请求数。请等待 Retry-After 秒。 |
情绪接口对未知 ID 不返回 404。它返回 200 和空的 results 数组,source 为 null 或缺失。追加到详情时,未知 ID 由详情调用返回 404。完整列表见错误,限制见速率限制。