API videí a trailerů
Endpointy videí vypisují trailery, teasery, klipy a featurety připojené k filmu nebo seriálu. Každá položka udává název hostitele, klíč videa, typ, příznak official, velikost a datum zveřejnění. Cesty sezón a epizod existují, ale žádná videa nevracejí. Podle jazyka a typu filtrujte ve vlastním kódu.
Získání videí filmu
GET / vrací záznamy videí připojené k jednomu filmu. Záznam jsou jen metadata: název, hostitel, který video poskytuje, klíč videa u tohoto hostitele, typ a několik příznaků. amodb videosoubory nevrací.
Příklad vypíše první oficiální anglický trailer a jako zálohu vezme libovolný anglický trailer.
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")
}Parametry
movie_idpathpovinnýČíselné ID filmu, například550.api_keyqueryjeden ze dvouVáš klíč. Použijte jej, nebo hlavičkuAuthorization: Bearer.language,include_video_languagequeryPřijímají se, ale ignorují. Odpověď vždy obsahuje všechna videa titulu. Filtrujte podleiso_639_1ve svém kódu.
Pole odpovědi
| Pole | Typ | Poznámky |
|---|---|---|
id | integer | ID filmu. |
results | array | Záznamy videí, neřazené podle typu ani data. Prázdné, když žádné nejsou známé. |
results[].iso_639_1, results[].iso_3166_1 | string | Jazyk a země videa, například en a US. |
results[].name | string | Název videa, například #TBT Trailer. |
results[].key | string | ID videa u daného hostitele. |
results[].site | string | Název hostitele videa. Dnes vždy YouTube. |
results[].size | integer | Svislé rozlišení. Dnes vždy 1080. |
results[].type | string | Trailer, Teaser, Clip, Featurette, Behind the Scenes, Bloopers, Opening Credits nebo Recap. |
results[].official | boolean | True, když video zveřejnilo studio nebo držitel práv. |
results[].published_at | string | Časové razítko ISO 8601, s milisekundami nebo bez nich. |
results[].id | string | ID záznamu videa. Rovná se key. |
Příklad odpovědi
Zobrazeny jsou tři z 19 záznamů filmu 550.
{
"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"
}
]
}Typy videí
Pole type říká, co video je. Porovnávejte přesně, s uvedenými velkými písmeny.
| Typ | K čemu ho použít |
|---|---|
Trailer | Hlavní upoutávka. Zobrazte ji na stránce detailu. |
Teaser | Krátké oznámení před trailerem. |
Clip | Scéna z hotového filmu nebo epizody. |
Featurette | Krátký příspěvek o tom, jak titul vznikal. |
Behind the Scenes | Záběry z natáčení a rozhovory. |
Bloopers | Zkažené záběry a sestřihy gagů. |
Opening Credits | Úvodní znělka seriálu. |
Recap | Shrnutí předchozích epizod. |
Časem se mohou objevit další hodnoty, neznámý type proto berte jako obecný bonus a nenechte na něm kód selhat.
Výběr správného videa
Pro každý titul používejte stejné pořadí. Zkoušejte své jazyky podle pořadí. Uvnitř jednoho jazyka jdou první oficiální trailery, pak libovolný trailer, pak teasery a pak klipy. V rámci skupiny řaďte podle published_at: vzestupně dá první trailer, sestupně nejnovější.
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']);Jazyky
language a include_video_language odpověď nemění, takže jedno volání dá každé video titulu. Každý záznam nese iso_639_1 a iso_3166_1. Film 550 má videa označená fr, en, es, pt, it, cs, pl a ru. Filtrujte podle iso_639_1 ve svém kódu, jak je ukázáno výše, a pak uživateli ukažte, v jakém jazyce video uslyší. Titul nemusí mít video v jazyce, který chcete, mějte proto zálohu v angličtině nebo v libovolném jazyce. Všech 14 podporovaných jazyků je uvedeno na stránce jazyky.
Další endpointy videí
Cesty níže vracejí stejný tvar id a results.
| Metoda a cesta | Vrací |
|---|---|
GET / | Videa seriálu. |
GET / | Vždy prázdné pole results. |
GET / | Vždy prázdné pole results. |
K volání detailů filmu nebo seriálu můžete také přidat append_. Přidaný blok obsahuje results a žádné id. Stránky seriálů a sezón popisují seriály a sezóny a epizody.
Chyby
| HTTP | status_code | Kdy |
|---|---|---|
| 401 | 7 | Klíč chybí nebo je nesprávný. |
| 402 | 36 | Platnost tarifu skončila. |
| 404 | 34 | Sezóna ani epizoda s tímto ID neexistuje, nebo ID není číslo. |
| 405 | 37 | Použili jste metodu pro zápis na cestě videí. |
| 429 | 25 | Překročili jste počet požadavků za minutu. Počkejte tolik sekund, kolik říká Retry-After. |
ID filmu nebo seriálu, které neexistuje, zde není chyba: cesta videí odpoví 200 s "results": [], stejně jako u známého titulu bez videí. Cesta detailů odpoví u neznámého ID 404. Více viz chyby a limity požadavků.
Praktické poznámky
- Ukládejte u titulu vybraný
siteakey, ne celou adresu, abyste mohli později změnit přehrávač. - Seznamy videí sledují cache detailů, 6 hodin na edge. Cache u klienta na několik hodin tomu odpovídá.
sizeje dnes u každého záznamu 1080, takže nepoví, které video je lehké. Kvalitu nechte vybrat přehrávač.- Nespoléhejte na to, že trailer existuje. Tlačítko přehrání skryjte, když vaše funkce výběru vrátí null.
- Pořadí
resultsnic neznamená. Řaďte ve svém kódu. - Soubory plakátů a pozadí viz obrázky. Pohled na případ užití viz API trailerů filmů.