cloudinary-8.x-1.x-dev/modules/cloudinary_video/src/Element/CloudinaryVideo.php

modules/cloudinary_video/src/Element/CloudinaryVideo.php
<?php

namespace Drupal\cloudinary_video\Element;

use Cloudinary\Asset\DeliveryType;
use Cloudinary\Tag\VideoTag;
use Drupal\Component\Serialization\Json;
use Drupal\Core\Cache\Cache;
use Drupal\Core\Render\Element\RenderElement;
use Drupal\Core\Render\Markup;
use Drupal\Core\Url;

/**
 * Provides a render element to render cloudinary video.
 *
 * Properties:
 * - #public_id: Public ID of the asset to render.
 * - #player_type: Override default player type.
 * - #muted: Mute the video.
 * - #controls: Whether to show controls.
 * - #autoplay: Autoplay video.
 * - #loop: Loop video.
 * - #player: Override default cloudinary player configuration.
 * - #responsive: Whether to display responsive video.
 * - #width: Width of the video (applicable if video is not responsive).
 * - #height: Height of the video (applicable if video is not responsive).
 * - #delivery_type: Delivery type of the asset.
 * - #sources: Override default sources.
 * - #default_transformation: Whether to apply default video transformation.
 * - #attributes: Apply custom attributes to the video.
 * - #raw_transformation: Optional string of URL transformation.
 *     e.g. 'e_progressbar:width_5'.
 *
 * Usage Example:
 * @code
 * $build['video'] = [
 *   '#type' => 'cloudinary_video',
 *   '#public_id' => 'samples/cld-sample-video',
 *   '#raw_transformation' => 'e_progressbar:width_5',
 *   '#width' => '100%',
 *   '#attributes' => ['class' => ['demo-video']],
 * ];
 * @endcode
 *
 * @RenderElement("cloudinary_video")
 */
class CloudinaryVideo extends RenderElement {

  /**
   * {@inheritdoc}
   */
  public function getInfo() {
    return [
      '#width' => 854,
      '#height' => 480,
      '#autoplay' => FALSE,
      '#raw_transformation' => NULL,
      '#sources' => NULL,
      '#responsive' => TRUE,
      '#resource_type' => 'video',
      '#player_type' => 'auto',
      '#delivery_type' => DeliveryType::UPLOAD,
      '#attributes' => [],
      '#muted' => FALSE,
      '#controls' => FALSE,
      '#loop' => FALSE,
      '#default_transformation' => TRUE,
      '#pre_render' => [
        [get_class($this), 'preRenderVideoElement'],
      ],
    ];
  }

  /**
   * Build an url for cloudinary player iframe.
   *
   * @param array $element
   *   The element array.
   *
   * @return \Drupal\Core\Url
   *   The source iframe url.
   */
  protected static function buildUrl(array $element): Url {
    $sdk_config = \Drupal::config('cloudinary_sdk.settings');
    $video_config = \Drupal::config('cloudinary_video.settings');

    // Define required params for the source url.
    $query = [
      'cloud_name' => $sdk_config->get('cloudinary_sdk_cloud_name'),
      'public_id' => $element['#public_id'],
    ];

    // Use cname option in the url.
    if ($cname = $sdk_config->get('cloudinary_sdk_cname')) {
      $query['cloudinary'] = [
        'secure_distribution' => $cname,
        'private_cdn' => TRUE,
      ];
    }

    // Override default player settings.
    $player = $element['#player'] ?? [];
    if ($player_settings = $video_config->get('cloudinary_video_player_config')) {
      $player += Json::decode($player_settings);
    }

    if ($player) {
      $query['player'] = $player;
    }

    // Force the controls visibility option.
    $query['player']['controls'] = $element['#controls'] ? 'true' : 'false';

    // Force the loop option.
    $query['player']['loop'] = $element['#loop'] ? 'true' : 'false';

    // Force the muted option.
    $query['player']['muted'] = $element['#muted'] ? 'true' : 'false';

    // Force autoplay option for the player.
    if ($element['#autoplay']) {
      $query['player']['autoplay'] = 'true';
      $query['player']['autoplayMode'] = 'always';
    }

    // Apply default transformation.
    $transformations = [];
    if ($element['#default_transformation']) {
      if ($transformation = $video_config->get('cloudinary_video_optimizations')) {
        $transformations[] = $transformation;
      }
    }

    // Apply custom transformation.
    if ($element['#raw_transformation']) {
      $transformations[] = $element['#raw_transformation'];
    }

    if ($transformations) {
      $query['source']['transformation']['raw_transformation'] = implode('/', $transformations);
    }

    return Url::fromUri('https://player.cloudinary.com/embed/', [
      'query' => $query,
    ]);
  }

  /**
   * Cloudinary video element process callback.
   */
  public static function preRenderVideoElement($element) {
    $video_config = \Drupal::config('cloudinary_video.settings');
    $player_type = $element['#player_type'] === 'auto'
      ? $video_config->get('cloudinary_default_player')
      : $element['#player_type'];

    $element['#player_type'] = $player_type;
    $element['#theme'] = 'cloudinary_video_player';

    switch ($player_type) {
      case 'cloudinary':
        $url = static::buildUrl($element);

        $default_attributes = [
          'src' => $url->toString(),
          'frameborder' => 0,
          'scrolling' => FALSE,
          'allow' => 'autoplay; fullscreen; encrypted-media; picture-in-picture',
          'allowfullscreen' => 'true',
        ];

        if (!$element['#responsive']) {
          $default_attributes['width'] = $element['#width'];
          $default_attributes['height'] = $element['#height'];
        }

        $element['#children'] = [
          '#type' => 'html_tag',
          '#tag' => 'iframe',
          '#attributes' => $element['#attributes'] + $default_attributes,
        ];
        break;

      case 'html5':
        $video_tag = new VideoTag($element['#public_id'], $element['#sources']);
        $default_attributes = [];

        // Set up global player settings.
        if ($player_attributes = $video_config->get('cloudinary_default_player_config')) {
          foreach (explode(' ', $player_attributes) as $attribute) {
            $data = explode('=', $attribute);
            $default_attributes[$data[0]] = $data[1] ?? $data[0];
          }
        }

        // Force height and width for non-responsive video.
        if (!$element['#responsive']) {
          $default_attributes['width'] = $element['#width'];
          $default_attributes['height'] = $element['#height'];
        }

        // Override attributes with custom one.
        if (isset($element['#attributes']['class'])) {
          $video_tag->addClass($element['#attributes']['class']);
          unset($element['#attributes']['class']);
        }

        $attributes = $element['#attributes'] + $default_attributes;

        $video_tag->setAttributes($attributes);
        $video_tag->fallback(t('Your browser does not support HTML5 video tags'));
        $video_tag->deliveryType($element['#delivery_type']);

        // Apply default transformation.
        if ($element['#default_transformation']) {
          if ($transformation = $video_config->get('cloudinary_video_optimizations')) {
            $video_tag->addTransformation($transformation);
          }
        }

        // Apply custom transformation.
        if ($element['#raw_transformation']) {
          $video_tag->addTransformation($element['#raw_transformation']);
        }

        $optional_attributes = [
          'loop',
          'muted',
          'controls',
          'autoplay',
        ];

        foreach ($optional_attributes as $attribute) {
          if (!empty($element["#{$attribute}"])) {
            $video_tag->setAttribute($attribute, $attribute);
          }
        }

        $element += [
          '#children' => Markup::create((string) $video_tag),
        ];
        break;
    }

    $tags = $element['#cache']['tags'] ?? [];
    $element['#cache']['tags'] = Cache::mergeTags($tags, $video_config->getCacheTags());

    return $element;
  }

}

Главная | Обратная связь

drupal hosting | друпал хостинг | it patrol .inc