Постеры фильмов с хоста изображений без ключа
URL постера выглядит так: https:/. Файловая часть: строка poster_path из ответа любого фильма, поиска или списка, и она начинается со слеша. Часть с размером это название размера, например w342. Изображениям ключ не нужен, поэтому браузеры и приложения могут грузить их напрямую. JSON, который сообщает имя файла, по-прежнему требует ключ, а amodb является независимым API, использующим протокол TMDB v3, поэтому существующий код для изображений продолжает работать после смены хоста.
Что вы получаете:
- Постеры, фоны (backdrop), логотипы, фото профилей и кадры серий на одном хосте.
- Десять названий размеров, от
w92доoriginal. - Списки постеров по каждому тайтлу, с языком, шириной и высотой у каждого элемента.
- Edge-кэш изображений на 30 дней.
Какие данные вы получаете
| Изображение | Откуда берется имя файла | Типичные размеры |
|---|---|---|
| Постер фильма | poster_path в /3/movie/{movie_id} и в списках | w92, w154, w185, w342, w500, w780, original |
| Фон (backdrop) | backdrop_path | w300, w780, w1280, original |
| Фото человека | profile_path в /3/person/{person_id} | w185, h632, original |
| Логотип компании или телесети | logo_path | w92, w154, w185, w300, w500, original |
| Кадр серии | still_path | w92, w185, w300, original |
| Все постеры одного тайтла | GET / | Массив posters |
poster_path есть и у сериалов, сезонов и коллекций. Точные списки размеров один раз при запуске читайте из блока images в GET /3/configuration, а не зашивайте в код. Справочник по изображениям находится на странице API изображений.
Начало работы в 3 шага
- Выберите тариф на странице цены. Он задает лимит вызовов JSON: 20, 40 или 120 запросов в минуту.
- Создайте ключ в личном кабинете.
- Прочитайте
poster_pathиз вызова данных или списка, затем подставьте его после хоста изображений и названия размера.
Пример запроса
Программа на Go перечисляет постеры The Matrix (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)
}Сокращенный ответ images для include_: 3 из 145 постеров, английский, самый широкий английский и без текста. В ответе есть также 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 выше выводит srcset с вариантами 185w, 342w, 500w и 780w. Сочетайте его с атрибутом sizes, подходящим вашей верстке, например sizes= на элементе img.
Языки постеров
У каждого элемента 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. Из него позже можно собрать любой размер. - Edge-кэш хранит изображения 30 дней. Данные хранятся в кэше 6 часов, поэтому после этого срока снова читайте
poster_path, чтобы узнать, изменился ли он. - Держите ключ на своем сервере. Браузеру отправляйте только URL изображений.
- Если
poster_pathравен null, показывайте заглушку вместо сломанного изображения.
Сравнение
| Возможность | Парсинг страниц ради изображений | Свои копии на своем хостинге | Хост изображений amodb |
|---|---|---|---|
| Нужен ли ключ | Нет, действуют условия каждого сайта | Нет | Для изображений ключ не нужен |
| Варианты размеров | Любой размер, который отдает страница | Вы создаете и храните каждый сами | Фиксированные названия размеров в URL, от w92 до original |
| Поиск файла | Разбор HTML | Ваша собственная база | poster_path в каждом ответе |
| Языки изображений | Страница за страницей | Что вы собрали | include_image_language на эндпоинтах изображений |
| Хранилище и трафик | Ваши, плюс источника | Ваши | Браузер загружает с img.amodb.dev |
| Кэш | Ваш | Ваш | 30 дней в edge-кэше |
Цены
Загрузка изображений идет без ключа. Тариф ограничивает только вызовы JSON, которые дают имена файлов, а ответы со списками уже включают poster_path для каждого элемента, поэтому один вызов списка наполняет всю сетку. Выберите 20, 40 или 120 запросов в минуту на странице цены. Доступ оплачивается заранее на 1, 3, 6, 12 или 24 месяца со скидкой 0, 10, 20, 30 и 40 процентов, сам он не продлевается, бесплатного тарифа нет.