Current Path : /var/www/axolotl/data/www/kirov.axolotls.ru/bitrix/modules/disk/lib/view/ |
Current File : /var/www/axolotl/data/www/kirov.axolotls.ru/bitrix/modules/disk/lib/view/video.php |
<?php namespace Bitrix\Disk\View; use Bitrix\Disk\Configuration; use Bitrix\Disk\TypeFile; use Bitrix\Main\ArgumentNullException; use Bitrix\Main\UI\Extension; class Video extends Base { // should be equal to \Bitrix\Transformer\VideoTransformer::MAX_FILESIZE const TRANSFORM_VIDEO_MAX_LIMIT = 3221225472; const PLAYER_MIN_WIDTH = 400; const PLAYER_MIN_HEIGHT = 300; public function __construct($name, $fileId, $viewId = null, $previewId = null, $isTransformationEnabledInStorage = true) { parent::__construct($name, $fileId, $viewId, $previewId, $isTransformationEnabledInStorage); $preview = $this->getPreviewData(); if(!empty($preview)) { $sizes = $this->calculateSizes($preview, array('WIDTH' => $this->getJsViewerWidth(), 'HEIGHT' => $this->getJsViewerHeight()), array('WIDTH' => self::PLAYER_MIN_WIDTH, 'HEIGHT' => self::PLAYER_MIN_HEIGHT) ); $this->jsViewerHeight = $sizes['HEIGHT']; $this->jsViewerWidth = $sizes['WIDTH']; } } /** * Extension of the view. * * @return string */ public static function getViewExtension() { return 'mp4'; } /** * Is transformation allowed for this View. * * @return bool */ public static function isTransformationAllowedInOptions() { return Configuration::allowVideoTransformation(); } /** * Returns maximum allowed transformation file size. * * @return int */ public function getMaxSizeTransformation() { return Configuration::getMaxSizeForVideoTransformation(); } /** * Return type of viewer from core_viewer.js * * @return string|null */ public function getJsViewerType() { return 'ajax'; } /** * Return html code to view file. * * @param array $params * @return string */ public function render($params = array()) { if(empty($params) || !isset($params['PATH']) || empty($params['PATH'])) { return ''; } $params = $this->normalizePaths($params); $preview = $this->getPreviewData(); if($params['IFRAME'] == 'Y') { $sizeType = 'fluid'; $params['WIDTH'] = ''; $params['HEIGHT'] = ''; } else { $sizeType = 'adjust'; if($preview) { $sizeType = 'fluid'; } if(isset($params['SIZE_TYPE']) && !empty($params['SIZE_TYPE'])) { $sizeType = $params['SIZE_TYPE']; } if(!empty($preview) && isset($params['WIDTH']) && isset($params['HEIGHT'])) { $sizes = $this->calculateSizes($preview, $params); $params['WIDTH'] = $sizes['WIDTH']; $params['HEIGHT'] = $sizes['HEIGHT']; } if(!isset($params['WIDTH'])) { $params['WIDTH'] = $this->getJsViewerWidth(); } if(!isset($params['HEIGHT'])) { $params['HEIGHT'] = $this->getJsViewerHeight(); } } $autostart = 'Y'; if(isset($params['AUTOSTART']) && $params['AUTOSTART'] == 'N') { $autostart = $params['AUTOSTART']; } if(isset($params['ID'])) { $params['PLAYER_ID'] = $params['ID']; } ob_start(); if($params['IS_MOBILE_APP'] === true) { $this->renderForMobileApp($params); } else { $this->renderForDesktop($params, $autostart, $sizeType); } return ob_get_clean(); } /** * Calculate sizes of popup with player. * @param array $originalSizes * @param array $maxSizes * @param array $minSizes * @return array * @throws ArgumentNullException */ private function calculateSizes($originalSizes, $maxSizes, $minSizes = array()) { if(!isset($originalSizes['WIDTH']) || !isset($originalSizes['HEIGHT'])) { throw new ArgumentNullException('originalSizes'); } if(!isset($maxSizes['WIDTH']) || !isset($maxSizes['HEIGHT'])) { throw new ArgumentNullException('maxSizes'); } if(!isset($minSizes['WIDTH'])) { $minSizes['WIDTH'] = 0; } if(!isset($minSizes['HEIGHT'])) { $minSizes['HEIGHT'] = 0; } if($originalSizes['WIDTH'] > $minSizes['WIDTH'] && $originalSizes['HEIGHT'] > $minSizes['HEIGHT'] && $originalSizes['WIDTH'] < $maxSizes['WIDTH'] && $originalSizes['HEIGHT'] < $maxSizes['HEIGHT']) { $newSizes = array( 'WIDTH' => $originalSizes['WIDTH'], 'HEIGHT' => $originalSizes['HEIGHT'] ); return $newSizes; } if($originalSizes['WIDTH'] < $minSizes['WIDTH'] || $originalSizes['HEIGHT'] < $minSizes['HEIGHT']) { $newSizes = array( 'WIDTH' => $minSizes['WIDTH'], 'HEIGHT' => $minSizes['HEIGHT'] ); $resultRelativeSize = $newSizes['WIDTH'] / $newSizes['HEIGHT']; $videoRelativeSize = $originalSizes['WIDTH'] / $originalSizes['HEIGHT']; if($resultRelativeSize > $videoRelativeSize) { $reduceRatio = $newSizes['WIDTH'] / $originalSizes['WIDTH']; } else { $reduceRatio = $newSizes['HEIGHT'] / $originalSizes['HEIGHT']; } } else { $newSizes = array( 'WIDTH' => $maxSizes['WIDTH'], 'HEIGHT' => $maxSizes['HEIGHT'] ); $resultRelativeSize = $newSizes['WIDTH'] / $newSizes['HEIGHT']; $videoRelativeSize = $originalSizes['WIDTH'] / $originalSizes['HEIGHT']; if($resultRelativeSize > $videoRelativeSize) { $reduceRatio = $newSizes['HEIGHT'] / $originalSizes['HEIGHT']; } else { $reduceRatio = $newSizes['WIDTH'] / $originalSizes['WIDTH']; } } $newSizes['WIDTH'] = floor($originalSizes['WIDTH'] * $reduceRatio); $newSizes['HEIGHT'] = floor($originalSizes['HEIGHT'] * $reduceRatio); return array('WIDTH' => $newSizes['WIDTH'], 'HEIGHT' => $newSizes['HEIGHT']); } /** * Returns true if view can be rendered in some way. * * @return bool */ public function isHtmlAvailable() { if($this->getData() || $this->isTransformationAllowed()) { return true; } return false; } public function renderTransformationInProcessMessage($params = []) { ob_start(); global $APPLICATION; $APPLICATION->IncludeComponent( 'bitrix:disk.file.transform.video', '', [ 'BFILE_ID' => $this->fileId, 'ATTACHED_OBJECT' => $params['ATTACHED_OBJECT'], 'FILE' => $params['FILE'], ] ); return ob_get_clean(); } /** * Returns true if edit button should be hidden in js viewer. * * @return bool */ public function isJsViewerHideEditButton() { return true; } /** * Get type attribute for bb-code in html-editor * * @return string */ public function getEditorTypeFile() { if($this->isHtmlAvailable()) { return 'player'; } return null; } /** * Returns array of extensions that can be viewed. * * @return array */ public static function getViewableExtensions() { return array_merge( array( self::getViewExtension() ), self::getAdditionalViewableExtensions(), self::getAlternativeExtensions() ); } /** * Returns array of alternative extensions, that has the same mime type as main extension * * @return array */ public static function getAlternativeExtensions() { return array('mp4v', 'mpg4'); } /** * @return array */ private static function getAdditionalViewableExtensions() { return array('flv', 'webm', 'ogv', 'mov'); } /** * Returns additional json array parameters for core_viewer.js * * @return array */ public function getJsViewerAdditionalJsonParams() { return array('wrapClassName' => 'bx-viewer-video'); } /** * Returns true if file should be transformed into view regardless of origin extension. * * @return bool */ public static function isAlwaysTransformToViewFormat() { return true; } /** * Returns true if attached object with this file should have limited rights while transform in progress. * * @return bool */ public function isNeededLimitRightsOnTransformTime() { if($this->id > 0) { return false; } $mp4Formats = array_merge( array( self::getViewExtension() ), self::getAlternativeExtensions() ); if(in_array(strtolower($this->fileExtension), $mp4Formats)) { return false; } if($this->isLastTransformationFailed()) { return false; } return $this->isTransformationAllowed(); } /** * Check $params['PATH'] and fills $params['TRACKS'] from it with mime-types. * * @param array $params * @return mixed */ protected function normalizePaths($params) { $mimeTypes = TypeFile::getMimeTypeExtensionList(); if(is_array($params['PATH'])) { foreach($params['PATH'] as $key => $source) { if($key == 0) { $type = $mimeTypes[$this->getExtension()]; } else { $type = TypeFile::getMimeTypeByFilename($this->name); } $params['TRACKS'][] = array( 'src' => $source, 'type' => $type, ); } $params['USE_PLAYLIST_AS_SOURCES'] = 'Y'; $params['USE_PLAYLIST'] = 'Y'; unset($params['PATH']); } else { $params['TYPE'] = $mimeTypes[$this->getExtension()]; } return $params; } /** * Include component to render player in mobile application. * * @param array $params */ protected function renderForMobileApp($params) { global $APPLICATION; $APPLICATION->IncludeComponent( 'bitrix:mobile.player', '', $params ); } /** * Include component to render player with custom skin in browser. * * @param array $params * @param string $autostart * @param string $sizeType */ protected function renderForDesktop($params, $autostart, $sizeType) { ?><div class="disk-player-container<?if($sizeType == 'adjust') { ?> player-adjust<? } ?>"<? if($sizeType == 'fluid') { ?> style="width: <?=$params['WIDTH'];?>px; height: <?=$params['HEIGHT'];?>px;"<? } ?>> <div class="main-ui-loader"> <svg class="main-ui-loader-svg" viewBox="25 25 50 50"> <circle class="main-ui-loader-svg-circle" cx="50" cy="50" r="20" fill="none" stroke-miterlimit="10"/> </svg> </div> <? global $APPLICATION; Extension::load(['disk.video']); $APPLICATION->IncludeComponent( 'bitrix:player', '', array_merge($params, array( 'SIZE_TYPE' => $sizeType, 'PLAYER_TYPE' => 'videojs', 'AUTOSTART' => $autostart, 'SKIN_PATH' => '/bitrix/js/disk/video/', 'SKIN' => 'disk_player.css', 'HIDE_ERRORS' => 'Y', ) )); ?></div><? } /** * Returns true if we should display message about transformation status. * * @return bool */ public function isShowTransformationInfo() { if(!self::isTransformationAllowedInOptions()) { return false; } if($this->id > 0) { return false; } if($this->getSize() < self::TRANSFORM_VIDEO_MAX_LIMIT) { return true; } return false; } }