API videoclipuri și trailere

Endpoint-urile de videoclipuri listează trailerele, teaserele, clipurile și featurette-urile atașate unui film sau serial. Fiecare intrare dă numele gazdei, o cheie de videoclip, un tip, un indicator oficial, o dimensiune și o dată de publicare. Căile de sezon și de episod există, dar nu întorc videoclipuri. Filtrează după limbă și tip în propriul cod.

Actualizat Vezi ca Markdown

Obține videoclipurile unui film

GET /3/movie/{movie_id}/videos întoarce înregistrările video atașate unui film. O înregistrare este doar metadate: un nume, gazda care servește videoclipul, cheia videoclipului pe acea gazdă, un tip și câteva indicatoare. amodb nu întoarce fișiere video.

Exemplul afișează primul trailer oficial în engleză, revenind la orice trailer în engleză.

bashjspyphpgo
curl -s "https://api.amodb.dev/3/movie/550/videos" \
  -H "Authorization: Bearer $AMODB_KEY"
const url = 'https://api.amodb.dev/3/movie/550/videos';
const res = await fetch(url, { headers: { Authorization: `Bearer ${process.env.AMODB_KEY}` } });
if (!res.ok) throw new Error(`amodb returned ${res.status}`);
const { results } = await res.json();
const trailers = results.filter((v) => v.type === 'Trailer' && v.iso_639_1 === 'en');
const pick = trailers.find((v) => v.official) ?? trailers[0];
console.log(pick ? `${pick.name} (${pick.site}, key ${pick.key})` : 'no trailer');
import os
import requests

r = requests.get(
    "https://api.amodb.dev/3/movie/550/videos",
    headers={"Authorization": f"Bearer {os.environ['AMODB_KEY']}"},
    timeout=10,
)
r.raise_for_status()
trailers = [v for v in r.json()["results"] if v["type"] == "Trailer" and v["iso_639_1"] == "en"]
official = [v for v in trailers if v["official"]]
pick = (official or trailers or [None])[0]
print(f"{pick['name']} ({pick['site']}, key {pick['key']})" if pick else "no trailer")
<?php
$url = 'https://api.amodb.dev/3/movie/550/videos';
$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");
}
$trailers = array_values(array_filter(
    json_decode($body, true)['results'],
    fn($v) => $v['type'] === 'Trailer' && $v['iso_639_1'] === 'en'
));
$official = array_values(array_filter($trailers, fn($v) => $v['official']));
$pick = $official[0] ?? $trailers[0] ?? null;
echo $pick ? "{$pick['name']} ({$pick['site']}, key {$pick['key']})" : 'no trailer', PHP_EOL;
package main

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

type Videos struct {
	Results []struct {
		Name     string `json:"name"`
		Key      string `json:"key"`
		Site     string `json:"site"`
		Type     string `json:"type"`
		Language string `json:"iso_639_1"`
		Official bool   `json:"official"`
	} `json:"results"`
}

func main() {
	url := "https://api.amodb.dev/3/movie/550/videos"
	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 v Videos
	if err := json.NewDecoder(res.Body).Decode(&v); err != nil {
		panic(err)
	}
	for _, r := range v.Results {
		if r.Type == "Trailer" && r.Language == "en" && r.Official {
			fmt.Printf("%s (%s, key %s)\n", r.Name, r.Site, r.Key)
			return
		}
	}
	fmt.Println("no official trailer")
}

Parametri

  • movie_idcaleobligatoriu
    ID numeric de film, de exemplu 550.
  • api_keyinterogareuna dintre cele două
    Cheia ta. Folosește-o pe aceasta sau antetul Authorization: Bearer.
  • language, include_video_languageinterogare
    Acceptați, dar ignorați. Răspunsul conține mereu fiecare videoclip al titlului. Filtrează după iso_639_1 în codul tău.

Câmpurile răspunsului

CâmpTipObservații
idnumăr întregID-ul filmului.
resultsarrayÎnregistrări video, nesortate după tip sau dată. Gol când nu se cunoaște niciuna.
results[].iso_639_1, results[].iso_3166_1șirLimba și țara videoclipului, de exemplu en și US.
results[].nameșirTitlul videoclipului, de exemplu #TBT Trailer.
results[].keyșirID-ul videoclipului pe acea gazdă.
results[].siteșirNumele gazdei video. Azi este mereu YouTube.
results[].sizenumăr întregRezoluția verticală. Azi este mereu 1080.
results[].typeșirTrailer, Teaser, Clip, Featurette, Behind the Scenes, Bloopers, Opening Credits sau Recap.
results[].officialbooleanTrue când studioul sau deținătorul drepturilor l-a publicat.
results[].published_atșirMarcaj de timp ISO 8601, cu sau fără milisecunde.
results[].idșirID-ul înregistrării video. Egal cu key.

Exemplu de răspuns

Sunt arătate trei din cele 19 înregistrări ale filmului 550.

JSON
{
  "id": 550,
  "results": [
    {
      "iso_639_1": "en",
      "iso_3166_1": "US",
      "name": "Theatrical Trailer (HD Fan Remaster)",
      "key": "6JnN1DmbqoU",
      "site": "YouTube",
      "size": 1080,
      "type": "Trailer",
      "official": false,
      "published_at": "2015-02-26T03:19:25Z",
      "id": "6JnN1DmbqoU"
    },
    {
      "iso_639_1": "en",
      "iso_3166_1": "US",
      "name": "#TBT Trailer",
      "key": "BdJKm16Co6M",
      "site": "YouTube",
      "size": 1080,
      "type": "Trailer",
      "official": true,
      "published_at": "2014-10-02T19:20:22Z",
      "id": "BdJKm16Co6M"
    },
    {
      "iso_639_1": "en",
      "iso_3166_1": "US",
      "name": "Mark Kermode introduces Fight Club | Film4 Interview",
      "key": "tiWCNtGDGEY",
      "site": "YouTube",
      "size": 1080,
      "type": "Featurette",
      "official": true,
      "published_at": "2015-05-08T15:59:05Z",
      "id": "tiWCNtGDGEY"
    }
  ]
}

Tipuri de videoclipuri

Câmpul type îți spune ce este un videoclip. Potrivește-l exact, cu literele mari arătate.

TipFolosește-l pentru
TrailerPromo-ul principal. Arată-l pe o pagină de detalii.
TeaserUn anunț scurt care vine înainte de trailer.
ClipO scenă luată din filmul sau episodul finalizat.
FeaturetteO piesă scurtă despre cum a fost făcut titlul.
Behind the ScenesImagini de pe platou și interviuri.
BloopersScene tăiate și montaje cu gafe.
Opening CreditsSecvența de titlu a unui serial.
RecapUn rezumat al episoadelor anterioare.

Pot apărea și alte valori în timp, deci tratează un type necunoscut ca un extra generic și nu eșua pe el.

Alege videoclipul potrivit

Folosește aceeași ordine pentru fiecare titlu. Încearcă limbile tale în ordine. În interiorul unei limbi, trailerele oficiale vin primele, apoi orice trailer, apoi teaserele, apoi clipurile. În interiorul unui grup sortează după published_at: crescător dă primul trailer, descrescător dă ultimul.

JavaScript
function pickVideo(results, langs = ['en']) {
  const order = ['Trailer', 'Teaser', 'Clip'];
  for (const lang of langs) {
    for (const type of order) {
      const group = results
        .filter((v) => v.iso_639_1 === lang && v.type === type)
        .sort((a, b) => Number(b.official) - Number(a.official) || Date.parse(a.published_at) - Date.parse(b.published_at));
      if (group.length > 0) return group[0];
    }
  }
  return null;
}

// Russian first, English as the fallback.
// const video = pickVideo(results, ['ru', 'en']);

Limbi

language și include_video_language nu schimbă răspunsul, deci un singur apel îți dă fiecare videoclip al titlului. Fiecare înregistrare poartă iso_639_1 și iso_3166_1. Filmul 550 are videoclipuri etichetate fr, en, es, pt, it, cs, pl și ru. Filtrează după iso_639_1 în codul tău, ca mai sus, apoi arată-i utilizatorului în ce limbă urmează să audă. Un titlu poate să nu aibă niciun videoclip în limba dorită, deci păstrează o variantă de rezervă în engleză sau în orice limbă. Cele 14 limbi servite sunt listate la limbi.

Alte endpoint-uri de videoclipuri

Căile de mai jos întorc aceeași structură id și results.

Metodă și caleÎntoarce
GET /tv/{series_id}/videosVideoclipurile unui serial.
GET /tv/{series_id}/season/{season_number}/videosMereu un array results gol.
GET /tv/{series_id}/season/{season_number}/episode/{episode_number}/videosMereu un array results gol.

Poți adăuga și append_to_response=videos la un apel de detalii pentru film sau serial. Blocul atașat conține results și nu are id. Paginile de serial și de sezon sunt descrise la seriale TV și sezoane și episoade.

Erori

HTTPstatus_codeCând
4017Cheia lipsește sau este greșită.
40236Perioada planului s-a încheiat.
40434Niciun sezon sau episod cu acel ID sau un ID care nu este număr.
40537Ai folosit o metodă de scriere pe o cale de videoclipuri.
42925Ai 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 videoclipuri răspunde 200 cu "results": [], la fel ca pentru un titlu cunoscut fără videoclipuri. Calea de detalii răspunde 404 pentru un ID necunoscut. Mai multe la erori și limite de cereri.

Note practice

  • Stochează site și key alese împreună cu titlul, nu o adresă completă, ca să poți schimba playerul mai târziu.
  • Listele de videoclipuri urmează cache-ul de detalii de 6 ore la margine. Un cache de client de câteva ore se potrivește.
  • size este 1080 la fiecare înregistrare azi, deci nu îți spune care clip este ușor. Lasă playerul să aleagă calitatea.
  • Nu te baza pe existența unui singur trailer. Ascunde butonul de redare când funcția ta de alegere întoarce null.
  • Ordinea din results nu are niciun sens. Sortează în codul tău.
  • Pentru fișierele de poster și imagine de fundal vezi imagini. Pentru perspectiva cazului de utilizare, vezi API trailere filme.