无需密钥的电影海报图片主机

海报 URL 是 https://img.amodb.dev/t/p/{size}/{file}。file 部分是任意电影、搜索或列表响应中的 poster_path 字符串,以斜杠开头。size 部分是 w342 这样的名称。图片无需密钥,因此浏览器和应用可以直接加载。告诉你文件名的 JSON 仍然需要你的密钥。amodb 是使用 TMDB v3 协议的独立 API,所以更换主机后,现有的图片代码仍可继续使用。

你会得到:

  • 同一个主机上的海报、背景图、标志、人物照片和剧集剧照。
  • 十种尺寸名,从 w92 到 original。
  • 每部作品的海报列表,每项带有语言、宽度和高度。
  • 图片在边缘缓存 30 天。

可获取的数据

图片文件名来自常用尺寸
电影海报/3/movie/{movie_id} 和列表中的 poster_pathw92、w154、w185、w342、w500、w780、original
背景图backdrop_pathw300、w780、w1280、original
人物照片/3/person/{person_id} 上的 profile_pathw185、h632、original
公司或电视网标志logo_pathw92、w154、w185、w300、w500、original
剧集剧照still_pathw92、w185、w300、original
一部作品的所有海报GET /3/movie/{movie_id}/imagesposters 数组

电视剧、季和系列合集也带有 poster_path。请在启动时从 GET /3/configuration 的 images 块读取一次确切的尺寸列表,而不是写死。图片参考见图片。

三步开始

  1. 在定价页选择套餐。它决定 JSON 调用的速率:每分钟 20、40 或 120 个请求。
  2. 在账户后台创建密钥。
  3. 从详情或列表调用中读取 poster_path,再把它接到图片主机和尺寸名之后。

请求示例

这个 Go 程序列出《黑客帝国》(电影 ID 603)的英文海报和不含文字的海报,选出最宽的一张,打印现成的 srcset,并保存 w342 文件。密钥只用于 JSON 调用。

bashgo
# 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_image_language=en,null 的精简 images 响应:145 张海报中的 3 张,分别是一张英文海报、最宽的英文海报和一张不含文字的海报。响应还包含 backdrops 和 logos,此处省略。

JSON
{
  "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="(max-width: 600px) 45vw, 185px"。

海报语言

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% 的折扣,不会自动续费,也没有免费额度。