无需密钥的电影海报图片主机
海报 URL 是 https:/。file 部分是任意电影、搜索或列表响应中的 poster_path 字符串,以斜杠开头。size 部分是 w342 这样的名称。图片无需密钥,因此浏览器和应用可以直接加载。告诉你文件名的 JSON 仍然需要你的密钥。amodb 是使用 TMDB v3 协议的独立 API,所以更换主机后,现有的图片代码仍可继续使用。
你会得到:
- 同一个主机上的海报、背景图、标志、人物照片和剧集剧照。
- 十种尺寸名,从
w92到original。 - 每部作品的海报列表,每项带有语言、宽度和高度。
- 图片在边缘缓存 30 天。
可获取的数据
| 图片 | 文件名来自 | 常用尺寸 |
|---|---|---|
| 电影海报 | /3/movie/{movie_id} 和列表中的 poster_path | w92、w154、w185、w342、w500、w780、original |
| 背景图 | backdrop_path | w300、w780、w1280、original |
| 人物照片 | /3/person/{person_id} 上的 profile_path | w185、h632、original |
| 公司或电视网标志 | logo_path | w92、w154、w185、w300、w500、original |
| 剧集剧照 | still_path | w92、w185、w300、original |
| 一部作品的所有海报 | GET / | posters 数组 |
电视剧、季和系列合集也带有 poster_path。请在启动时从 GET /3/configuration 的 images 块读取一次确切的尺寸列表,而不是写死。图片参考见图片。
三步开始
- 在定价页选择套餐。它决定 JSON 调用的速率:每分钟 20、40 或 120 个请求。
- 在账户后台创建密钥。
- 从详情或列表调用中读取
poster_path,再把它接到图片主机和尺寸名之后。
请求示例
这个 Go 程序列出《黑客帝国》(电影 ID 603)的英文海报和不含文字的海报,选出最宽的一张,打印现成的 srcset,并保存 w342 文件。密钥只用于 JSON 调用。
# the JSON call needs the key
curl -s "https://api.amodb.dev/3/movie/603/images?include_image_language=en,null" \
-H "Authorization: Bearer $AMODB_KEY"
# the image call does not
curl -s -o poster.jpg "https://img.amodb.dev/t/p/w342/aOIuZAjPaRIE6CMzbazvcHuHXDc.jpg"package main
import (
"encoding/json"
"fmt"
"io"
"net/http"
"os"
"strings"
"time"
)
const imgBase = "https://img.amodb.dev/t/p/"
type poster struct {
FilePath string `json:"file_path"`
Lang *string `json:"iso_639_1"`
Width int `json:"width"`
}
type images struct {
Posters []poster `json:"posters"`
}
func srcset(file string) string {
var parts []string
for _, w := range []int{185, 342, 500, 780} {
parts = append(parts, fmt.Sprintf("%sw%d%s %dw", imgBase, w, file, w))
}
return strings.Join(parts, ", ")
}
func main() {
client := &http.Client{Timeout: 10 * time.Second}
url := "https://api.amodb.dev/3/movie/603/images?include_image_language=en,null"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Set("Authorization", "Bearer "+os.Getenv("AMODB_KEY"))
res, err := client.Do(req)
if err != nil {
panic(err)
}
defer res.Body.Close()
if res.StatusCode != http.StatusOK {
panic(res.Status)
}
var imgs images
if err := json.NewDecoder(res.Body).Decode(&imgs); err != nil {
panic(err)
}
if len(imgs.Posters) == 0 {
fmt.Println("no posters")
return
}
best := imgs.Posters[0]
for _, p := range imgs.Posters {
if p.Width > best.Width {
best = p
}
}
lang := "none"
if best.Lang != nil {
lang = *best.Lang
}
fmt.Println("best poster:", best.FilePath, "language:", lang, "width:", best.Width)
fmt.Println("srcset:", srcset(best.FilePath))
// Image requests carry no key.
pic, err := client.Get(imgBase + "w342" + best.FilePath)
if err != nil {
panic(err)
}
defer pic.Body.Close()
if pic.StatusCode != http.StatusOK {
panic(pic.Status)
}
out, err := os.Create("poster.jpg")
if err != nil {
panic(err)
}
defer out.Close()
io.Copy(out, pic.Body)
}include_ 的精简 images 响应:145 张海报中的 3 张,分别是一张英文海报、最宽的英文海报和一张不含文字的海报。响应还包含 backdrops 和 logos,此处省略。
{
"id": 603,
"posters": [
{
"aspect_ratio": 0.667,
"height": 2250,
"iso_639_1": "en",
"file_path": "/dXNAPwY7VrqMAo51EKhhCJfaGb5.jpg",
"vote_average": 0,
"vote_count": 0,
"width": 1500
},
{
"aspect_ratio": 0.667,
"height": 3000,
"iso_639_1": "en",
"file_path": "/aOIuZAjPaRIE6CMzbazvcHuHXDc.jpg",
"vote_average": 0,
"vote_count": 0,
"width": 2000
},
{
"aspect_ratio": 0.701,
"height": 1426,
"iso_639_1": null,
"file_path": "/iLWzJxatuwwMT76dtMuwh3FEp2X.jpg",
"vote_average": 0,
"vote_count": 0,
"width": 1000
}
]
}选择尺寸
w 尺寸中的数字是图像宽度(像素),h632 表示高度。小尺寸节省带宽,大尺寸能在高密度屏幕上保留细节。
| 尺寸 | 典型用途 |
|---|---|
w92 | 搜索建议和很小的列表行 |
w154、w185 | 密集的列表和卡片 |
w342 | 手机上的网格卡片 |
w500 | 详情页 |
w780 | 大屏幕和 2x 显示屏 |
original | 存档或打印,未缩放的原文件 |
提供多个宽度,让浏览器自己选择。上面的 Go 程序会打印一个带有 185w、342w、500w 和 780w 候选项的 srcset。请搭配与你的布局相符的 sizes 属性,例如 img 元素上的 sizes=。
海报语言
posters 中的每一项都有 iso_639_1 值,要么是语言代码,要么是 null(表示不含文字的图稿)。include_image_language 参数接受用逗号分隔的代码列表。
| 取值 | 返回 |
|---|---|
en | 标记为英语的海报 |
en,null | 英语海报和不含文字的海报 |
null | 仅限不含文字的海报 |
较好的回退顺序是:用户语言的海报,然后是不含文字的海报,最后是英语海报。在每一组内部按 width 排序,并列时保留第一张。电影和电视剧图片上的 vote_average 和 vote_count 均为 0,所以它们无法用于排名。海报语言描述的是印在图稿上的文字,因此与 14 种界面语言无关。请检查返回内容的 iso_639_1,因为可用集合取决于作品。
保存和缓存海报
- 保存
poster_path,而不是完整 URL。之后可以据此拼出任意尺寸。 - 边缘节点缓存图片 30 天。详情缓存 6 小时,所以在此之后请重新读取
poster_path,看看是否有变化。 - 把密钥留在你的服务器上。只把图片 URL 发给浏览器。
- 当
poster_path为 null 时,请渲染占位图,而不是裂开的图片。
对比
| 能力 | 抓取页面获取图片 | 自己托管副本 | amodb 图片主机 |
|---|---|---|---|
| 是否需要密钥 | 无,适用各网站的条款 | 无 | 图片无需密钥 |
| 尺寸变体 | 页面提供什么尺寸就是什么 | 你自己生成并存储每一个 | URL 中的固定尺寸名,从 w92 到 original |
| 查找文件 | 解析 HTML | 你自己的数据库 | 每个响应中的 poster_path |
| 图稿语言 | 逐页处理 | 取决于你收集了什么 | images 接口上的 include_image_language |
| 存储与带宽 | 你的,外加来源网站的 | 你的 | 浏览器从 img.amodb.dev 加载 |
| 缓存 | 你的 | 你的 | 边缘缓存 30 天 |
定价
图片下载不带密钥。套餐只限制为你提供文件名的 JSON 调用,而列表响应已经为每一项包含了 poster_path,所以一次列表调用就能填满整个网格。请在定价页选择每分钟 20、40 或 120 个请求。访问需预付 1、3、6、12 或 24 个月,分别享受 0、10、20、30 和 40% 的折扣,不会自动续费,也没有免费额度。