Как получить события VK.VideoPlayer в JavaScript для live
Отслеживание vk события play, pause, ended в VK.VideoPlayer: инициализация iframe с js_api=1, ошибки для live.vkvideo.ru, примеры кода, обходные пути с HLS и мониторингом трансляций.
Как получить события от VK.VideoPlayer с помощью JavaScript для отслеживания запуска и остановки трансляций?
Я пытаюсь отследить события запуска и остановки трансляции во встроенном плеере VK, но столкнулся с проблемами при инициализации. Использую следующий код:
<iframe
id="strm"
src="https://live.vkvideo.ru/app/embed/kotik?autoplay=true&js_api=1"
allow="autoplay;encrypted-media;fullscreen;picture-in-picture"
allowfullscreen>
</iframe>
<script src="https://vk.com/js/api/videoplayer.js"></script>
При попытке инициализации плеера:
const player = VK.VideoPlayer("strm");
// или
const player = VK.VideoPlayer(document.querySelector("#strm"));
Получаю ошибку: Uncaught Error: iframe src is not a VK embed
Также заметил, что для трансляций этот подход не работает, так как видео должно быть предварительно загружено. Интересно, как можно реализовать отслеживание состояния плеера для трансляций, подобно тому, как это делается на Twitch.
Ошибка Uncaught Error: iframe src is not a VK embed возникает потому, что VK.VideoPlayer распознаёт только официальные встраиваемые URL (например, video_ext.php?...&js_api=1), а https://live.vkvideo.ru/... — другой хост и другой шаблон embed. Для VOD (video_ext.php) можно инициализировать VK.VideoPlayer и подписаться на vk события (play, pause, ended, timeupdate) через vk api javascript; для live‑трансляций на live.vkvideo.ru официальной поддержки событий нет — придётся использовать обходные пути: прямой HLS + внешний плеер (hls.js/video.js), серверный мониторинг манифеста или неофициальные API (с риском и ограничениями).
Содержание
- VK.VideoPlayer и vk события — почему ваш код падает
- Корректное встраивание VOD (video_ext.php + js_api=1)
- Примеры кода: подписка на события плеера (play/pause/ended)
- Почему live.vkvideo.ru не распознаётся — ограничения для vk live stream
- Обходные варианты для отслеживания старта/остановки трансляции
- Отладка: ошибка “iframe src is not a VK embed” — чеклист
- Источники
- Заключение
VK.VideoPlayer и vk события — почему ваш код падает
Коротко: скрипт https://vk.com/js/api/videoplayer.js проверяет src iframe и допускает только поддерживаемые шаблоны embed (обычно https://vk.com/video_ext.php?...&js_api=1). Если iframe ссылается на другой домен или другой формат (например, https://live.vkvideo.ru/...), инициализация бросит iframe src is not a VK embed. Это подтверждается в официальной документации и исходнике плеера — см. VK Developer Documentation и сам скрипт https://vk.com/js/api/videoplayer.js.
Почему это важно? Потому что для управления и получения событий плеер и API должны договориться по протоколу (обычно через postMessage). Если рукопожатия нет — нет и событий. На практике для VOD‑встраивания (video_ext.php) это работает: можно создать экземпляр VK.VideoPlayer(iframe) и получить методы/события. Но для трансляций на отдельной платформе — часто другой плеер, другие правила, и события ended и т.п. могут отсутствовать или никогда не вызываться (видео считается «вечным»). См. практические обсуждения на StackOverflow на русском.
Корректное встраивание VOD (video_ext.php + js_api=1)
Если задача — отслеживать события через VK.VideoPlayer, используйте официальную встраиваемую ссылку вида https://vk.com/video_ext.php?...&js_api=1. Обычно её можно получить через кнопку “Embed” в публикации ВК или из HTML кода поста.
Пример минимальной разметки для VOD:
<iframe
id="vkPlayer"
src="https://vk.com/video_ext.php?oid=-12345&id=67890&hash=...&js_api=1"
allow="autoplay;encrypted-media;fullscreen;picture-in-picture"
allowfullscreen>
</iframe>
<script src="https://vk.com/js/api/videoplayer.js"></script>
<script>
document.getElementById('vkPlayer').addEventListener('load', () => {
try {
const player = VK.VideoPlayer(document.getElementById('vkPlayer'));
console.log('VK player ready:', player);
// далее — подписка на события (см. далее)
} catch (err) {
console.error(err.message);
}
});
</script>
Нюансы:
- Скрипт
https://vk.com/js/api/videoplayer.jsдолжен загрузиться до вызоваVK.VideoPlayer(или вызывать инициализацию в обработчикеonloadэтого скрипта). - Если видео приватное/требует авторизации — плеер может не инициализироваться.
- После инициализации объект плеера содержит набор методов и событий (в разных версиях API названия методов могут отличаться) — посмотрите
console.dir(player)в DevTools, чтобы увидеть доступные API.
Подробнее о привычном VOD‑паттерне — в официальной документации: VK Developer Documentation и примерах сообщества: qna.habr.com.
Примеры кода: подписка на события плеера в JavaScript (play/pause/ended)
API у разных версий плеера может немного отличаться, потому универсальный приём — сначала инспектировать объект, затем подписаться на доступные методы. Пример «безопасной» подписки, которая проверяет несколько вариантов API:
function subscribeEvent(player, evt, handler) {
if (!player) return;
if (typeof player.on === 'function') {
player.on(evt, handler); // часто встречается
} else if (typeof player.addEventListener === 'function') {
player.addEventListener(evt, handler);
} else if (typeof player.bind === 'function') {
player.bind(evt, handler);
} else {
console.warn('No event API found on VK player — will attempt polling', evt);
}
}
// Пример использования (после успешной инициализации VK.VideoPlayer)
subscribeEvent(player, 'play', () => console.log('play'));
subscribeEvent(player, 'pause', () => console.log('pause'));
subscribeEvent(player, 'ended', () => console.log('ended'));
subscribeEvent(player, 'timeupdate', (t) => console.log('time', t));
Если событий нет или API ограничен — используйте fallback: короткий polling (раз в 1–2 с) с проверкой доступных методов у объекта:
// Polling-safe пример
let lastTime = 0;
const poll = setInterval(() => {
if (!player) return;
if (typeof player.getCurrentTime === 'function') {
const t = player.getCurrentTime();
if (t !== lastTime) {
// проигрывание идёт
lastTime = t;
}
} else if ('currentTime' in player) {
const t = player.currentTime;
if (t !== lastTime) lastTime = t;
} else {
// нет API - остановить polling или перейти к серверному подходу
clearInterval(poll);
}
}, 1000);
Но помните: доступ к свойствам iframe‑вложенного DOM запрещён из-за CORS — polling тут возможен только если API плеера предоставляет методы (postMessage) или если вы используете свой собственный video элемент (см. HLS ниже).
Если вы можете получить прямой поток (MP4/HLS), то лучший и самый надёжный путь — подключить внешний плеер (hls.js / video.js) и подписываться на стандартные события HTMLMediaElement (playing, pause, ended) — пример ниже в разделе Обходы.
Почему live.vkvideo.ru не распознаётся — ограничения для vk live stream
Причины, почему ваш код с https://live.vkvideo.ru/app/embed/...&js_api=1 не работает:
- другой домен и другой шаблон embed — официальный
VK.VideoPlayerожидаетvk.com/video_ext.php(проверка в коде плеера), поэтому он бросаетiframe src is not a VK embed(см. vk.com/js/api/videoplayer.js); - live‑плеер может реализован совсем иначе (специализированный player на live.vkvideo.ru) и не поддерживает js_api handshake;
- трансляции по сути «поточные» и окончание трансляции может не отражаться событием
endedу плеера — платформа может просто перестать выдавать сегменты или показывать оффлайн страницу; обсуждение таких ограничений — на StackOverflow RU и в описании live‑платформы live.vkvideo.ru.
Что это значит практично? Нельзя заставить VK.VideoPlayer работать с iframe, который он не распознаёт. Нельзя надеяться, что play/ended будут приходить, если плеер на стороне сервиса не передаёт эти события.
Обходные варианты для отслеживания старта/остановки трансляции (HLS, серверный мониторинг, неофициальные API)
Если нельзя использовать VK.VideoPlayer для live.vkvideo.ru — есть рабочие альтернативы. Выбор зависит от доступа к прямым потокам и от требований к надёжности.
- Подключить прямой HLS (m3u8) к внешнему плееру (рекомендуется, если у вас есть URL m3u8)
- Используйте hls.js / video.js: вы получите стандартные события медиаплеера. Пример:
<video id="hlsPlayer" controls></video>
<script src="https://cdn.jsdelivr.net/npm/hls.js@latest"></script>
<script>
const video = document.getElementById('hlsPlayer');
const url = 'https://cdn.example.com/live/stream/playlist.m3u8'; // ваш HLS manifest
if (Hls.isSupported()) {
const hls = new Hls();
hls.loadSource(url);
hls.attachMedia(video);
video.addEventListener('playing', () => console.log('stream playing'));
video.addEventListener('pause', () => console.log('paused'));
video.addEventListener('ended', () => console.log('ended'));
} else {
video.src = url; // нативный HLS в Safari
}
</script>
- Минусы: нужен прямой доступ к manifest (CORS) и стабильный URL.
- Серверный мониторинг манифеста (надежно для оповещений)
- Сервер опрашивает HLS manifest (или RTMP ingest/статус) и решает, онлайн ли поток. Затем оповещает клиентов через WebSocket/SSE/webhook. Это обходной, надёжный путь, работает независимо от возможностей embed. Пример Node.js‑логики:
const axios = require('axios');
setInterval(async () => {
try {
const res = await axios.get('https://cdn.example.com/live/stream/playlist.m3u8', { timeout: 5000 });
const data = res.data;
const isLive = data.includes('#EXTINF') && !data.includes('#EXT-X-ENDLIST');
// если состояние изменилось — уведомить клиентов
} catch (e) {
// 404/timeout => возможно offline
}
}, 15000);
- Минусы: нужно серверное место, возможны ограничения доступа к CDN (авторизация/CORS).
- Неформальные/неофициальные API и парсинг страницы
- Есть проекты в сообществе, которые пытаются получить метаданные трансляций у vkplay.live — например unofficial-vk-play-live-api. Но они нестабильны и могут нарушать правила — используйте с осторожностью.
- Для быстрых решений иногда парсят страницу трансляции или используют streamlink/CLI (см. обсуждение streamlink issue). Минус: ненадёжно и может быть запрещено правилами сервиса.
- Запросить официальные webhooks / API (если доступны)
- Иногда платформа предоставляет серверные уведомления о старте/остановке — стоит проверить документацию платформы или обратиться в поддержку.
Итог: если вы не можете получить прямой поток — лучшая схема для надёжности: серверный мониторинг + нотификации клиентам. Если есть прямой m3u8 — используйте hls.js и стандартные события HTMLMediaElement.
Отладка: ошибка “iframe src is not a VK embed” — чеклист
Быстрая проверка — пройдите этот чеклист по порядку:
- Проверьте src iframe — он должен быть
https://vk.com/video_ext.php?...&js_api=1. Если нет — замените на корректный embed (получите код в ВК). - Проверьте наличие параметра
js_api=1в URL — без него скрипт не активирует JS API. - Убедитесь, что
<script src="https://vk.com/js/api/videoplayer.js"></script>загружен ДО вызоваVK.VideoPlayer(или инициализация выполняется в onload скрипта/iframe). - Подождите загрузки iframe (
iframe.addEventListener('load', ...)) — инициализируйте внутри обработчика. - Посмотрите в консоль:
console.dir(VK)иconsole.dir(player)— это покажет доступные методы/события. - Если видео приватное/под авторизацией — проверьте, виден ли embed в режиме инкогнито.
- Если нужен мониторинг live — подумайте о серверном опросе manifest (см. выше).
- Примеры и объяснения ошибок ищите в обсуждениях: StackOverflow RU и в официальной документации VK Widgets — Video.
Если после всех проверок проблема остаётся — пришлите точный iframe src (можно без hash) и скрин консоли — помогу с конкретикой.
Источники
- https://dev.vk.com/ru/widgets/video
- https://vk.com/js/api/videoplayer.js
- https://ru.stackoverflow.com/questions/1444459/Управление-vk-видео-через-js
- https://qna.habr.com/q/1302430
- https://live.vkvideo.ru/
- https://github.com/Something-Went-Wrong-ORG/unofficial-vk-play-live-api
- https://github.com/streamlink/streamlink/issues/879
- https://stackoverflow.com/questions/38969996/vk-com-embed-set-start-time-and-hide-controls
Заключение
Коротко: ваш текущий iframe с live.vkvideo.ru не совместим с VK.VideoPlayer — отсюда ошибка iframe src is not a VK embed. Если цель — отслеживать vk события через VK.VideoPlayer, используйте video_ext.php?...&js_api=1 (VOD). Для live‑трансляций надежнее получить прямой поток (HLS) и подключить hls.js/video.js или реализовать серверный мониторинг manifest (оповещения через WebSocket/SSE). Нужна помощь с конкретной реализацией (например, пример на hls.js + серверный poll для m3u8 или готовый серверный webhook)? Могу подготовить рабочий пример под ваш кейс.