Escolha pelo escopo e pelo orçamento

O TVmaze cobre só TV. É uma API pública de uso gratuito com limites por endereço IP, e seus dados vêm sob uma licença de atribuição, então consulte a documentação deles para os detalhes. O amodb é pago e cobre TV, filmes e pessoas. Se o seu app é um rastreador de séries e uma fonte gratuita atende, o TVmaze é um começo sensato. Se você também mostra filmes, páginas de elenco ou pôsteres em vários idiomas, uma chave do amodb substitui várias fontes.

O que cada escopo significa para o seu app

O seu app mostraTVmazeamodb
Página de uma série de TVSimGET /3/tv/{series_id}
Lista de episódiosSimGET /3/tv/{series_id}/season/{season_number}
Página de um filmeSem filmesGET /3/movie/{movie_id}
Página de um atorConsulte a documentação delesGET /3/person/{person_id} e créditos combinados
Séries no ar hojeConsulte a documentação delesGET /3/tv/airing_today
Uma sinopse traduzidaConsulte a documentação delesParâmetro language, 14 idiomas
Notas de vários sitesConsulte a documentação delesExtensão /ratings

A linha dos filmes decide a maioria dos casos. Se você não tem páginas de filmes, o escopo extra não tem valor para você.

Lacunas a verificar antes de migrar

Os endpoints de temporada e episódio seguem o formato do TMDB, e algumas partes deles voltam vazias. Teste as telas que os usam.

  • Elenco do episódio. Em um episódio, cast é um array vazio. guest_stars e crew vêm preenchidos, e a chamada /credits da série traz o elenco principal.
  • Extras da temporada. images, videos e translations da temporada vêm vazios, então o pôster de uma temporada vem do registro da temporada e não de uma lista de imagens.
  • IDs externos. Os external_ids de temporada e episódio são todos null. Relacione episódios com os seus próprios registros por season_number e episode_number.
  • Criadores. created_by de uma série vem vazio na maioria das séries.
  • Sem feed de alterações. O amodb não tem um endpoint que liste as séries alteradas desde uma data.

Comparação de recursos

RecursoTVmazeamodb
Modelo de preçoAPI pública de uso gratuitoPré-pago, de 1 a 24 meses por compra
Plano gratuitoSim, toda a API públicaNenhum, e sem período de teste
AutenticaçãoConsulte a documentação delesapi_key ou cabeçalho Bearer
Formato da respostaJSON, consulte a documentação delesJSON no formato TMDB v3
IdiomasConsulte a documentação deles14 idiomas de interface
FilmesNãoSim
TVSim, o único focoSim
PessoasConsulte a documentação delesSim
ImagensConsulte a documentação delesimg.amodb.dev, dez tokens de tamanho
AvaliaçõesConsulte a documentação delesCinco fontes, quando conhecidas
Limite de requisiçõesPor endereço IP, consulte a documentação deles para ver os números20, 40 ou 120 por minuto por chave
Uso comercialDados sob licença de atribuição, consulte a documentação delesPlanos pagos, veja preços
CompatibilidadeAPI própriaLeituras do TMDB v3 e OMDb

Onde o amodb se diferencia

  • O limite acompanha a chave. Todos os seus servidores compartilham um contador em uma janela deslizante de 60 segundos, e as respostas trazem X-RateLimit-Remaining. Nada depende do endereço de onde a requisição sai.
  • Filmes, TV e pessoas num só lugar. Um cliente, um formato de erro e um conjunto de cabeçalhos cobrem o app inteiro.
  • Idiomas. Títulos e sinopses voltam em qualquer um dos 14 idiomas, e original_name mantém o título nativo.
  • Protocolo consolidado. Bibliotecas escritas para as leituras do TMDB v3 funcionam com uma nova URL base. Veja a página da API de séries de TV para os endpoints de séries.

Onde o TVmaze é mais indicado

  • Sem orçamento. É de uso gratuito, então um projeto de estudante ou um rastreador de fim de semana não exige pagamento. O amodb não tem plano gratuito nem período de teste.
  • Só TV, sem complicação. Se o seu modelo de dados tem séries e episódios e mais nada, uma API focada em TV combina com ele.
  • As próprias convenções. Apps já construídos em torno do modelo do TVmaze economizam trabalho ao ficar.

Se você ficar, siga a licença de atribuição dele. Consulte a documentação deles para ver o texto.

Migrar para o amodb

Comece com um job de mapeamento. Leia os IDs externos que os seus registros guardados do TVmaze listam (consulte a documentação deles para os nomes dos campos) e resolva-os por /3/find. O programa abaixo mapeia um ID do IMDb para uma série e imprime a data do próximo episódio.

Go
package main

import (
	"encoding/json"
	"fmt"
	"net/http"
	"os"
	"time"
)

type findResult struct {
	TVResults []struct {
		ID   int    `json:"id"`
		Name string `json:"name"`
	} `json:"tv_results"`
}

type episode struct {
	AirDate       string `json:"air_date"`
	SeasonNumber  int    `json:"season_number"`
	EpisodeNumber int    `json:"episode_number"`
}

type series struct {
	Name        string   `json:"name"`
	Status      string   `json:"status"`
	NextEpisode *episode `json:"next_episode_to_air"`
}

var client = &http.Client{Timeout: 10 * time.Second}

func get(path string, out any) error {
	req, err := http.NewRequest(http.MethodGet, "https://api.amodb.dev/3"+path, nil)
	if err != nil {
		return err
	}
	req.Header.Set("Authorization", "Bearer "+os.Getenv("AMODB_KEY"))
	res, err := client.Do(req)
	if err != nil {
		return err
	}
	defer res.Body.Close()
	if res.StatusCode != http.StatusOK {
		return fmt.Errorf("amodb returned %s", res.Status)
	}
	return json.NewDecoder(res.Body).Decode(out)
}

func main() {
	var found findResult
	if err := get("/find/tt0903747?external_source=imdb_id", &found); err != nil {
		fmt.Println(err)
		return
	}
	if len(found.TVResults) == 0 {
		fmt.Println("no match")
		return
	}
	var s series
	if err := get(fmt.Sprintf("/tv/%d", found.TVResults[0].ID), &s); err != nil {
		fmt.Println(err)
		return
	}
	fmt.Println(s.Name, s.Status)
	if s.NextEpisode != nil {
		fmt.Println("next episode:", s.NextEpisode.AirDate)
	}
}

O tipo ponteiro para NextEpisode lida com o null que séries encerradas retornam. Rode o mapeamento uma vez, salve o ID do amodb em cada um dos seus registros e chame /3/tv/{id} daí em diante. Um 429 é respondido com Retry-After, e a página busca por ID externo lista as outras fontes de ID.

Dimensionar uma sincronização noturna

Suponha que você atualize 300 séries por noite. São 300 requisições, já que uma chamada de série retorna uma série. A 20 requisições por minuto o job leva 15 minutos, a 40 leva 7.5 minutos e a 120 leva 2.5 minutos. Acrescente append_to_response=credits,ratings a cada chamada para que elenco e notas cheguem na mesma requisição, em vez de custar mais duas por série. Leia X-RateLimit-Remaining e pause quando chegar a zero, depois continue após os segundos de X-RateLimit-Reset.

Preços

O amodb é pré-pago e nunca renova sozinho. Escolha 1, 3, 6, 12 ou 24 meses e um plano de 20, 40 ou 120 requisições por minuto. Períodos mais longos saem 10, 20, 30 ou 40 por cento mais baratos, e cada plano inclui todos os dados. Os valores estão em preços.