Setting up a product video gallery in 1C-Bitrix

Our company is engaged in the development, support and maintenance of Bitrix and Bitrix24 solutions of any complexity. From simple one-page sites to complex online stores, CRM systems with 1C and telephony integration. The experience of developers is confirmed by certificates from the vendor.
Our competencies:
Development stages
Latest works
  • image_website-b2b-advance_0.png
    B2B ADVANCE company website development
    1212
  • image_bitrix-bitrix-24-1c_fixper_448_0.png
    Website development for FIXPER company
    815
  • image_bitrix-bitrix-24-1c_development_of_an_online_appointment_booking_widget_for_a_medical_center_594_0.webp
    Development based on Bitrix, Bitrix24, 1C for the company Development of an Online Appointment Booking Widget for a Medical Center
    565
  • image_bitrix-bitrix-24-1c_mirsanbel_458_0.webp
    Development based on 1C Enterprise for MIRSANBEL
    747
  • image_crm_dolbimby_434_0.webp
    Website development on CRM Bitrix24 for DOLBIMBY
    657
  • image_crm_technotorgcomplex_453_0.webp
    Development based on Bitrix24 for the company TECHNOTORGKOMPLEKS
    980

Setting Up Product Video Gallery in 1C-Bitrix

When product has three video reviews, montage video and unboxing — one VIDEO_URL property insufficient. Need gallery: switching between clips, preview thumbnails, sync with photo gallery. Bitrix has no ready component, so solution assembled from iblock infrastructure and custom template.

Storing Multiple Videos in Iblock

For multiple videos use property type S (string) with MULTIPLE = Y flag. Symbol code — VIDEO_GALLERY. In b_iblock_element_property each video stored separate row with one IBLOCK_ELEMENT_ID. Get all values:

$videos = [];
$res = \Bitrix\Iblock\ElementPropertyTable::getList([
    'filter' => [
        'IBLOCK_ELEMENT_ID' => $elementId,
        'CODE'              => 'VIDEO_GALLERY',
    ],
    'select' => ['VALUE', 'DESCRIPTION'],
    'order'  => ['ID' => 'ASC'],
]);
while ($row = $res->fetch()) {
    $videos[] = $row;
}

DESCRIPTION field used as video caption — standard field for multiple properties, edited right in element card.

Gallery Structure: Preview + Main Player

Classic pattern — large player-slot top, row of thumbnails bottom. Click thumbnail → main slot changes. Preview from thumbnail API of respective hosting.

catalog.element template, gallery block:

<?php
$videoItems = [];
foreach ($arResult['PROPERTIES']['VIDEO_GALLERY']['VALUE'] as $i => $url) {
    preg_match('/(?:v=|youtu\.be\/)([a-zA-Z0-9_-]{11})/', $url, $m);
    if (!empty($m[1])) {
        $videoItems[] = [
            'id'    => $m[1],
            'desc'  => $arResult['PROPERTIES']['VIDEO_GALLERY']['DESCRIPTION'][$i] ?? '',
            'thumb' => "https://img.youtube.com/vi/{$m[1]}/mqdefault.jpg",
        ];
    }
}
?>
<?php if ($videoItems): ?>
<div class="video-gallery" id="videoGallery">
    <div class="video-gallery__main" data-active="<?= $videoItems[0]['id'] ?>">
        <!-- iframe appears on click via JS -->
    </div>
    <div class="video-gallery__thumbs">
        <?php foreach ($videoItems as $idx => $v): ?>
        <button class="video-gallery__thumb <?= $idx === 0 ? 'is-active' : '' ?>"
                data-video-id="<?= $v['id'] ?>"
                aria-label="<?= htmlspecialcharsEx($v['desc']) ?>">
            <img src="<?= $v['thumb'] ?>" loading="lazy" alt="">
        </button>
        <?php endforeach; ?>
    </div>
</div>
<?php endif; ?>

Combining Video and Photo Gallery

Stores want unified gallery: first photos, then videos. In catalog.element photos from $arResult['MORE_PHOTO'] — array of image paths. Video thumbnails added to same slider container end, but with data-type="video" attribute. JavaScript handles click: if data-type === 'video' — initialize iframe, else — show image.

Allows using one Swiper or Splide instance for both content types without logic duplication.

Cache and Access Rights

Multiple property read within cacheable block. Problem on edit: manager added video in admin, cache not cleared. Must register tag:

$this->SetResultCacheKeys(['PROPERTIES']);
$GLOBALS['CACHE_MANAGER']->RegisterTag('iblock_id_' . CATALOG_IBLOCK_ID);

OnAfterIBlockElementUpdate event in iblock module clears tag on element save.

Vimeo and Other Hostings

If some videos on Vimeo, thumbnail loads via API https://vimeo.com/api/v2/video/{id}.json. Synchronous request — can't do in template. Right approach: Bitrix background agent (CAgent) traverses gallery properties, requests thumbnail, saves URL to separate multiple property VIDEO_THUMB. Template reads ready previews without external requests on render.