Постери фільмів із хоста зображень без ключа

URL постера має вигляд https://img.amodb.dev/t/p/{size}/{file}. Частина з назвою файлу це рядок poster_path з будь-якої відповіді про фільм, пошуку чи списку, і він починається зі скісної риски. Частина з розміром це назва, наприклад w342. Зображення не потребують ключа, тож браузери й застосунки можуть завантажувати їх напряму. JSON, який повідомляє назву файлу, усе ще потребує вашого ключа, а amodb це незалежний API, що працює за протоколом TMDB v3, тож наявний код для зображень продовжує працювати після зміни хоста.

Що ви отримуєте:

  • Постери, фони (backdrop), логотипи, фото профілів і кадри серій на одному хості.
  • Десять назв розмірів, від w92 до original.
  • Списки постерів для кожного тайтлу з мовою, шириною та висотою в кожному елементі.
  • 30-денний edge-кеш для зображень.

Які дані ви отримуєте

ЗображенняЗвідки береться назва файлуПоширені розміри
Постер фільмуposter_path у /3/movie/{movie_id} і в спискахw92, w154, w185, w342, w500, w780, original
Фон (backdrop)backdrop_pathw300, w780, w1280, original
Фото персониprofile_path у /3/person/{person_id}w185, h632, original
Логотип компанії або телемережіlogo_pathw92, w154, w185, w300, w500, original
Кадр серіїstill_pathw92, w185, w300, original
Усі постери одного тайтлуGET /3/movie/{movie_id}/imagesМасив posters

Серіали, сезони та колекції теж мають poster_path. Прочитайте точні списки розмірів із блоку images у GET /3/configuration один раз на старті, а не вписуйте їх у код. Довідник зображень на сторінці API зображень.

Почніть за 3 кроки

  1. Оберіть тариф на сторінці ціни. Він визначає ліміт викликів JSON: 20, 40 або 120 запитів на хвилину.
  2. Створіть ключ у кабінеті акаунта.
  3. Прочитайте poster_path із запиту деталей або списку, а потім додайте його після хоста зображень і назви розміру.

Приклад запиту

Програма на Go виводить постери The Matrix (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)
}

Скорочена відповідь images для include_image_language=en,null: 3 зі 145 постерів, англійський, найширший англійський і без тексту. Відповідь також містить 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 вище друкує srcset із кандидатами 185w, 342w, 500w і 780w. Поєднайте його з атрибутом sizes, що відповідає вашій верстці, наприклад sizes="(max-width: 600px) 45vw, 185px" на елементі 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 днів на периферії

Ціни

Завантаження зображень не потребують ключа. Ваш тариф обмежує лише виклики JSON, що дають назви файлів, а відповіді зі списками вже містять poster_path для кожного елемента, тож один запит списку наповнює цілу сітку. Оберіть 20, 40 або 120 запитів на хвилину на сторінці ціни. Доступ передплачується на 1, 3, 6, 12 або 24 місяці зі знижками 0, 10, 20, 30 і 40 відсотків, нічого не поновлюється саме, а безкоштовного тарифу немає.