Locandine di film da un host di immagini senza chiave

L'URL di una locandina è https://img.amodb.dev/t/p/{size}/{file}. La parte file è la stringa poster_path di qualsiasi risposta di film, ricerca o lista, e inizia con una barra. La parte dimensione è un nome come w342. Le immagini non richiedono alcuna chiave, quindi browser e app possono caricarle direttamente. Il JSON che ti dà il nome del file richiede ancora la tua chiave, e amodb è un'API indipendente che parla il protocollo TMDB v3, quindi il codice per le immagini esistente continua a funzionare dopo un cambio di host.

Cosa ottieni:

  • Locandine, immagini di sfondo, loghi, foto del profilo e immagini degli episodi su un solo host.
  • Dieci nomi di dimensione, da w92 a original.
  • Liste di locandine per titolo, con lingua, larghezza e altezza di ogni elemento.
  • Una cache edge di 30 giorni per le immagini.

Quali dati ottieni

ImmagineIl nome del file viene daDimensioni comuni
Locandina del filmposter_path su /3/movie/{movie_id} e nelle listew92, w154, w185, w342, w500, w780, original
Immagine di sfondobackdrop_pathw300, w780, w1280, original
Foto della personaprofile_path su /3/person/{person_id}w185, h632, original
Logo di società o emittentelogo_pathw92, w154, w185, w300, w500, original
Immagine di un episodiostill_pathw92, w185, w300, original
Tutte le locandine di un titoloGET /3/movie/{movie_id}/imagesArray posters

Anche serie TV, stagioni e collezioni portano poster_path. Leggi una volta all'avvio gli elenchi esatti delle dimensioni dal blocco images di GET /3/configuration invece di scriverli nel codice. Il riferimento sulle immagini è nella pagina immagini.

Parti in 3 passaggi

  1. Scegli un piano nella pagina dei prezzi. Stabilisce la frequenza delle chiamate JSON: 20, 40 o 120 richieste al minuto.
  2. Crea una chiave nella dashboard del tuo account.
  3. Leggi poster_path da una chiamata di dettagli o di lista, poi mettilo dietro l'host delle immagini e un nome di dimensione.

Esempio di richiesta

Il programma in Go elenca le locandine di Matrix (ID film 603) in inglese e senza testo, sceglie la più larga, stampa un srcset pronto e salva il file w342. La chiave serve solo alla chiamata 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)
}

Una risposta ridotta delle immagini per include_image_language=en,null: 3 delle 145 locandine, una in inglese, la più larga tra quelle in inglese e una senza testo. La risposta contiene anche backdrops e logos, omessi qui.

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
    }
  ]
}

Scegliere una dimensione

Il numero in una dimensione w è la larghezza dell'immagine in pixel, e h632 è un'altezza. I nomi piccoli risparmiano banda, quelli grandi mantengono i dettagli sugli schermi ad alta densità.

DimensioneUso tipico
w92Suggerimenti di ricerca e righe di elenco minuscole
w154, w185Elenchi densi e schede
w342Tessere di una griglia su telefono
w500Pagina di dettaglio
w780Schermi grandi e display 2x
originalArchivio o stampa, il file non ridimensionato

Dai al browser più larghezze e lascia che scelga. Il programma in Go qui sopra stampa un srcset con candidati 185w, 342w, 500w e 780w. Abbinalo a un attributo sizes che corrisponda al tuo layout, per esempio sizes="(max-width: 600px) 45vw, 185px" sull'elemento img.

Lingue delle locandine

Ogni elemento di posters ha un valore iso_639_1, che è un codice di lingua oppure null per un'immagine senza testo. Il parametro include_image_language accetta un elenco di codici separati da virgole.

ValoreRestituisce
enLe locandine segnate come inglesi
en,nullLe locandine in inglese e quelle senza testo
nullSolo le locandine senza testo

Un buon ordine di ripiego è la locandina nella lingua dell'utente, poi una senza testo, poi l'inglese. All'interno di ogni gruppo ordina per width e tieni la prima in caso di parità. vote_average e vote_count valgono 0 sulle immagini di film e serie, quindi non ordinano nulla. Le lingue delle locandine descrivono il testo stampato sull'immagine, quindi non seguono le 14 lingue dell'interfaccia. Controlla iso_639_1 su ciò che torna, perché l'insieme dipende dal titolo.

Salvare e mettere in cache le locandine

  • Salva poster_path, non l'URL completo. Da esso si può costruire poi qualsiasi dimensione.
  • L'edge mette in cache le immagini per 30 giorni. I dettagli restano in cache 6 ore, quindi rileggi poster_path dopo quel tempo per vedere se è cambiato.
  • Tieni la chiave sul tuo server. Al browser invia solo gli URL delle immagini.
  • Quando poster_path è null, mostra un segnaposto invece di un'immagine rotta.

Confronto

FunzionalitàFare scraping delle immagini dalle pagineOspitare copie proprieHost di immagini di amodb
Chiave necessariaNessuna, valgono le condizioni di ogni sitoNessunaNessuna chiave per le immagini
Varianti di dimensioneQuella che serve la paginaLe generi e le salvi tutte tuNomi di dimensione fissi nell'URL, da w92 a original
Trovare il fileAnalizzare l'HTMLIl tuo databaseposter_path in ogni risposta
Lingue delle immaginiPagina per paginaQuelle che hai raccoltoinclude_image_language sugli endpoint delle immagini
Storage e bandaTuoi, più quelli della fonteTuoiIl browser carica da img.amodb.dev
CacheLa tuaLa tua30 giorni sull'edge

Prezzi

Il download delle immagini non richiede chiave. Il tuo piano limita solo le chiamate JSON che ti danno i nomi dei file, e le risposte di lista includono già poster_path per ogni elemento, quindi una sola chiamata di lista alimenta un'intera griglia. Scegli 20, 40 o 120 richieste al minuto nella pagina dei prezzi. L'accesso è prepagato per 1, 3, 6, 12 o 24 mesi con uno sconto di 0, 10, 20, 30 e 40 per cento, nulla si rinnova da solo e non esiste un piano gratuito.