Pôsteres de filmes de um host de imagens que dispensa chave

Uma URL de pôster é https://img.amodb.dev/t/p/{size}/{file}. A parte do arquivo é a string poster_path de qualquer resposta de filme, busca ou lista, e ela começa com uma barra. A parte do tamanho é um nome como w342. As imagens não precisam de chave, então navegadores e apps podem carregá-las direto. O JSON que informa o nome do arquivo ainda precisa da sua chave, e o amodb é uma API independente que fala o protocolo TMDB v3, então o código de imagens que você já tem continua funcionando depois da troca de host.

O que você recebe:

  • Pôsteres, imagens de fundo (backdrop), logos, fotos de perfil e imagens de episódios (stills) em um só host.
  • Dez nomes de tamanho, de w92 a original.
  • Listas de pôsteres por título, com idioma, largura e altura em cada item.
  • Cache de borda de 30 dias para as imagens.

Quais dados você recebe

ImagemDe onde vem o nome do arquivoTamanhos comuns
Pôster de filmeposter_path em /3/movie/{movie_id} e nas listasw92, w154, w185, w342, w500, w780, original
Imagem de fundo (backdrop)backdrop_pathw300, w780, w1280, original
Foto de pessoaprofile_path em /3/person/{person_id}w185, h632, original
Logo de produtora ou emissoralogo_pathw92, w154, w185, w300, w500, original
Imagem de episódiostill_pathw92, w185, w300, original
Todos os pôsteres de um títuloGET /3/movie/{movie_id}/imagesarray posters

Séries, temporadas e coleções também têm poster_path. Leia as listas exatas de tamanhos no bloco images de GET /3/configuration uma vez na inicialização, em vez de deixá-las fixas no código. A referência de imagens está em imagens.

Comece em 3 passos

  1. Escolha um plano em preços. Ele define a taxa das chamadas JSON: 20, 40 ou 120 requisições por minuto.
  2. Crie uma chave no painel da sua conta.
  3. Leia poster_path de uma chamada de detalhes ou de lista e depois coloque-o atrás do host de imagens e de um nome de tamanho.

Exemplo de requisição

O programa em Go lista os pôsteres de The Matrix (id de filme 603) em inglês e sem texto, escolhe o mais largo, imprime um srcset pronto e salva o arquivo w342. A chave vai só na chamada 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)
}

Uma resposta de imagens reduzida para include_image_language=en,null: 3 dos 145 pôsteres, um em inglês, o mais largo em inglês e um sem texto. A resposta também contém backdrops e logos, omitidos aqui.

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

Escolha um tamanho

O número em um tamanho w é a largura da imagem em pixels, e h632 é uma altura. Nomes pequenos economizam banda, nomes grandes mantêm o detalhe em telas densas.

TamanhoUso típico
w92Sugestões de busca e linhas de lista bem pequenas
w154, w185Listas densas e cartões
w342Blocos de grade em celulares
w500Página de detalhes
w780Telas grandes e telas 2x
originalArquivamento ou impressão, o arquivo sem redimensionar

Dê ao navegador várias larguras e deixe que ele escolha. O programa em Go acima imprime um srcset com candidatos 185w, 342w, 500w e 780w. Combine-o com um atributo sizes que corresponda ao seu layout, por exemplo sizes="(max-width: 600px) 45vw, 185px" no elemento img.

Idiomas dos pôsteres

Cada item em posters tem um valor iso_639_1, que é um código de idioma ou null para arte sem texto. O parâmetro include_image_language aceita uma lista de códigos separados por vírgula.

ValorRetorna
enPôsteres marcados como inglês
en,nullPôsteres em inglês e pôsteres sem texto
nullSó pôsteres sem texto

Uma boa ordem de fallback é o pôster no idioma do seu usuário, depois um sem texto e por fim o inglês. Dentro de cada grupo, ordene por width e mantenha o primeiro em caso de empate. vote_average e vote_count valem 0 nas imagens de filmes e séries, então não servem para classificar nada. Os idiomas dos pôsteres descrevem o texto impresso na arte, portanto não seguem os 14 idiomas da interface. Confira iso_639_1 no que voltar, porque o conjunto depende do título.

Armazenar e fazer cache de pôsteres

  • Guarde poster_path, não a URL completa. Qualquer tamanho pode ser montado a partir dele depois.
  • A borda guarda as imagens em cache por 30 dias. Os detalhes ficam em cache por 6 horas, então leia poster_path de novo depois disso para ver se mudou.
  • Mantenha a chave no seu servidor. Envie ao navegador só as URLs das imagens.
  • Quando poster_path for null, exiba um placeholder em vez de uma imagem quebrada.

Como se compara

RecursoFazer scraping de páginas para imagensHospedar suas próprias cópiasHost de imagens do amodb
Chave necessáriaNenhuma, valem os termos de cada siteNenhumaSem chave para imagens
Variantes de tamanhoO tamanho que a página servirVocê gera e guarda cada umaNomes de tamanho fixos na URL, de w92 até original
Achar o arquivoInterpretar o HTMLSeu próprio banco de dadosposter_path em toda resposta
Idiomas da artePágina por páginaO que você coletouinclude_image_language nos endpoints de imagens
Armazenamento e bandaSeus, mais os da fonteSeusO navegador carrega de img.amodb.dev
CacheSeuSeu30 dias na borda

Preços

Os downloads de imagens não levam chave. Seu plano limita só as chamadas JSON que informam os nomes de arquivo, e as respostas de lista já incluem poster_path para cada item, então uma chamada de lista alimenta uma grade inteira. Escolha 20, 40 ou 120 requisições por minuto em preços. O acesso é pré-pago por 1, 3, 6, 12 ou 24 meses com 0, 10, 20, 30 e 40 por cento de desconto, nada renova sozinho e não há plano gratuito.