# API за видеа и трейлъри

> Ендпойнтите за видеа изброяват трейлърите, тийзърите, клиповете и featurette, прикачени към филм или сериал. Всеки запис дава име на хост, ключ на видеото, тип, флаг за официалност, размер и дата на публикуване. Пътищата за сезон и епизод съществуват, но не връщат видеа. Филтрирайте по език и тип във вашия код.

## Ендпойнт

`GET /3/movie/{movie_id}/videos`

```bash
curl "https://api.amodb.dev/3/movie/550/videos" \
  -H "Authorization: Bearer $AMODB_KEY"
```

Отговор:

```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": "20th Anniversary Trailer",
      "key": "dfeUzm6KF4g",
      "site": "YouTube",
      "size": 1080,
      "type": "Trailer",
      "official": true,
      "published_at": "2019-10-15T18:59:47Z",
      "id": "dfeUzm6KF4g"
    }
  ]
}
```

## Вземане на видеа за филм

`GET /3/movie/{movie_id}/videos` връща записите за видеа, прикачени към един филм. Записът са само метаданни: име, хостът, който обслужва видеото, ключът на видеото на този хост, тип и няколко флага. amodb не връща видеофайлове.

Примерът отпечатва първия официален английски трейлър, а при липса му всеки английски трейлър.

```bash
curl -s "https://api.amodb.dev/3/movie/550/videos" \
  -H "Authorization: Bearer $AMODB_KEY"
```

```js
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');
```

```python
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
<?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;
```

```go
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.

```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"
    }
  ]
}
```

## Видове видеа

Полето `type` ви казва какво е видеото. Сравнявайте го точно, с главните букви, както са показани.

| Тип                 | За какво да го ползвате                                         |
| ------------------- | --------------------------------------------------------------- |
| `Trailer`           | Основният рекламен клип. Показвайте го на страницата с детайли. |
| `Teaser`            | Кратко обявяване, което излиза преди трейлъра.                  |
| `Clip`              | Сцена от готовия филм или епизод.                               |
| `Featurette`        | Кратък материал за това как е направено заглавието.             |
| `Behind the Scenes` | Кадри от снимачната площадка и интервюта.                       |
| `Bloopers`          | Изрязани дубли и сбирки с гафове.                               |
| `Opening Credits`   | Заглавната секвенция на сериал.                                 |
| `Recap`             | Резюме на предишни епизоди.                                     |

С времето могат да се появят други стойности, затова третирайте непознат `type` като общо допълнение и не връщайте грешка.

## Изберете правилното видео

Ползвайте един и същи ред за всяко заглавие. Опитайте езиците си по ред. В рамките на един език първи са официалните трейлъри, после всеки трейлър, после тийзърите, после клиповете. В рамките на група сортирайте по `published_at`: възходящо дава първия трейлър, низходящо дава последния.

```js
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-те обслужвани езика са изброени на страницата [езици](https://amodb.dev/bg/languages/).

## Други ендпойнти за видеа

Пътищата по-долу връщат същата форма с `id` и `results`.

| Метод и път                                                                  | Какво връща                    |
| ---------------------------------------------------------------------------- | ------------------------------ |
| `GET /tv/{series_id}/videos`                                                 | Видеа на сериал.               |
| `GET /tv/{series_id}/season/{season_number}/videos`                          | Винаги празен масив `results`. |
| `GET /tv/{series_id}/season/{season_number}/episode/{episode_number}/videos` | Винаги празен масив `results`. |

Можете да добавите и `append_to_response=videos` към извикване за детайли на филм или сериал. Добавеният блок съдържа `results` и няма `id`. Страниците за сериали и сезони са описани в [сериали](https://amodb.dev/bg/tv-series/) и [сезони и епизоди](https://amodb.dev/bg/tv-seasons-episodes/).

## Грешки

| HTTP | status_code | Кога                                                                        |
| ---- | ----------- | --------------------------------------------------------------------------- |
| 401  | 7           | Ключът липсва или е грешен.                                                 |
| 402  | 36          | Периодът на плана е изтекъл.                                                |
| 404  | 34          | Няма сезон или епизод с това id, или id не е число.                         |
| 405  | 37          | Ползвали сте метод за запис на път за видеа.                                |
| 429  | 25          | Надхвърлили сте лимита на заявки в минута. Изчакайте `Retry-After` секунди. |

Id на филм или сериал, което не съществува, тук не е грешка: пътят за видеа отговаря със 200 и `"results": []`, както за познато заглавие без видеа. Пътят за детайли отговаря с 404 за непознато id. Повече на страниците [грешки](https://amodb.dev/bg/errors/) и [лимити на заявките](https://amodb.dev/bg/rate-limits/).

## Практически бележки

- Пазете избраните `site` и `key` със заглавието, а не пълен адрес, за да можете да смените плейъра по-късно.
- Списъците с видеа следват кеша на детайлите от 6 часа на edge. Клиентски кеш от няколко часа му съответства.
- `size` е 1080 за всеки запис днес, така че не ви казва кой клип е лек. Оставете плейъра да избере качеството.
- Не разчитайте, че трейлър съществува. Скрийте бутона за пускане, когато функцията ви за избор върне null.
- Редът на `results` не носи значение. Сортирайте във вашия код.
- За файловете с постери и фонови изображения вижте [изображения](https://amodb.dev/bg/images-api/). За гледната точка на случая на употреба вижте [API за трейлъри на филми](https://amodb.dev/bg/movie-trailer-api/).

## Въпроси и отговори

### Как да взема само официалния трейлър?

Филтрирайте масива results за type равно на Trailer и official равно на true. Ако останат няколко, сортирайте по published_at, за да вземете най-ранния или най-новия.

### Как да взема видеа на моя език?

Ендпойнтът връща всяко видео на заглавието и игнорира language и include_video_language. Филтрирайте results по iso_639_1 във вашия код, например първо ru и en като резерва. Много заглавия нямат видео на даден език.

### Как да пусна видео от отговора?

Ползвайте полето site, за да изберете плейъра, и полето key като id на видеото на този хост. В данните, които се обслужват днес, site е винаги YouTube. Построете адреса за вграждане или гледане по шаблона на самия хост. amodb връща метаданни, а не видеофайлове.

### Имат ли епизодите и сезоните собствени видеа?

Не. Пътищата за видеа на сезон и епизод отговарят със 200 и празен масив results. Записи за видеа носят само филмите и сериалите.

## Свързани страници

- [API за детайли на филм](https://amodb.dev/bg/movies/): API за детайли на филм със същите пътища и JSON като TMDB v3. Един филм по id, а актьори, рейтинги и настроения през append_to_response, на 14 езика.
- [API за сериали](https://amodb.dev/bg/tv-series/): API за сериали със същите пътища и JSON като TMDB v3. Сериал по id със сезони, мрежи и следващ епизод, плюс възрастови рейтинги и доставчици за гледане.
- [API за сезони и епизоди на сериали](https://amodb.dev/bg/tv-seasons-episodes/): API за сезони и епизоди със същите пътища и JSON като TMDB v3. Четете сезон с всичките му епизоди или един епизод с дата на излъчване, продължителност и кадър.
- [API за трейлъри на филми](https://amodb.dev/bg/movie-trailer-api/): API за трейлъри върху ендпойнта за видеа на TMDB v3. Подредете трейлъри, тийзъри и клипове по тип, официалност и език, с една заявка на заглавие.
- [API за изображения и хост за изображения](https://amodb.dev/bg/images-api/): API за изображения на филми с пътища на TMDB v3: списъци с постери, фонови изображения, лога и кадри, после зареждане от img.amodb.dev в 10 размера без ключ.
- [Бърз старт](https://amodb.dev/bg/quickstart/): Първата ви заявка към amodb: вземете ключ, поискайте детайли за филм с curl, JavaScript, Python, PHP или Go и заредете постера от img.amodb.dev. До 2 минути.

Обновено: 2026-10-18. Source: https://amodb.dev/bg/videos-trailers/
