API delle immagini e host delle immagini
Gli endpoint delle immagini elencano locandine, sfondi, loghi, profili e fermi immagine di un titolo come percorsi di file. Poi carichi ogni file da img.amodb.dev in una dimensione fissa, senza chiave e con una cache edge di 30 giorni. Percorsi e JSON seguono TMDB v3, quindi il codice per le immagini esistente funziona dopo un cambio di URL di base.
Ottenere le immagini di un film
GET / elenca tutte le immagini note di un film come tre array: backdrops, logos e posters. Ogni voce ha un file_path, la sua dimensione in pixel e un tag di lingua. Il file stesso non è nel JSON. Lo carichi dall'host delle immagini in un secondo passaggio.
L'esempio chiede le immagini in inglese e senza testo, sceglie la prima locandina inglese e poi scarica quel file con 500 pixel di larghezza.
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_idpercorsoobbligatorioID numerico del film, per esempio550.api_keyqueryuno dei dueLa tua chiave. Usa questa o l'headerAuthorization: Bearer.include_image_languagequeryCodici ISO 639-1 separati da virgole. Aggiunginullper includere le immagini senza testo, per esempioen,null. Tornano solo le lingue elencate. Senza, ottieni ogni lingua.languagequeryAccettato ma ignorato su questo endpoint. Usainclude_image_languageper scegliere le lingue.
Campi della risposta
| Campo | Tipo | Note |
|---|---|---|
id | intero | L'ID del film. |
backdrops, logos, posters | array | Un array per tipo di immagine, in quest'ordine di chiavi. Ognuno può essere vuoto. |
file_path | stringa | Inizia con una barra. Da accodare a una dimensione sull'host delle immagini. Locandine e sfondi sono .jpg, i loghi sono .png o .svg. |
width, height | intero | Dimensione in pixel del file originale. 0 quando la dimensione non è nota. |
aspect_ratio | numero | Larghezza divisa per altezza. Le locandine stanno vicino a 0.667, gli sfondi vicino a 1.778. 0 quando la dimensione non è nota. |
iso_639_1 | stringa o null | Lingua del testo sull'immagine. null significa nessun testo. |
vote_average, vote_count | numero, intero | Sempre 0 per le immagini di film e serie, quindi non possono ordinare le immagini. Mantieni l'ordine restituito dall'API. |
Risposta di esempio
Sono mostrate due voci per 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
}
]
}La seconda locandina mostra una voce la cui dimensione non è nota. Il file si carica comunque.
Costruire l'URL di un'immagine
Unisci tre parti: https:/, un segmento di dimensione e il file_path. Il percorso inizia già con una barra, quindi https:/ più / è un URL completo.
Una dimensione è w più una larghezza in pixel, h più un'altezza in pixel, oppure original per il file salvato. L'host serve dieci dimensioni: w92, w154, w185, w300, w342, w500, w780, w1280, h632 e original. Qualsiasi altra dimensione, come w400, risponde 404. /3/configuration elenca le dimensioni adatte a ogni tipo di immagine.
| Tipo | Campo di configurazione | Dimensioni |
|---|---|---|
| Locandina | poster_sizes | w92, w154, w185, w342, w500, w780, original |
| Sfondo | backdrop_sizes | w300, w780, w1280, original |
| Logo | logo_sizes | w92, w154, w185, w300, w500, original |
| Profilo | profile_sizes | w185, h632, original |
| Fermo immagine | still_sizes | w92, w185, w300, original |
L'host non controlla il tipo, quindi una locandina si carica anche a w1280. Resta sulle dimensioni elencate per il tipo, così il tuo codice corrisponde alla configurazione e a qualsiasi client TMDB.
L'host delle immagini non richiede chiave, e l'edge tiene ogni file per 30 giorni. Poiché non si invia alcuna chiave, i caricamenti delle immagini non usano le tue richieste al minuto. Le risposte portano Access-Control-Allow-Origin: *, quindi un browser può caricarle da qualsiasi pagina. Una dimensione sconosciuta o un file sconosciuto risponde 404 con un corpo JSON.
Immagini responsive con srcset
Scegli la dimensione più piccola che copra ancora la larghezza mostrata moltiplicata per la densità dello schermo. Una locandina mostrata a 171 pixel CSS di larghezza richiede w342 su uno schermo 2x. Questa funzione di aiuto costruisce un srcset da un percorso salvato.
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">`);Altri endpoint delle immagini
Tutti i percorsi qui sotto usano la base https:/ e restituiscono gli array indicati nella seconda colonna.
| Metodo e percorso | Array restituiti | Parametri |
|---|---|---|
GET / | backdrops, logos, posters | include_image_language |
GET / | posters, sempre vuoto | nessuno |
GET / | stills, una voce con width e height a 0 | nessuno |
GET / | profiles | nessuno |
Per film e serie puoi anche aggiungere append_ a una chiamata di dettagli. Anche lì funziona include_image_language. Il blocco aggiunto non ha un id proprio.
I profili delle persone sono l'unico posto in cui vote_average porta un punteggio reale. L'id di una risposta di stagione o di episodio è l'ID della stagione o dell'episodio. Vedi persone e serie TV per le schede padre.
amodb non offre percorsi di immagini per collezioni, società ed emittenti. Le loro schede contengono già un poster_path, un backdrop_path o un logo_path, descritti nelle pagine collezioni e società ed emittenti.
L'endpoint di configurazione
GET /3/configuration restituisce un blocco images con secure_base_url impostato su https:/, base_url (la forma http semplice), e gli elenchi di dimensioni backdrop_sizes, logo_sizes, poster_sizes, profile_sizes e still_sizes. Leggilo una volta all'avvio, usa la forma sicura e costruisci gli URL da esso invece di scrivere le dimensioni nel codice. L'edge lo tiene in cache per 24 ore.
Errori
| HTTP | status_code | Quando |
|---|---|---|
| 401 | 7 | La chiave manca o è sbagliata su una chiamata JSON. |
| 402 | 36 | Il periodo del piano è terminato. |
| 404 | 34 | Nessuna persona, stagione o episodio con quell'ID, o una dimensione o un file sconosciuto sull'host delle immagini. |
| 405 | 37 | Hai usato un metodo di scrittura su un percorso di immagini. |
| 429 | 25 | Hai superato le richieste al minuto. Attendi i secondi di Retry-After. |
Un ID di film o serie che non esiste qui non è un errore: il percorso delle immagini risponde 200 con array vuoti, mentre il percorso dei dettagli risponde 404. Vedi errori per l'elenco completo. Le richieste dei file immagine sono semplici caricamenti HTTP, quindi controlla il codice di stato della risposta invece di analizzare un corpo JSON.
Note pratiche
- Salva
file_pathnel tuo database e costruisci l'URL al momento della visualizzazione. Una nuova dimensione o un nuovo host costa così una sola modifica al codice. - Passa
include_image_languagecon la tua lingua di visualizzazione piùnull, per esempioru,null, così non compaiono locandine con testo straniero. - Un array vuoto è un normale 200. Ripiega sul
poster_pathdella scheda dei dettagli del film. - Usa
w1280per gli sfondi a tutta larghezza ew780per le schede.originalè il file salvato a piena risoluzione ed è molto più pesante diw780. - Le copie sull'edge durano 30 giorni e sono condivise, quindi un file richiesto da un client viene servito dalla cache al successivo.