RuTube Video Integration in 1C-Bitrix Product Card
RuTube is Russian video platform increasingly used as YouTube alternative on domestic projects. Technically RuTube integration in product card differs from YouTube: different Video ID format, different embed-link structure, no public thumbnail CDN. Here's how to implement without extra dependencies.
RuTube URL Structure and Video ID
RuTube uses UUID (32 characters without dashes) as video identifier. Link formats:
-
https://rutube.ru/video/a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4/— standard URL -
https://rutube.ru/play/embed/a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4— already embed-link
Parsing Video ID:
function parseRutubeId(string $url): ?string
{
if (preg_match(
'/rutube\.ru\/(?:video|play\/embed)\/([a-f0-9]{32})/',
$url,
$m
)) {
return $m[1];
}
return null;
}
function getRutubeEmbedUrl(string $videoId): string
{
return 'https://rutube.ru/play/embed/' . $videoId
. '?rel=0&showControls=1&skinColor=ff0000&startFrom=0&mute=0';
}
RuTube embed parameters much poorer than YouTube: main — rel (don't show similar videos), skinColor (player elements color in HEX without #), mute.
Storage in 1C-Bitrix Infoblock
Similar to YouTube — "String" type property with code VIDEO_RUTUBE, multiple if needed:
CIBlockProperty::Add([
'IBLOCK_ID' => CATALOG_IBLOCK_ID,
'NAME' => 'RuTube Video',
'CODE' => 'VIDEO_RUTUBE',
'PROPERTY_TYPE' => 'S',
'MULTIPLE' => 'Y',
'SORT' => 210,
]);
If project uses both sources (YouTube + RuTube), can create one universal VIDEO_URL property and detect platform by URL domain.
Getting Thumbnail via API
Unlike YouTube, RuTube has no public CDN for preview by template URL. Thumbnail must be obtained via API:
GET https://rutube.ru/api/video/{VIDEO_ID}/?format=json
Response contains thumbnail_url field — direct thumbnail link. Also available title, description, duration.
function getRutubeVideoInfo(string $videoId): ?array
{
$cacheKey = 'rutube_' . $videoId;
$cache = \Bitrix\Main\Data\Cache::createInstance();
if ($cache->initCache(3600 * 24, $cacheKey, '/rutube/')) {
return $cache->getVars();
}
$http = new \Bitrix\Main\Web\HttpClient();
$response = $http->get("https://rutube.ru/api/video/{$videoId}/?format=json");
if ($http->getStatus() !== 200) {
return null;
}
$data = json_decode($response, true);
if (empty($data['id'])) {
return null;
}
$result = [
'id' => $data['id'],
'title' => $data['title'] ?? '',
'thumbnail_url' => $data['thumbnail_url'] ?? '',
'duration' => $data['duration'] ?? 0,
];
$cache->startDataCache(3600 * 24, $cacheKey, '/rutube/');
$cache->endDataCache($result);
return $result;
}
24-hour cache mandatory — RuTube API has no published limits, but frequent requests on high traffic create load and slow page response.
Output in Product Card Template
$rutubeUrls = (array)($arResult['PROPERTIES']['VIDEO_RUTUBE']['VALUE'] ?? []);
foreach ($rutubeUrls as $rutubeUrl) {
$videoId = parseRutubeId($rutubeUrl);
if (!$videoId) continue;
$info = getRutubeVideoInfo($videoId);
$thumbUrl = $info['thumbnail_url'] ?? '/local/img/video-placeholder.jpg';
$embedUrl = getRutubeEmbedUrl($videoId);
echo '<div class="rutube-facade" data-embed="' . htmlspecialchars($embedUrl) . '">';
echo '<img src="' . htmlspecialchars($thumbUrl) . '"
alt="' . htmlspecialchars($info['title'] ?? 'Video review') . '"
loading="lazy" width="640" height="360">';
echo '<button class="play-btn" aria-label="Watch video"></button>';
echo '</div>';
}
JavaScript initialization (similar to YouTube facade):
document.querySelectorAll('.rutube-facade').forEach(function(el) {
el.addEventListener('click', function() {
const iframe = document.createElement('iframe');
iframe.src = this.dataset.embed + '&autoplay=1';
iframe.width = '640';
iframe.height = '360';
iframe.allowFullscreen = true;
iframe.allow = 'autoplay; encrypted-media';
this.replaceWith(iframe);
});
});
Joint YouTube and RuTube Usage
If card needs both services, unify handling via one VIDEO_URL property:
function detectVideoSource(string $url): string
{
if (str_contains($url, 'youtube.com') || str_contains($url, 'youtu.be')) {
return 'youtube';
}
if (str_contains($url, 'rutube.ru')) {
return 'rutube';
}
return 'unknown';
}
Simplifies manager's work: one property type, paste any link, system figures it out.
SEO Markup VideoObject for RuTube
Search engines accept VideoObject markup for RuTube too:
if ($info) {
$schema = [
'@context' => 'https://schema.org',
'@type' => 'VideoObject',
'name' => $info['title'],
'thumbnailUrl'=> $info['thumbnail_url'],
'embedUrl' => getRutubeEmbedUrl($videoId),
'duration' => 'PT' . gmdate('H\Hi\Ms\S', $info['duration']),
'uploadDate' => date('c'),
];
echo '<script type="application/ld+json">'
. json_encode($schema, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)
. '</script>';
}
RuTube videos indexed in Yandex search and may appear in video results. Google doesn't guarantee RuTube content indexing yet, but markup won't hurt.
Implementation Timeline
| Variant | Work | Timeline |
|---|---|---|
| Basic (single video, iframe without preview) | Property + template | 0.5 day |
| With API preview and facade pattern | API request + cache + JS | 1–2 days |
| Universal (YouTube + RuTube + SEO + gallery) | Single property + platform routing + markup | 2–3 days |







