API imagini și gazdă de imagini
Endpoint-urile de imagini listează posterele, imaginile de fundal, logourile, profilurile și cadrele unui titlu ca căi de fișiere. Apoi încarci fiecare fișier de la img.amodb.dev într-o dimensiune fixă, fără cheie și cu cache la margine de 30 de zile. Căile și JSON-ul se potrivesc cu TMDB v3, deci codul existent pentru imagini funcționează după schimbarea URL-ului de bază.
Obține imaginile unui film
GET / listează fiecare imagine cunoscută a unui film în trei array-uri: backdrops, logos și posters. Fiecare intrare are un file_path, dimensiunea în pixeli și o etichetă de limbă. Fișierul în sine nu se află în JSON. Îl încarci de la gazda de imagini într-un al doilea pas.
Exemplul cere imagini în engleză și fără text, alege primul poster în engleză și apoi preia acel fișier la 500 de pixeli lățime.
curl -s "https://api.amodb.dev/3/movie/550/images?include_image_language=en,null" \
-H "Authorization: Bearer $AMODB_KEY"
curl -s -o poster.jpg -w "%{http_code}\n" \
"https://img.amodb.dev/t/p/w500/jSziioSwPVrOy9Yow3XhWIBDjq1.jpg"const url = 'https://api.amodb.dev/3/movie/550/images?include_image_language=en,null';
const res = await fetch(url, { headers: { Authorization: `Bearer ${process.env.AMODB_KEY}` } });
if (!res.ok) throw new Error(`amodb returned ${res.status}`);
const { posters } = await res.json();
if (posters.length === 0) throw new Error('no posters');
const poster = posters.find((p) => p.iso_639_1 === 'en') ?? posters[0];
const posterUrl = `https://img.amodb.dev/t/p/w500${poster.file_path}`;
const img = await fetch(posterUrl);
console.log(img.status, img.headers.get('content-type'), posterUrl);import os
import requests
r = requests.get(
"https://api.amodb.dev/3/movie/550/images",
params={"include_image_language": "en,null"},
headers={"Authorization": f"Bearer {os.environ['AMODB_KEY']}"},
timeout=10,
)
r.raise_for_status()
posters = r.json()["posters"]
if not posters:
raise SystemExit("no posters")
poster = next((p for p in posters if p["iso_639_1"] == "en"), posters[0])
poster_url = "https://img.amodb.dev/t/p/w500" + poster["file_path"]
img = requests.get(poster_url, timeout=10)
print(img.status_code, img.headers.get("content-type"), poster_url)<?php
$url = 'https://api.amodb.dev/3/movie/550/images?include_image_language=en,null';
$ch = curl_init($url);
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");
}
$posters = json_decode($body, true)['posters'];
if (!$posters) {
throw new RuntimeException('no posters');
}
$poster = $posters[0];
foreach ($posters as $p) {
if ($p['iso_639_1'] === 'en') {
$poster = $p;
break;
}
}
$posterUrl = 'https://img.amodb.dev/t/p/w500' . $poster['file_path'];
$img = curl_init($posterUrl);
curl_setopt_array($img, [CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 10]);
curl_exec($img);
echo curl_getinfo($img, CURLINFO_HTTP_CODE), ' ', curl_getinfo($img, CURLINFO_CONTENT_TYPE), ' ', $posterUrl, PHP_EOL;
curl_close($img);package main
import (
"encoding/json"
"fmt"
"net/http"
"os"
"time"
)
type Images struct {
Posters []struct {
FilePath string `json:"file_path"`
Language string `json:"iso_639_1"`
} `json:"posters"`
}
func main() {
url := "https://api.amodb.dev/3/movie/550/images?include_image_language=en,null"
req, _ := http.NewRequest("GET", url, 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 images Images
if err := json.NewDecoder(res.Body).Decode(&images); err != nil || len(images.Posters) == 0 {
panic("no posters")
}
poster := images.Posters[0]
for _, p := range images.Posters {
if p.Language == "en" {
poster = p
break
}
}
posterURL := "https://img.amodb.dev/t/p/w500" + poster.FilePath
img, err := client.Get(posterURL)
if err != nil {
panic(err)
}
defer img.Body.Close()
fmt.Println(img.StatusCode, img.Header.Get("Content-Type"), posterURL)
}Parametri
movie_idcaleobligatoriuID numeric de film, de exemplu550.api_keyinterogareuna dintre cele douăCheia ta. Folosește-o pe aceasta sau antetulAuthorization: Bearer.include_image_languageinterogareCoduri ISO 639-1 separate prin virgulă. Adaugănullca să incluzi imaginile fără text, de exempluen,null. Revin doar limbile listate. Fără el primești toate limbile.languageinterogareAcceptat, dar ignorat pe acest endpoint. Foloseșteinclude_image_languageca să alegi limbile.
Câmpurile răspunsului
| Câmp | Tip | Observații |
|---|---|---|
id | număr întreg | ID-ul filmului. |
backdrops, logos, posters | array | Câte un array pentru fiecare fel de imagine, în această ordine a cheilor. Fiecare poate fi gol. |
file_path | șir | Începe cu o bară oblică. Adaugă-l la o dimensiune de pe gazda de imagini. Posterele și imaginile de fundal sunt .jpg, logourile sunt .png sau .svg. |
width, height | număr întreg | Dimensiunea în pixeli a fișierului original. 0 când dimensiunea nu se cunoaște. |
aspect_ratio | număr | Lățimea împărțită la înălțime. Posterele sunt aproape de 0.667, imaginile de fundal aproape de 1.778. 0 când dimensiunea nu se cunoaște. |
iso_639_1 | șir sau null | Limba textului de pe imagine. null înseamnă fără text. |
vote_average, vote_count | număr, număr întreg | Mereu 0 la imaginile de film și de serial, deci nu pot ordona imaginile. Păstrează ordinea întoarsă de API. |
Exemplu de răspuns
Sunt arătate două intrări pe array.
{
"id": 550,
"backdrops": [
{
"aspect_ratio": 1.778,
"height": 1440,
"iso_639_1": null,
"file_path": "/c6OLXfKAk5BKeR6broC8pYiCquX.jpg",
"vote_average": 0,
"vote_count": 0,
"width": 2560
},
{
"aspect_ratio": 1.778,
"height": 1080,
"iso_639_1": "en",
"file_path": "/b9HyPoxwxjxkWEUL5ErZdhApQe2.jpg",
"vote_average": 0,
"vote_count": 0,
"width": 1920
}
],
"logos": [
{
"aspect_ratio": 4.638,
"height": 389,
"iso_639_1": "en",
"file_path": "/7Uqhv24pGJs4Ns31NoOPWFJGWNG.png",
"vote_average": 0,
"vote_count": 0,
"width": 1804
},
{
"aspect_ratio": 0.848,
"height": 1295,
"iso_639_1": "en",
"file_path": "/4XkF0Rf7gvSfea8fYLFbU5tmuJw.png",
"vote_average": 0,
"vote_count": 0,
"width": 1098
}
],
"posters": [
{
"aspect_ratio": 0.667,
"height": 3000,
"iso_639_1": "en",
"file_path": "/jSziioSwPVrOy9Yow3XhWIBDjq1.jpg",
"vote_average": 0,
"vote_count": 0,
"width": 2000
},
{
"aspect_ratio": 0,
"height": 0,
"iso_639_1": null,
"file_path": "/qkrH7rjYKU4KOwwIl6wF6H3ISvm.jpg",
"vote_average": 0,
"vote_count": 0,
"width": 0
}
]
}Al doilea poster arată o intrare a cărei dimensiune nu se cunoaște. Fișierul se încarcă totuși.
Construiește un URL de imagine
Îmbină trei părți: https:/, un segment de dimensiune și file_path. Calea începe deja cu o bară oblică, deci https:/ plus / este un URL complet.
O dimensiune este w plus o lățime în pixeli, h plus o înălțime în pixeli sau original pentru fișierul stocat. Gazda servește zece dimensiuni: w92, w154, w185, w300, w342, w500, w780, w1280, h632 și original. Orice altă dimensiune, precum w400, răspunde 404. /3/configuration listează dimensiunile care se potrivesc fiecărui fel de imagine.
| Fel | Câmp de configurare | Dimensiuni |
|---|---|---|
| Poster | poster_sizes | w92, w154, w185, w342, w500, w780, original |
| Imagine de fundal | backdrop_sizes | w300, w780, w1280, original |
| Logo | logo_sizes | w92, w154, w185, w300, w500, original |
| Profil | profile_sizes | w185, h632, original |
| Cadru | still_sizes | w92, w185, w300, original |
Gazda nu verifică felul, deci un poster se încarcă și la w1280. Rămâi la dimensiunile listate pentru fiecare fel, ca să se potrivească codul tău cu configurația și cu orice client TMDB.
Gazda de imagini nu cere cheie, iar marginea ține fiecare fișier 30 de zile. Pentru că nu se trimite nicio cheie, încărcările de imagini nu consumă cererile tale pe minut. Răspunsurile poartă Access-Control-Allow-Origin: *, deci un browser le poate încărca de pe orice pagină. O dimensiune necunoscută sau un fișier necunoscut răspunde 404 cu un corp JSON.
Imagini responsive cu srcset
Alege cea mai mică dimensiune care acoperă totuși lățimea afișată înmulțită cu densitatea ecranului. Un poster afișat la 171 de pixeli CSS lățime are nevoie de w342 pe un ecran 2x. Acest helper construiește un srcset dintr-o cale stocată.
const WIDTHS = [185, 342, 500, 780];
function posterSrcset(filePath) {
return WIDTHS.map((w) => `https://img.amodb.dev/t/p/w${w}${filePath} ${w}w`).join(', ');
}
const path = '/jSziioSwPVrOy9Yow3XhWIBDjq1.jpg';
console.log(`<img src="https://img.amodb.dev/t/p/w342${path}" srcset="${posterSrcset(path)}" sizes="(max-width: 600px) 50vw, 342px" alt="Fight Club poster">`);Alte endpoint-uri de imagini
Toate căile de mai jos folosesc baza https:/ și întorc array-urile numite în a doua coloană.
| Metodă și cale | Array-uri întoarse | Parametri |
|---|---|---|
GET / | backdrops, logos, posters | include_image_language |
GET / | posters, mereu gol | niciunul |
GET / | stills, o intrare cu width și height setate la 0 | niciunul |
GET / | profiles | niciunul |
Pentru filme și seriale poți adăuga și append_ la un apel de detalii. include_image_language funcționează și acolo. Blocul atașat nu are un id propriu.
Profilurile persoanelor sunt singurul loc în care vote_average poartă un scor real. id din răspunsul unui sezon sau episod este ID-ul sezonului sau episodului. Vezi persoane și seriale TV pentru înregistrările părinte.
amodb nu oferă căi de imagini pentru colecții, companii și rețele. Înregistrările lor conțin deja un singur poster_path, backdrop_path sau logo_path, descrise la colecții și companii și rețele.
Endpoint-ul de configurare
GET /3/configuration întoarce un bloc images cu secure_base_url setat la https:/, base_url (forma http simplă) și listele de dimensiuni backdrop_sizes, logo_sizes, poster_sizes, profile_sizes și still_sizes. Citește-l o dată la pornire, folosește forma securizată și construiește URL-urile din el în loc să scrii fix dimensiunile. Marginea îl ține în cache 24 de ore.
Erori
| HTTP | status_code | Când |
|---|---|---|
| 401 | 7 | Cheia lipsește sau este greșită la un apel JSON. |
| 402 | 36 | Perioada planului s-a încheiat. |
| 404 | 34 | Nu există o persoană, un sezon sau un episod cu acel ID, sau o dimensiune ori un fișier necunoscut pe gazda de imagini. |
| 405 | 37 | Ai folosit o metodă de scriere pe o cale de imagini. |
| 429 | 25 | Ai depășit cererile pe minut. Așteaptă numărul de secunde din Retry-After. |
Un ID de film sau de serial care nu există nu este aici o eroare: calea de imagini răspunde 200 cu array-uri goale, în timp ce calea de detalii răspunde 404. Vezi erori pentru lista completă. Cererile de fișiere de imagine sunt încărcări HTTP simple, deci verifică codul de stare al răspunsului în loc să parsezi un corp JSON.
Note practice
- Stochează
file_pathîn baza ta de date și construiește URL-ul în momentul afișării. O dimensiune sau o gazdă nouă costă atunci o singură schimbare de cod. - Transmite
include_image_languagecu limba ta de afișare plusnull, de exempluru,null, ca să nu apară postere cu text străin. - Un array gol este un 200 normal. Revino la
poster_pathdin fișa de detalii film. - Folosește
w1280pentru imaginile de fundal pe toată lățimea șiw780pentru carduri.originaleste fișierul stocat la rezoluție completă și este mult mai mare decâtw780. - Copiile de la margine trăiesc 30 de zile și sunt partajate, deci un fișier cerut de un client este servit din cache următorului.