Просмотр исходного кода

#3331 Videos: ffmpeg is called upon opening view video page

Alex Trofimov 5 лет назад
Родитель
Сommit
917c5dcaf3

+ 58 - 3
inc/classes/BxDolStorage.php

@@ -79,7 +79,8 @@ define('BX_DOL_STORAGE_QUEUED_DELETIONS_PER_RUN', 200); ///< max number of file
  * - engine - storage engine, for now the following engines are supported:
  *     1. Local - local storage, by default files are stored in /storage/ subfolder 
  *     2. S3 - Amazon S3 storage, files are stored on Amazon S3 storage, you need to point AWS Access Key, AWS Secret Key and AWS Bucket in the settings
- * - params - custom storage engine params as php serialized string
+ * - params - custom storage engine params as php serialized string, supported params:
+ *      1. fields - list of additional fields to add to database as key(field name) and value(func or serialized service call to get the value)
  * - token_life - life of the security token in seconds for private files
  * - cache_control - control browser cache, allow browser to store files in browser's cache for this number of seconds, to disable browser cache,
  *   or let browser to decide on its own set it to 0(zero)
@@ -450,6 +451,21 @@ abstract class BxDolStorage extends BxDolFactory implements iBxDolFactoryObject
             return false;
         }
 
+        // process additional custom fields, like video duration and video dimension
+
+        $aAdditionalFields = array();
+        if (isset($this->_aParams['fields']) && is_array($this->_aParams['fields'])) {
+            foreach ($this->_aParams['fields'] as $sField => $mixedMethod) {
+                if (is_string($mixedMethod) && method_exists($this, $mixedMethod)) {
+                    $aAdditionalFields[$sField] = $this->$mixedMethod($sTmpFile, $sMimeType, $sExt, $this);
+                }
+                elseif (is_array($mixedMethod) && isset($mixedMethod['module']) && isset($mixedMethod['method'])) {
+                    $mixedMethod['params'] = array($sTmpFile, $sMimeType, $sExt, $this);
+                    $aAdditionalFields[$sField] = call_user_func_array('bx_srv', array($mixedMethod['module'], $mixedMethod['method'], $mixedMethod['params'], isset($mixedMethod['class']) ? $mixedMethod['class'] : 'Module'));
+                } 
+            }
+        }
+
         // store file to storage engine
 
         $sLocalId = $this->genRandName();
@@ -467,7 +483,7 @@ abstract class BxDolStorage extends BxDolFactory implements iBxDolFactoryObject
 
         $iTime = time();
         $iSize = $oHelper->getSize();
-        $bFileAdded = $this->_oDb->addFile($iProfileId, $sLocalId, $sRemoteNamePath, $oHelper->getName(), $sMimeType, $sExt, $iSize, $iTime, $isPrivate);
+        $bFileAdded = $this->_oDb->addFile($iProfileId, $sLocalId, $sRemoteNamePath, $oHelper->getName(), $sMimeType, $sExt, $iSize, $iTime, $isPrivate, $aAdditionalFields);
         $iId = $this->_oDb->lastId();
         if (!$bFileAdded || !$iId) {
             $this->deleteFileFromEngine($sPath . $sLocalId, $isPrivate);
@@ -689,7 +705,29 @@ abstract class BxDolStorage extends BxDolFactory implements iBxDolFactoryObject
      */
     public function getFile($iFileId)
     {
-        return $this->_oDb->getFileById($iFileId);
+        $a = $this->_oDb->getFileById($iFileId);
+
+        // update custom fields for previously uploaded files
+        if (!defined('BX_DOL_STORAGE_CUSTOM_FIELDS_UPDATE_SKIP') && isset($this->_aParams['fields']) && is_array($this->_aParams['fields'])) {
+            foreach ($this->_aParams['fields'] as $sField => $mixedMethod) {
+                if ($a[$sField])
+                    continue;
+
+                $sFileUrl = $this->getFileUrlById($iFileId);
+
+                if (is_string($mixedMethod) && method_exists($this, $mixedMethod)) {
+                    $a[$sField] = $this->$mixedMethod($sFileUrl, $a['mime_type'], $a['ext'], $this);
+                }
+                elseif (is_array($mixedMethod) && isset($mixedMethod['module']) && isset($mixedMethod['method'])) {
+                    $mixedMethod['params'] = array($sFileUrl, $a['mime_type'], $a['ext'], $this);
+                    $a[$sField] = call_user_func_array('bx_srv', array($mixedMethod['module'], $mixedMethod['method'], $mixedMethod['params'], isset($mixedMethod['class']) ? $mixedMethod['class'] : 'Module'));
+                } 
+                if ($a[$sField])
+                    $this->_oDb->modifyCustomField($iFileId, $sField, $a[$sField], false);
+            }
+        }
+
+        return $a;
     }
 
     /**
@@ -1201,6 +1239,23 @@ abstract class BxDolStorage extends BxDolFactory implements iBxDolFactoryObject
 
         return $this->queueFilesForDeletion($a);
     }
+
+    protected function getFileDuration($sFilePath, $sMimeType, $sExt, $oStorage)
+    {
+        if (strncmp('video/', $sMimeType, 6) === 0)
+            return (int)BxDolTranscoderVideo::getDuration($sFilePath);
+        return 0;
+    }
+
+    protected function getFileDimensions($sFilePath, $sMimeType, $sExt, $oStorage)
+    {
+        if (strncmp('video/', $sMimeType, 6) === 0 && $o = BxDolTranscoderVideo::getObjectVideoAbstract()) {
+            $a = $o->getVideoSize($sFilePath);
+            if ($a && isset($a['w']) && isset($a['h']))
+                return $a['w'] . 'x' . $a['h'];
+        }
+        return '';
+    }
 }
 
 

+ 14 - 6
inc/classes/BxDolStorageQuery.php

@@ -122,13 +122,21 @@ class BxDolStorageQuery extends BxDolDb
         return BxDolProfileQuery::getInstance()->updateProfileQuota($iProfileId, $iSize, $iNumber);
     }
 
-    public function addFile($iProfileId, $sLocalId, $sPath, $aFileName, $sMimeType, $sExt, $iSize, $iTime, $isPrivate)
+    public function addFile($iProfileId, $sLocalId, $sPath, $aFileName, $sMimeType, $sExt, $iSize, $iTime, $isPrivate, $aAdditionalFields = array())
     {
-        $sQuery = $this->prepare("INSERT INTO " . $this->_sTableFiles . " SET
-            `profile_id` = ?, `remote_id` = ?, `path` = ?, `file_name` = ?, `mime_type` = ?, `ext` = ?, `size` = ?, `added` = ?, `modified` = ?, `private` = ?",
-            $iProfileId, $sLocalId, $sPath, $aFileName, $sMimeType, $sExt, $iSize, $iTime, $iTime, $isPrivate ? 1 : 0
-        );
-        return $this->query($sQuery);
+        $aBind = array('profile_id' => $iProfileId, 'local_id' => $sLocalId, 'path' => $sPath, 'file_name' => $aFileName, 'mime_type' => $sMimeType, 'ext' => $sExt, 'size' => $iSize, 'time' => $iTime, 'private' => $isPrivate ? 1 : 0);
+
+        $sQuery = "INSERT INTO " . $this->_sTableFiles . " SET
+            `profile_id` = :profile_id, `remote_id` = :local_id, `path` = :path, `file_name` = :file_name, `mime_type` = :mime_type, `ext` = :ext, `size` = :size, `added` = :time, `modified` = :time, `private` = :private";
+
+        if ($aAdditionalFields && is_array($aAdditionalFields)) {
+            foreach ($aAdditionalFields as $sField => $sValue) {
+                $aBind[$sField] = $sValue;
+                $sQuery .= ", `$sField` = :$sField";
+            }
+        }
+
+        return $this->query($sQuery, $aBind);
     }
 
     public function modifyFilePrivate($iFileId, $isPrivate)

+ 10 - 0
inc/classes/BxDolTranscoderVideo.php

@@ -77,6 +77,16 @@ class BxDolTranscoderVideo extends BxDolTranscoder implements iBxDolFactoryObjec
         $this->_sQueueTable = $this->_oDb->getQueueTable();
     }
 
+    public static function getObjectVideoAbstract()
+    {
+        if (isset($GLOBALS['bxDolClasses'][__CLASS__ . '!Abstract']))
+            return $GLOBALS['bxDolClasses'][__CLASS__ . '!Abstract'];
+
+        $aObject = array('object' => 'abstract');
+        $o = new BxDolTranscoderVideo ($aObject, null);
+        return ($GLOBALS['bxDolClasses'][__CLASS__ . '!Abstract'] = $o);
+    }
+
     public static function getDuration($sFile)
     {
         $sCommand = escapeshellcmd(BX_SYSTEM_FFMPEG) . " -i " . escapeshellarg($sFile) . " 2>&1";

+ 2 - 2
modules/boonex/videos/classes/BxVideosModule.php

@@ -122,10 +122,10 @@ class BxVideosModule extends BxBaseModTextModule
             $sPoster = $oTcvPoster->getFileUrl($iFile);
 
         $sVideoUrl = $oStorage->getFileUrlById($iFile);
-        $aVideoSize = $oTcvMp4Hd->getVideoSize($sVideoUrl);
+        $aVideoFile = $oStorage->getFile($iFile);
 
         $sVideoUrlHd = '';
-        if(!empty($aVideoSize) && is_array($aVideoSize) && (int)$aVideoSize['h'] >= 720)
+        if (!empty($aVideoFile['dimensions']) && ($aDim = explode('x', $aVideoFile['dimensions'])) && isset($aDim[1]) && (int)$aDim[1] >= 720)
             $sVideoUrlHd = $oTcvMp4Hd->getFileUrl($iFile);
 
         return array(

+ 2 - 2
modules/boonex/videos/classes/BxVideosTemplate.php

@@ -101,10 +101,10 @@ class BxVideosTemplate extends BxBaseModTextTemplate
             $sPoster = $aTranscodersVideo['poster']->getFileUrl($iFile);
 
         $sVideoUrl = $oStorage->getFileUrlById($iFile);
-        $aVideoSize = $aTranscodersVideo['mp4_hd']->getVideoSize($sVideoUrl);
+        $aVideoFile = $oStorage->getFile($iFile);
 
         $sVideoUrlHd = '';
-        if(!empty($aVideoSize) && is_array($aVideoSize) && (int)$aVideoSize['h'] >= 720)
+        if (!empty($aVideoFile['dimensions']) && ($aDim = explode('x', $aVideoFile['dimensions'])) && isset($aDim[1]) && (int)$aDim[1] >= 720)
             $sVideoUrlHd = $aTranscodersVideo['mp4_hd']->getFileUrl($iFile);
 
         return array(

+ 2 - 1
modules/boonex/videos/install/sql/install.sql

@@ -61,6 +61,7 @@ CREATE TABLE IF NOT EXISTS `bx_videos_videos` (
   `mime_type` varchar(128) NOT NULL,
   `ext` varchar(32) NOT NULL,
   `size` bigint(20) NOT NULL,
+  `dimensions` varchar(12) NOT NULL,
   `added` int(11) NOT NULL,
   `modified` int(11) NOT NULL,
   `private` int(11) NOT NULL,
@@ -282,7 +283,7 @@ SET @sStorageEngine = (SELECT `value` FROM `sys_options` WHERE `name` = 'sys_sto
 
 INSERT INTO `sys_objects_storage` (`object`, `engine`, `params`, `token_life`, `cache_control`, `levels`, `table_files`, `ext_mode`, `ext_allow`, `ext_deny`, `quota_size`, `current_size`, `quota_number`, `current_number`, `max_file_size`, `ts`) VALUES
 ('bx_videos_photos', @sStorageEngine, '', 360, 2592000, 3, 'bx_videos_photos', 'allow-deny', 'jpg,jpeg,jpe,gif,png', '', 0, 0, 0, 0, 0, 0),
-('bx_videos_videos', @sStorageEngine, '', 360, 2592000, 3, 'bx_videos_videos', 'allow-deny', 'avi,flv,mpg,mpeg,wmv,mp4,m4v,mov,qt,divx,xvid,3gp,3g2,webm,mkv,ogv,ogg,rm,rmvb,asf,drc', '', 0, 0, 0, 0, 0, 0),
+('bx_videos_videos', @sStorageEngine, 'a:1:{s:6:"fields";a:1:{s:10:"dimensions";s:17:"getFileDimensions";}}', 360, 2592000, 3, 'bx_videos_videos', 'allow-deny', 'avi,flv,mpg,mpeg,wmv,mp4,m4v,mov,qt,divx,xvid,3gp,3g2,webm,mkv,ogv,ogg,rm,rmvb,asf,drc', '', 0, 0, 0, 0, 0, 0),
 ('bx_videos_media_resized', @sStorageEngine, '', 360, 2592000, 3, 'bx_videos_media_resized', 'allow-deny', 'jpg,jpeg,jpe,gif,png,avi,flv,mpg,mpeg,wmv,mp4,m4v,mov,qt,divx,xvid,3gp,3g2,webm,mkv,ogv,ogg,rm,rmvb,asf,drc', '', 0, 0, 0, 0, 0, 0);
 
 INSERT INTO `sys_objects_transcoder` (`object`, `storage_object`, `source_type`, `source_params`, `private`, `atime_tracking`, `atime_pruning`, `ts`, `override_class_name`, `override_class_file`) VALUES