Сценарий типичный: файл MP4 загружен в медиабиблиотеку, в карточке товара ссылка есть, но на фронтенде вместо плеера пустой блок, битая иконка или вообще ничего. В WooCommerce это часто всплывает после переноса сайта, смены темы, установки CDN или когда видео вставляют не через редактор, а через кастомное поле и шаблон.
Ниже разберём не «почему WordPress вообще умеет видео», а конкретно: где ломается цепочка от файла в медиабиблиотеке до вывода в товаре, как это проверить и что править без лишних плагинов.
Что именно ломается: диагностика проблемы
Перед правкой кода стоит понять, на каком этапе видео перестаёт работать. Обычно проблема находится в одном из четырёх мест:
- файл загружен, но сервер отдаёт неверный
Content-Type; - в шаблон WooCommerce попадает неправильный URL или пустое значение;
- браузер блокирует воспроизведение из-за политики автозапуска, CORS или mixed content;
- тема переопределила шаблон товара и не выводит нужный HTML.
Быстрая проверка в браузере
Откройте страницу товара и посмотрите исходный HTML. Если вы ожидаете тег <video>, но его нет, значит проблема в PHP-выводе. Если тег есть, но источник не загружается, смотрите вкладку Network в DevTools: там будет либо 404, либо 403, либо неверный MIME-тип, либо редирект на страницу вложения вместо самого файла.
Полезно проверить сам URL файла напрямую. Он должен открываться как медиафайл, а не как HTML-страница вложения WordPress.
Что проверить на сервере
- файл реально лежит в
wp-content/uploadsи не был удалён при миграции; - права на каталог и файл позволяют чтение веб-сервером;
- сервер отдаёт MP4 как
video/mp4, WebM какvideo/webm; - если сайт за HTTPS, видео тоже должно грузиться по HTTPS;
- если используется CDN, он не режет диапазонные запросы и не кэширует HTML вместо файла.
Как вывести видео в карточке товара WooCommerce правильно
Если видео хранится как вложение WordPress, самый надёжный путь — получить URL по ID вложения и вывести обычный HTML5 video. Это лучше, чем вставлять «сырой» URL в контент товара, потому что вы контролируете размеры, poster и fallback.
Ниже пример: видео хранится в произвольном поле product_video_id у товара. Код можно положить в functions.php дочерней темы или в собственный мини-плагин.
<?php
add_action( 'woocommerce_before_single_product_summary', 'wpvideo_output_product_video', 15 );
function wpvideo_output_product_video() {
if ( ! is_product() ) {
return;
}
global $post;
$video_id = (int) get_post_meta( $post->ID, 'product_video_id', true );
if ( ! $video_id ) {
return;
}
$video_url = wp_get_attachment_url( $video_id );
if ( ! $video_url ) {
return;
}
$poster_id = (int) get_post_thumbnail_id( $post->ID );
$poster_url = $poster_id ? wp_get_attachment_image_url( $poster_id, 'large' ) : '';
echo '<div class="product-video">';
echo '<video controls preload="metadata" playsinline' . ( $poster_url ? ' poster="' . esc_url( $poster_url ) . '"' : '' ) . '>';
echo '<source src="' . esc_url( $video_url ) . '" type="video/mp4">';
echo esc_html__( 'Ваш браузер не поддерживает воспроизведение видео.', 'textdomain' );
echo '</video>';
echo '</div>';
}Этот вариант решает сразу две частые проблемы: вы не зависите от визуального редактора и не полагаетесь на то, как тема фильтрует контент товара.
Если видео хранится не в поле, а в описании товара
Тогда проверьте, не вырезает ли тема теги <video> или <source> из контента. Некоторые шаблоны и фильтры безопасности чистят HTML агрессивнее, чем нужно. В таком случае лучше либо разрешить нужные теги через фильтр, либо выводить видео отдельным блоком через хук WooCommerce.
<?php
add_filter( 'wp_kses_allowed_html', function( $tags, $context ) {
if ( 'post' === $context ) {
$tags['video'] = array(
'controls' => true,
'preload' => true,
'playsinline' => true,
'poster' => true,
'width' => true,
'height' => true,
);
$tags['source'] = array(
'src' => true,
'type' => true,
);
}
return $tags;
}, 10, 2 );Такой подход нужен только если вы действительно вставляете видео в контент и видите, что WordPress или тема вырезают теги. Если видео выводится отдельным шаблоном, этот фильтр обычно не нужен.
Пошаговое решение: от файла до фронтенда
Шаг 1. Убедитесь, что у вложения есть прямой URL
В админке откройте файл в медиабиблиотеке и скопируйте ссылку. Если ссылка ведёт на страницу вложения, а не на сам файл, это нормально для некоторых сценариев, но в <video> нужен именно прямой URL на MP4 или WebM.
Шаг 2. Проверьте MIME-тип
Если сервер отдаёт MP4 как application/octet-stream или text/plain, браузер может не воспроизвести файл. На Apache это обычно связано с настройками .htaccess или отсутствием правил для типов файлов. На Nginx — с конфигурацией types.
Для Apache можно добавить типы, если их действительно нет:
<IfModule mod_mime.c>
AddType video/mp4 .mp4
AddType video/webm .webm
</IfModule>После этого очистите кэш сервера и CDN, иначе вы будете смотреть на старый ответ.
Шаг 3. Выведите видео через хук WooCommerce
Если тема ломает стандартный вывод, не правьте шаблон товара в лоб. Сначала используйте хук, чтобы вставить видео в предсказуемое место. Для большинства магазинов удобно ставить блок перед галереей или сразу после неё.
Если нужно разместить видео рядом с галереей, а не в описании, используйте woocommerce_before_single_product_summary или woocommerce_single_product_summary. Это безопаснее, чем редактировать шаблон плагина WooCommerce напрямую.
Шаг 4. Добавьте fallback для старых браузеров и медленных соединений
Для практики полезно добавить постер и текстовый fallback. Это не «косметика», а способ не оставлять пользователя с пустым блоком, если видео не стартовало.
poster— статичная обложка товара;preload="metadata"— не тянуть весь файл сразу;playsinline— особенно важно для мобильных устройств;- текст внутри
<video>— запасной вариант для старых браузеров.
Сравнение подходов: плагин, код, шаблон
| Подход | Когда подходит | Минус |
|---|---|---|
| Плагин для медиа-блоков | Когда нужно быстро без разработки | Может добавлять лишний JS и конфликтовать с темой |
| Код через хук WooCommerce | Когда видео должно стабильно выводиться в карточке товара | Нужно аккуратно поддерживать код |
| Правка шаблона товара | Когда нужен полный контроль над версткой | Сложнее обновлять тему и WooCommerce |
Если у вас уже есть плагин для вставки видео из разных источников, например OmniVideo, его можно использовать для внешних роликов, но для локального MP4 в карточке товара часто проще и надёжнее вывести HTML вручную. Это уменьшает количество зависимостей и упрощает диагностику.
Проверка результата после внедрения
После правок не ограничивайтесь визуальной проверкой на одной странице. Пройдитесь по короткому чек-листу:
- видео видно в карточке товара на десктопе и на мобильном;
- файл открывается напрямую по URL без 404 и 403;
- в DevTools в Network запрос к видео получает
200или корректный206 Partial Content; - в HTML есть тег
<video>и корректныйsource; - если есть CDN, файл не подменяется старой версией;
- страница товара не стала заметно тяжелее из-за автозагрузки видео.
Если видео не воспроизводится только на iPhone или iPad, проверьте, что у тега есть playsinline и что вы не пытаетесь запускать ролик с выключенным звуком через автозапуск. Для мобильных браузеров это частая причина ложного ощущения, что «видео сломалось».
Частые ошибки и как их исправить
1. Вставляют ссылку на страницу вложения вместо файла
В <video> нужен прямой URL на медиафайл. Если подставить страницу attachment, браузер получит HTML, а не видео.
2. Файл загружен, но сервер отдаёт 403
Обычно это права на файл, ограничения в .htaccess, защита hotlinking или CDN, который блокирует прямой доступ. Сначала проверьте прямой URL в новой вкладке, потом уже логи сервера.
3. Видео не видно после обновления темы
Если вы правили шаблон WooCommerce напрямую, обновление темы могло перезаписать изменения. Перенесите вывод в дочернюю тему или в отдельный плагин.
4. Браузер показывает пустой плеер
Часто это неверный MIME-тип, битый файл или неподдерживаемый кодек. MP4 — это контейнер, а не гарантия совместимости. Если ролик закодирован экзотическим профилем, браузер может его не проиграть даже при правильном расширении.
5. Видео есть в HTML, но не видно на странице
Проверьте CSS темы: display:none, height:0, перекрытие блоков, z-index или обрезку контейнера. Иногда проблема вообще не в WooCommerce, а в стилях галереи.
Безопасность и производительность
Локальные видеофайлы быстро раздувают медиабиблиотеку и бэкапы. Если ролики большие, не храните их без необходимости в том же бэкапе, что и весь сайт. Для тяжёлых каталогов лучше заранее продумать хранение и доставку через CDN или отдельное хранилище.
Для фронтенда полезно не грузить видео автоматически, если оно не критично для первого экрана. В карточке товара обычно достаточно постера и ручного запуска. Это снижает нагрузку на страницу и уменьшает риск, что пользователь уйдёт до полной загрузки ролика.
Если вам нужно не только починить вывод, но и стандартизировать работу с видео в магазине, имеет смысл вынести логику в отдельный модуль: одно поле для ID вложения, один хук вывода, один шаблон обложки. Тогда проблему можно будет воспроизводить и проверять на любом товаре, а не искать вручную по контенту.