API за видеа и трейлъри
Ендпойнтите за видеа изброяват трейлърите, тийзърите, клиповете и featurette, прикачени към филм или сериал. Всеки запис дава име на хост, ключ на видеото, тип, флаг за официалност, размер и дата на публикуване. Пътищата за сезон и епизод съществуват, но не връщат видеа. Филтрирайте по език и тип във вашия код.
Вземане на видеа за филм
GET / връща записите за видеа, прикачени към един филм. Записът са само метаданни: име, хостът, който обслужва видеото, ключът на видеото на този хост, тип и няколко флага. amodb не връща видеофайлове.
Примерът отпечатва първия официален английски трейлър, а при липса му всеки английски трейлър.
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")
}Параметри
movie_idпътзадължителенЧислов id на филма, например550.api_keyзаявкаедин от дватаВашият ключ. Ползвайте него или заглавкатаAuthorization: Bearer.language,include_video_languageзаявкаПриемат се, но се игнорират. Отговорът винаги съдържа всяко видео на заглавието. Филтрирайте поiso_639_1във вашия код.
Полета на отговора
| Поле | Тип | Бележки |
|---|---|---|
id | цяло число | Id на филма. |
results | масив | Записи за видеа, неподредени по тип или дата. Празен, когато нищо не е известно. |
results[].iso_639_1, results[].iso_3166_1 | низ | Език и държава на видеото, например en и US. |
results[].name | низ | Заглавие на видеото, например #TBT Trailer. |
results[].key | низ | Id на видеото на този хост. |
results[].site | низ | Име на хоста на видеото. Днес винаги YouTube. |
results[].size | цяло число | Вертикална резолюция. Днес винаги 1080. |
results[].type | низ | Trailer, Teaser, Clip, Featurette, Behind the Scenes, Bloopers, Opening Credits или Recap. |
results[].official | булева стойност | True, когато студиото или носителят на правата го е публикувал. |
results[].published_at | низ | Времеви печат по ISO 8601, с или без милисекунди. |
results[].id | низ | Id на записа за видео. Равно на key. |
Примерен отговор
Показани са три от 19-те записа на филм 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"
}
]
}Видове видеа
Полето type ви казва какво е видеото. Сравнявайте го точно, с главните букви, както са показани.
| Тип | За какво да го ползвате |
|---|---|
Trailer | Основният рекламен клип. Показвайте го на страницата с детайли. |
Teaser | Кратко обявяване, което излиза преди трейлъра. |
Clip | Сцена от готовия филм или епизод. |
Featurette | Кратък материал за това как е направено заглавието. |
Behind the Scenes | Кадри от снимачната площадка и интервюта. |
Bloopers | Изрязани дубли и сбирки с гафове. |
Opening Credits | Заглавната секвенция на сериал. |
Recap | Резюме на предишни епизоди. |
С времето могат да се появят други стойности, затова третирайте непознат type като общо допълнение и не връщайте грешка.
Изберете правилното видео
Ползвайте един и същи ред за всяко заглавие. Опитайте езиците си по ред. В рамките на един език първи са официалните трейлъри, после всеки трейлър, после тийзърите, после клиповете. В рамките на група сортирайте по published_at: възходящо дава първия трейлър, низходящо дава последния.
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']);Езици
language и include_video_language не променят отговора, така че едно извикване дава всяко видео на заглавието. Всеки запис носи iso_639_1 и iso_3166_1. Филм 550 има видеа с етикети fr, en, es, pt, it, cs, pl и ru. Филтрирайте по iso_639_1 във вашия код, както е показано по-горе, и после кажете на потребителя на какъв език ще чуе видеото. Заглавие може да няма видео на езика, който искате, затова дръжте резерва на английски или на който и да е език. 14-те обслужвани езика са изброени на страницата езици.
Други ендпойнти за видеа
Пътищата по-долу връщат същата форма с id и results.
| Метод и път | Какво връща |
|---|---|
GET / | Видеа на сериал. |
GET / | Винаги празен масив results. |
GET / | Винаги празен масив results. |
Можете да добавите и append_ към извикване за детайли на филм или сериал. Добавеният блок съдържа results и няма id. Страниците за сериали и сезони са описани в сериали и сезони и епизоди.
Грешки
| HTTP | status_code | Кога |
|---|---|---|
| 401 | 7 | Ключът липсва или е грешен. |
| 402 | 36 | Периодът на плана е изтекъл. |
| 404 | 34 | Няма сезон или епизод с това id, или id не е число. |
| 405 | 37 | Ползвали сте метод за запис на път за видеа. |
| 429 | 25 | Надхвърлили сте лимита на заявки в минута. Изчакайте Retry-After секунди. |
Id на филм или сериал, което не съществува, тук не е грешка: пътят за видеа отговаря със 200 и "results": [], както за познато заглавие без видеа. Пътят за детайли отговаря с 404 за непознато id. Повече на страниците грешки и лимити на заявките.
Практически бележки
- Пазете избраните
siteиkeyсъс заглавието, а не пълен адрес, за да можете да смените плейъра по-късно. - Списъците с видеа следват кеша на детайлите от 6 часа на edge. Клиентски кеш от няколко часа му съответства.
sizeе 1080 за всеки запис днес, така че не ви казва кой клип е лек. Оставете плейъра да избере качеството.- Не разчитайте, че трейлър съществува. Скрийте бутона за пускане, когато функцията ви за избор върне null.
- Редът на
resultsне носи значение. Сортирайте във вашия код. - За файловете с постери и фонови изображения вижте изображения. За гледната точка на случая на употреба вижте API за трейлъри на филми.