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.
Obține videoclipurile unui film
GET / î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ă.
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_idcaleobligatoriuID numeric de film, de exemplu550.api_keyinterogareuna dintre cele douăCheia ta. Folosește-o pe aceasta sau antetulAuthorization: Bearer.language,include_video_languageinterogareAcceptaț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âmp | Tip | Observații |
|---|---|---|
id | număr întreg | ID-ul filmului. |
results | array | Înregistrări video, nesortate după tip sau dată. Gol când nu se cunoaște niciuna. |
results[].iso_639_1, results[].iso_3166_1 | șir | Limba și țara videoclipului, de exemplu en și US. |
results[].name | șir | Titlul videoclipului, de exemplu #TBT Trailer. |
results[].key | șir | ID-ul videoclipului pe acea gazdă. |
results[].site | șir | Numele gazdei video. Azi este mereu YouTube. |
results[].size | număr întreg | Rezoluția verticală. Azi este mereu 1080. |
results[].type | șir | Trailer, Teaser, Clip, Featurette, Behind the Scenes, Bloopers, Opening Credits sau Recap. |
results[].official | boolean | True când studioul sau deținătorul drepturilor l-a publicat. |
results[].published_at | șir | Marcaj de timp ISO 8601, cu sau fără milisecunde. |
results[].id | șir | ID-ul înregistrării video. Egal cu key. |
Exemplu de răspuns
Sunt arătate trei din cele 19 înregistrări ale filmului 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"
}
]
}Tipuri de videoclipuri
Câmpul type îți spune ce este un videoclip. Potrivește-l exact, cu literele mari arătate.
| Tip | Folosește-l pentru |
|---|---|
Trailer | Promo-ul principal. Arată-l pe o pagină de detalii. |
Teaser | Un anunț scurt care vine înainte de trailer. |
Clip | O scenă luată din filmul sau episodul finalizat. |
Featurette | O piesă scurtă despre cum a fost făcut titlul. |
Behind the Scenes | Imagini de pe platou și interviuri. |
Bloopers | Scene tăiate și montaje cu gafe. |
Opening Credits | Secvența de titlu a unui serial. |
Recap | Un 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.
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 / | Videoclipurile unui serial. |
GET / | Mereu un array results gol. |
GET / | Mereu un array results gol. |
Poți adăuga și append_ 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
| HTTP | status_code | Când |
|---|---|---|
| 401 | 7 | Cheia lipsește sau este greșită. |
| 402 | 36 | Perioada planului s-a încheiat. |
| 404 | 34 | Niciun sezon sau episod cu acel ID sau un ID care nu este număr. |
| 405 | 37 | Ai folosit o metodă de scriere pe o cale de videoclipuri. |
| 429 | 25 | Ai 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șikeyalese î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.
sizeeste 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
resultsnu 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.