CanPlayType: примеры (JAVASCRIPT)

Проверка поддержки медиаформатов с помощью canPlayType
Раздел: Мультимедиа, Видео/Аудио
canPlayType(type: String): String (probably, maybe, '')

Описание функции canPlayType

Метод canPlayType() принадлежит объектам HTMLMediaElement (таким как <audio> и <video>). Он предназначен для определения возможности воспроизведения браузером медиафайла определенного типа без необходимости его загрузки. Функция используется для предварительной проверки поддержки форматов и кодеков, что позволяет создавать адаптивные медиаплееры с фолбэками.

Функция принимает один аргумент:

  • type (обязательный): Строка, представляющая MIME-тип медиа и, опционально, параметры кодеков. Например, 'video/mp4' или 'video/mp4; codecs="avc1.42E01E, mp4a.40.2"'.

Возвращаемое значение:

  • "probably": Высокая вероятность, что тип может быть воспроизведен.
  • "maybe": Тип, возможно, может быть воспроизведен, но для уверенности требуется попытка загрузки.
  • "" (пустая строка): Браузер не поддерживает данный тип медиа.

Простые примеры использования

Пример 1: Проверка базовых форматов.

const video = document.createElement('video');
console.log(video.canPlayType('video/mp4'));
console.log(video.canPlayType('video/webm'));
console.log(video.canPlayType('video/ogg'));
"probably"
"probably"
"maybe"

Пример 2: Проверка аудиоформатов с указанием кодека.

const audio = document.createElement('audio');
console.log(audio.canPlayType('audio/mpeg'));
console.log(audio.canPlayType('audio/ogg; codecs="opus"'));
console.log(audio.canPlayType('audio/wav'));
"probably"
"probably"
""

Альтернативные методы в JavaScript

Прямых аналогов canPlayType() в JavaScript нет, но существуют смежные подходы:

  • MediaSource.isTypeSupported(): Часть Media Source Extensions API. Проверяет поддержку типа для генеративного воспроизведения (например, для DASH, HLS). Более точна для потоковых форматов.
    console.log(MediaSource.isTypeSupported('video/mp4; codecs="avc1.42E01E, mp4a.40.2"'));
  • Практическая попытка загрузки и воспроизведения: Создание элемента, установка src и обработка событий canplay и error. Это наиболее надежный, но асинхронный и ресурсозатратный метод.

canPlayType() предпочтительнее для быстрой синхронной проверки. MediaSource.isTypeSupported() используют при работе с расширенными медиаисточниками.

Аналоги в других языках программирования

Проверка типа медиа на других языках обычно происходит на стороне сервера или с помощью специализированных библиотек для анализа файлов, а не браузерной поддержки.

Python (библиотека mimetypes): Определяет MIME-тип по расширению файла, но не проверяет поддержку кодеков.

import mimetypes
print(mimetypes.guess_type('video.mp4')[0])  # 'video/mp4'
video/mp4

PHP (mime_content_type, finfo): Анализирует содержимое файла для определения его настоящего MIME-типа.

$finfo = finfo_open(FILEINFO_MIME_TYPE);
echo finfo_file($finfo, 'example.webm');
finfo_close($finfo);
video/webm

Эти методы служат другой цели - идентификации типа файла, в то время как canPlayType оценивает возможности среды воспроизведения (браузера).

Типичные ошибки

Ошибка 1: Вызов метода у элемента, который не является медиаэлементом.

const div = document.createElement('div');
console.log(div.canPlayType('video/mp4'));
Uncaught TypeError: div.canPlayType is not a function

Ошибка 2: Неверный формат строки типа. Отсутствие слеша или некорректный параметр codecs.

const video = document.createElement('video');
console.log(video.canPlayType('mp4')); // Нет MIME-типа
console.log(video.canPlayType('video/mp4; codec=avc1')); // codec вместо codecs
""
"" (или "maybe", в зависимости от браузера)

Ошибка 3: Попытка использовать результат как булево значение.

if (video.canPlayType('video/mp4')) {
    console.log('Поддерживается!');
} // Условие не выполнится для "", выполнится для "probably" и "maybe"

Правильно проверять конкретную возвращаемую строку.

История изменений

Спецификация функции стабильна, основные изменения касаются поддержки новых кодеков браузерами, а не самого API. Например, с течением времени ответ для 'video/webm; codecs="vp9"' изменился с пустой строки на "probably" в большинстве современных браузеров. Работа с параметром codecs стала более точной и детальной.

Расширенные примеры

Пример 1: Функция для определения оптимального источника видео из списка.

Пример javascript
function getSupportedSource(sources) {
    const video = document.createElement('video');
    for (const src of sources) {
        if (video.canPlayType(src.type) === 'probably') {
            return src.url;
        }
    }
    for (const src of sources) {
        if (video.canPlayType(src.type) === 'maybe') {
            return src.url;
        }
    }
    return null;
}

const formats = [
    { type: 'video/webm; codecs="vp9, opus"', url: 'movie_hd.webm' },
    { type: 'video/mp4; codecs="avc1.4D401E, mp4a.40.2"', url: 'movie_sd.mp4' },
    { type: 'video/ogg; codecs="theora, vorbis"', url: 'movie.ogv' }
];
console.log(getSupportedSource(formats));
"movie_hd.webm" (если VP9 поддерживается)

Пример 2: Динамическое создание элемента video с поддержкой фолбэка.

Пример javascript
function createVideoPlayer(format, fallbackFormat) {
    const video = document.createElement('video');
    const source = document.createElement('source');

    if (video.canPlayType(format.type)) {
        source.src = format.url;
        source.type = format.type;
    } else if (fallbackFormat && video.canPlayType(fallbackFormat.type)) {
        source.src = fallbackFormat.url;
        source.type = fallbackFormat.type;
    } else {
        video.innerHTML = 'Ваш браузер не поддерживает видео.';
    }
    video.appendChild(source);
    return video;
}

Пример 3: Сравнение проверки через canPlayType и MediaSource.

Пример javascript
const testType = 'video/mp4; codecs="av01.0.08M.08, opus"';
const videoEl = document.createElement('video');
console.log('canPlayType:', videoEl.canPlayType(testType));
if (typeof MediaSource !== 'undefined') {
    console.log('MediaSource.isTypeSupported:', MediaSource.isTypeSupported(testType));
}
canPlayType: "" (или "maybe")
MediaSource.isTypeSupported: false

JS canPlayType function comments

En
CanPlayType Returns an estimate of the likelihood that the browser can play a given media type