Преглед изворни кода

#2873 General support for audio/sounds/music attachments

Alex Trofimov пре 6 година
родитељ
комит
6403990f98

+ 88 - 32
modules/base/general/classes/BxBaseModGeneralTemplate.php

@@ -351,6 +351,7 @@ class BxBaseModGeneralTemplate extends BxDolModuleTemplate
         $oStorage = BxDolStorage::getObjectInstance($sStorage);
 
         list($oTranscoder, $oTranscoderPreview) = $this->getAttachmentsImagesTranscoders($sStorage);
+        $oTranscoderSound = isset($CNF['OBJECT_SOUNDS_TRANSCODER']) && $CNF['OBJECT_SOUNDS_TRANSCODER'] ? BxDolTranscoderImage::getObjectInstance($CNF['OBJECT_SOUNDS_TRANSCODER']) : null;
         $aTranscodersVideo = $this->getAttachmentsVideoTranscoders($sStorage);
 
         $aGhostFiles = $oStorage->getGhosts ($this->getModule()->serviceGetContentOwnerProfileId($aData[$CNF['FIELD_ID']]), $aData[$CNF['FIELD_ID']]);
@@ -373,6 +374,7 @@ class BxBaseModGeneralTemplate extends BxDolModuleTemplate
 
             $isImage = $oTranscoder && (0 === strncmp('image/', $a['mime_type'], 6)) && $oTranscoder->isMimeTypeSupported($a['mime_type']); // preview for images, transcoder object for preview must be defined
             $isVideo = $aTranscodersVideo && (0 === strncmp('video/', $a['mime_type'], 6)) && $aTranscodersVideo['poster']->isMimeTypeSupported($a['mime_type']); // preview for videos, transcoder object for video must be defined
+            $isSound = $oTranscoderSound && (0 === strncmp('audio/', $a['mime_type'], 6)) && $oTranscoderSound->isMimeTypeSupported($a['mime_type']); // preview for sounds, transcoder object for sounds must be defined
             $sUrlOriginal = $oStorage->getFileUrlById($a['id']);
             $sImgPopupId = 'bx-messages-atachment-popup-' . $a['id'];
 
@@ -409,9 +411,23 @@ class BxBaseModGeneralTemplate extends BxDolModuleTemplate
                 ),
             );
 
+            // sounds are displayed inline
+            $a['bx_if:sound'] = array (
+                'condition' => $isSound,
+                'content' => array (
+                    'sound' => $isSound && $oTranscoderSound && ($oPlayer = BxDolPlayer::getObjectInstance()) ? $this->parseHtmlByName('attachment_sound.html', array(
+                        'file_name' => $a['file_name'],
+                        'player' => $oTranscoderSound->isFileReady($a['id']) ? 
+                            $oPlayer->getCodeAudio (BX_PLAYER_STANDARD, array(
+                                'mp3' => $oTranscoderSound->getFileUrl($a['id']),
+                            )) : _t('_sys_txt_err_sound_not_transcoded_yet'),
+                    )) : '',
+                ),
+            );
+
             // non-images are displayed as text links to original file
             $a['bx_if:not_image'] = array (
-                'condition' => !$isImage && !$isVideo,
+                'condition' => !$isImage && !$isVideo && !$isSound,
                 'content' => array (
                     'url_original' => $sUrlOriginal,
                     'attr_file_name' => bx_html_attribute($a['file_name']),
@@ -426,11 +442,80 @@ class BxBaseModGeneralTemplate extends BxDolModuleTemplate
     }
 
     public function embedVideo($iFileId)
+    {
+        $CNF = $this->getModule()->_oConfig->CNF;
+        list($oPlayer, $oStorage, $aContentInfo, $a) = $this->_embedChecks('OBJECT_STORAGE_VIDEOS', $iFileId);
+
+        // check if file is really video
+        $aTranscodersVideo = $this->getAttachmentsVideoTranscoders($sStorage);        
+        if (!$aTranscodersVideo || (0 !== strncmp('video/', $a['mime_type'], 6)) || !$aTranscodersVideo['poster']->isMimeTypeSupported($a['mime_type'])) {
+            $this->displayErrorOccured('', BX_PAGE_EMBED);
+            exit;
+        }
+
+        // check HD video version
+        $sVideoUrlHd = '';
+        $sVideoUrl = $oStorage->getFileUrlById($a['id']);
+        $aVideoSize = $aTranscodersVideo['mp4_hd']->getVideoSize($sVideoUrl);
+        if (!empty($aVideoSize) && is_array($aVideoSize) && (int)$aVideoSize['h'] >= 720)
+            $sVideoUrlHd = $aTranscodersVideo['mp4_hd']->getFileUrl($a['id']);
+
+        // generate player code
+        $sCode = $oPlayer->getCodeVideo (BX_PLAYER_EMBED, array(
+            'poster' => $aTranscodersVideo['poster']->getFileUrl($a['id']),
+            'mp4' => array(
+                'sd' => $aTranscodersVideo['mp4']->getFileUrl($a['id']), 
+                'hd' => $sVideoUrlHd
+            ),
+        ));
+
+        // display page
+        $oTemplate = BxDolTemplate::getInstance();
+        $oTemplate->setPageNameIndex (BX_PAGE_EMBED);
+        $oTemplate->setPageHeader ($a['file_name']);
+        $oTemplate->setPageContent ('page_main_code', $sCode);
+        $oTemplate->getPageCode();
+        exit;
+    }
+
+    public function embedSound($iFileId)
+    {
+        $CNF = $this->getModule()->_oConfig->CNF;
+        list($oPlayer, $oStorage, $aContentInfo, $a) = $this->_embedChecks('OBJECT_STORAGE_SOUNDS', $iFileId);
+
+        // check if file is really audio
+        $oTranscoderSound = isset($CNF['OBJECT_SOUNDS_TRANSCODER']) ? BxDolTranscoderImage::getObjectInstance($CNF['OBJECT_SOUNDS_TRANSCODER']) : null;
+        if (!$oTranscoderSound || (0 !== strncmp('audio/', $a['mime_type'], 6)) || !$oTranscoderSound->isMimeTypeSupported($a['mime_type'])) {
+            $this->displayErrorOccured('', BX_PAGE_EMBED);
+            exit;
+        }
+
+        if (!$oTranscoderSound->isFileReady($a['id'])) {
+            $oTranscoderSound->getFileUrl($a['id']); // queue for encoding
+            $this->displayMsg('_sys_txt_err_sound_not_transcoded_yet', true, BX_PAGE_EMBED);
+            exit;
+        }
+
+        // generate player code
+        $sCode = $oPlayer->getCodeAudio (BX_PLAYER_EMBED, array(
+            'mp3' => $oTranscoderSound->getFileUrl($a['id']),
+        ));
+
+        // display page
+        $oTemplate = BxDolTemplate::getInstance();
+        $oTemplate->setPageNameIndex (BX_PAGE_EMBED);
+        $oTemplate->setPageHeader ($a['file_name']);
+        $oTemplate->setPageContent ('page_main_code', $sCode);
+        $oTemplate->getPageCode();
+        exit;
+    }
+
+    protected function _embedChecks($sStorageKey, $iFileId)
     {
         // general checks
         $oPlayer = BxDolPlayer::getObjectInstance();
         $CNF = $this->getModule()->_oConfig->CNF;
-        $sStorage = isset($CNF['OBJECT_STORAGE_VIDEOS']) ? $CNF['OBJECT_STORAGE_VIDEOS'] : false;
+        $sStorage = isset($CNF[$sStorageKey]) ? $CNF[$sStorageKey] : false;
         if (!$oPlayer || !$sStorage || !($oStorage = BxDolStorage::getObjectInstance($sStorage))) {
             $this->displayErrorOccured('', BX_PAGE_EMBED);
             exit;
@@ -465,36 +550,7 @@ class BxBaseModGeneralTemplate extends BxDolModuleTemplate
             exit;
         }
 
-        // check if file is really video
-        $aTranscodersVideo = $this->getAttachmentsVideoTranscoders($sStorage);        
-        if (!$aTranscodersVideo || (0 !== strncmp('video/', $a['mime_type'], 6)) || !$aTranscodersVideo['poster']->isMimeTypeSupported($a['mime_type'])) {
-            $this->displayErrorOccured('', BX_PAGE_EMBED);
-            exit;
-        }
-
-        // check HD video version
-        $sVideoUrlHd = '';
-        $sVideoUrl = $oStorage->getFileUrlById($a['id']);
-        $aVideoSize = $aTranscodersVideo['mp4_hd']->getVideoSize($sVideoUrl);
-        if (!empty($aVideoSize) && is_array($aVideoSize) && (int)$aVideoSize['h'] >= 720)
-            $sVideoUrlHd = $aTranscodersVideo['mp4_hd']->getFileUrl($a['id']);
-
-        // generate player code
-        $sCode = $oPlayer->getCodeVideo (BX_PLAYER_EMBED, array(
-            'poster' => $aTranscodersVideo['poster']->getFileUrl($a['id']),
-            'mp4' => array(
-                'sd' => $aTranscodersVideo['mp4']->getFileUrl($a['id']), 
-                'hd' => $sVideoUrlHd
-            ),
-        ));
-
-        // display page
-        $oTemplate = BxDolTemplate::getInstance();
-        $oTemplate->setPageNameIndex (BX_PAGE_EMBED);
-        $oTemplate->setPageHeader ($a['file_name']);
-        $oTemplate->setPageContent ('page_main_code', $sCode);
-        $oTemplate->getPageCode();
-        exit;
+        return array($oPlayer, $oStorage, $aContentInfo, $a);
     }
 
     public function addCssJs()

+ 7 - 0
modules/base/general/js/forms.js

@@ -36,6 +36,8 @@ function bx_base_general_delete_ghost (iFileId, sFileUrl, sFileIcon, aEditors, o
 function bx_base_general_insert_to_post (iFileId, sFileUrl, sEditorId, sMimeType, sEmbedBaseUrl) {
     if ('undefined' !== typeof(sMimeType) && sMimeType.startsWith('video/') && 'undefined' !== typeof(sEmbedBaseUrl))
         bx_base_general_insert_video_embed (sEditorId, 'bx-base-general-img-' + iFileId, sEmbedBaseUrl + iFileId, 'bx-base-general-img');
+    else if ('undefined' !== typeof(sMimeType) && sMimeType.startsWith('audio/') && 'undefined' !== typeof(sEmbedBaseUrl))
+        bx_base_general_insert_audio_embed (sEditorId, 'bx-base-general-img-' + iFileId, sEmbedBaseUrl + iFileId, 'bx-base-general-img');
     else
         bx_editor_insert_img (sEditorId, 'bx-base-general-img-' + iFileId, sFileUrl, 'bx-base-general-img');
 }
@@ -45,4 +47,9 @@ function bx_base_general_insert_video_embed (sEditorId, sHtmlId, sEmbedUrl, sCla
     bx_editor_insert_html (sEditorId, sHtmlId, '<iframe width="560" height="315" src="' + sEmbedUrl + '" frameborder="0" allow="autoplay; picture-in-picture" allowfullscreen></iframe>');
 }
 
+function bx_base_general_insert_audio_embed (sEditorId, sHtmlId, sEmbedUrl, sClass)
+{    
+    bx_editor_insert_html (sEditorId, sHtmlId, '<iframe width="320" height="52" src="' + sEmbedUrl + '" frameborder="0" allow="autoplay; picture-in-picture" allowfullscreen></iframe>');
+}
+
 /** @} */

+ 4 - 0
modules/base/general/template/attachment_sound.html

@@ -0,0 +1,4 @@
+<div class="bx-base-general-attachment-sound">
+    <div class="bx-base-general-attachment-sound-file-name bx-def-padding-sec bx-def-box-sizing">__file_name__</div>
+    <div class="bx-base-general-attachment-sound-player">__player__</div>
+</div>

+ 4 - 1
modules/base/general/template/attachments.html

@@ -10,6 +10,9 @@
             <bx_if:video>
                 __video__
             </bx_if:video>
+            <bx_if:sound>
+                __sound__
+            </bx_if:sound>
             <bx_if:not_image>
                 <a href="__url_original__" title="__attr_file_name__">
                     <div class="bx-def-round-corners bx-def-padding-sec">__file_name__</div>
@@ -29,4 +32,4 @@
             });
         }
     </script>
-</div>
+</div>

+ 18 - 0
modules/base/general/template/css/main.css

@@ -122,6 +122,24 @@ div.bx-base-general-breadcrumb i {
     overflow: hidden;
 }
 
+.bx-base-general-attachment-sound {
+    position:relative;
+    height:100%;
+}
+.bx-base-general-attachment-sound-file-name,
+.bx-base-general-attachment-sound-player {
+  display: flex;
+  justify-content: center;
+  align-content: center;
+  flex-direction: column;
+}
+.bx-base-general-attachment-sound-file-name {
+    height:9.25rem;
+}
+.bx-base-general-attachment-sound-player {
+    height:3.25rem;
+}
+
 /* comments item */
 div.bx-base-general-comments div.bx-base-general-comments-element-holder,
 div.bx-base-general-comments div.bx-base-general-comments-counter-holder {

+ 20 - 0
modules/base/text/classes/BxBaseModTextFormEntry.php

@@ -15,6 +15,7 @@
 class BxBaseModTextFormEntry extends BxBaseModGeneralFormEntry
 {
     protected $_sGhostTemplateVideo = 'form_ghost_template_video.html';
+    protected $_sGhostTemplateSound = 'form_ghost_template_sound.html';
     protected $_sGhostTemplateFile = 'form_ghost_template_file.html';
 
     public function __construct($aInfo, $oTemplate = false)
@@ -57,6 +58,13 @@ class BxBaseModTextFormEntry extends BxBaseModGeneralFormEntry
             $this->aInputs[$CNF['FIELD_VIDEO']]['ghost_template'] = $this->_oModule->_oTemplate->parseHtmlByName($this->_sGhostTemplateVideo, $this->_getVideoGhostTmplVars($aContentInfo));
         }
 
+        if (isset($CNF['FIELD_SOUND']) && isset($this->aInputs[$CNF['FIELD_SOUND']])) {
+            if ($bValues)
+                $this->aInputs[$CNF['FIELD_SOUND']]['content_id'] = $aValues['id'];
+
+            $this->aInputs[$CNF['FIELD_SOUND']]['ghost_template'] = $this->_oModule->_oTemplate->parseHtmlByName($this->_sGhostTemplateSound, $this->_getSoundGhostTmplVars($aContentInfo));
+        }
+
         if (isset($CNF['FIELD_FILE']) && isset($this->aInputs[$CNF['FIELD_FILE']])) {
             if ($bValues)
                 $this->aInputs[$CNF['FIELD_FILE']]['content_id'] = $aValues['id'];
@@ -132,6 +140,18 @@ class BxBaseModTextFormEntry extends BxBaseModGeneralFormEntry
     	);
     }
 
+    protected function _getSoundGhostTmplVars($aContentInfo = array())
+    {
+    	$CNF = &$this->_oModule->_oConfig->CNF;
+
+    	return array (
+            'name' => $this->aInputs[$CNF['FIELD_SOUND']]['name'],
+            'content_id' => (int)$this->aInputs[$CNF['FIELD_SOUND']]['content_id'],
+            'editor_id' => isset($CNF['FIELD_TEXT_ID']) ? $CNF['FIELD_TEXT_ID'] : '',
+            'embed_url' => BX_DOL_URL_ROOT . $this->_oModule->_oConfig->getBaseUri() . 'file_embed_sound/',
+    	);
+    }
+
     protected function _getFileGhostTmplVars($aContentInfo = array())
     {
     	$CNF = &$this->_oModule->_oConfig->CNF;

+ 6 - 0
modules/base/text/classes/BxBaseModTextFormsEntryHelper.php

@@ -66,6 +66,9 @@ class BxBaseModTextFormsEntryHelper extends BxBaseModGeneralFormsEntryHelper
         if (isset($CNF['FIELD_VIDEO']))
             $oForm->processFiles($CNF['FIELD_VIDEO'], $iContentId, false);
 
+        if (isset($CNF['FIELD_SOUND']))
+            $oForm->processFiles($CNF['FIELD_SOUND'], $iContentId, false);
+
         if (isset($CNF['FIELD_FILE']))
             $oForm->processFiles($CNF['FIELD_FILE'], $iContentId, false);
 
@@ -93,6 +96,9 @@ class BxBaseModTextFormsEntryHelper extends BxBaseModGeneralFormsEntryHelper
             if (isset($CNF['FIELD_VIDEO']))
                 $oForm->processFiles($CNF['FIELD_VIDEO'], $iContentId, true);
 
+            if (isset($CNF['FIELD_SOUND']))
+                $oForm->processFiles($CNF['FIELD_SOUND'], $iContentId, true);
+
             if (isset($CNF['FIELD_FILE']))
                 $oForm->processFiles($CNF['FIELD_FILE'], $iContentId, true);
 

+ 5 - 0
modules/base/text/classes/BxBaseModTextModule.php

@@ -96,6 +96,11 @@ class BxBaseModTextModule extends BxBaseModGeneralModule implements iBxDolConten
         $this->_oTemplate->embedVideo($iFileId);
     }
 
+    public function actionFileEmbedSound($iFileId)
+    {
+        $this->_oTemplate->embedSound($iFileId);
+    }
+
     // ====== SERVICE METHODS
 
     public function serviceGetSafeServices()

+ 1 - 0
modules/boonex/english/data/langs/system/en.xml

@@ -3017,6 +3017,7 @@ If it is not enabled then please consider implement this optimization, since it
 	<string name="_sys_txt_error_entry_is_not_defined"><![CDATA[Requested resource doesn't exist]]></string>
 	<string name="_sys_txt_error_entry_update"><![CDATA[Entry update failed]]></string>
     <string name="_sys_txt_error_occured"><![CDATA[Error Occurred]]></string>
+    <string name="_sys_txt_err_sound_not_transcoded_yet"><![CDATA[Sound file isn't transcoded yet]]></string>
     <string name="_sys_txt_field_created"><![CDATA[Created:]]></string>
     <string name="_sys_txt_field_updated"><![CDATA[Updated:]]></string>
 	<string name="_sys_txt_forgot_pasword"><![CDATA[Forgot password?]]></string>

+ 24 - 6
modules/boonex/plyr/classes/BxPlyrPlayer.php

@@ -28,6 +28,17 @@ class BxPlyrPlayer extends BxDolPlayer
     </div>
     ';
 
+    /**
+     * Standard view initialization params for audio
+     */
+    protected static $CONF_STANDARD_AUDIO = '
+    <div {attrs_wrapper}>
+        <audio {attrs}>
+            {mp3}
+        </audio>
+    </div>
+    ';
+
     /**
      * Minimal view initialization params
      */
@@ -57,14 +68,20 @@ class BxPlyrPlayer extends BxDolPlayer
 
     public function getCodeAudio ($iViewMode, $aParams, $bDynamicMode = false)
     {
-        // TODO:
+        $aControls = explode(',', 'play-large,play,progress,current-time,mute,volume,pip,airplay');
+        $aSettings = array();
+        return $this->_getCodePlyr (self::$CONF_STANDARD_AUDIO, 'bx-player-plyr', $aControls, $aSettings, $iViewMode, $aParams, $bDynamicMode);
     }
     
     public function getCodeVideo ($iViewMode, $aParams, $bDynamicMode = false)
     {
-        $sInit = self::$CONF_STANDARD;
-        $sClass = 'bx-player-plyr';
-        
+        $aControls = explode(',', getParam('bx_plyr_option_controls'));
+        $aSettings = explode(',', getParam('bx_plyr_option_settings'));
+        return $this->_getCodePlyr (self::$CONF_STANDARD, 'bx-player-plyr', $aControls, $aSettings, $iViewMode, $aParams, $bDynamicMode);
+    }
+
+    protected function _getCodePlyr ($sInit, $sClass, $aControls, $aSettings, $iViewMode, $aParams, $bDynamicMode = false)
+    {        
         // set visual mode
         switch ($iViewMode) {
         case BX_PLAYER_MINI:
@@ -105,9 +122,11 @@ class BxPlyrPlayer extends BxDolPlayer
         $aTypes = array(
             'webm' => '<source type="video/webm" src="{url}" size="{size}" />',
             'mp4' => '<source type="video/mp4" src="{url}" size="{size}" />',
+            'mp3' => '<source type="audio/mpeg" src="{url}" />',
         );              
         $mp4 = '';
         $webm = '';
+        $mp3 = '';
         foreach ($aTypes as $s => $ss) {
             if (!isset($aParams[$s]))
                 continue;
@@ -135,6 +154,7 @@ class BxPlyrPlayer extends BxDolPlayer
             'attrs_wrapper' => $sAttrsWrapper,
             'webm' => $webm,
             'mp4' => $mp4,
+            'mp3' => $mp3,
             'captions' => isset($aParams['captions']) ? $aParams['captions'] : '',
         ));
 
@@ -142,8 +162,6 @@ class BxPlyrPlayer extends BxDolPlayer
 
         if (!($sFormat = getParam('sys_player_default_format')))
             $sFormat = 'sd';
-        $aControls = explode(',', getParam('bx_plyr_option_controls'));
-        $aSettings = explode(',', getParam('bx_plyr_option_settings'));
         $aOptions = array_merge(array(
             // 'debug' => true,
             'quality' => array('default' => $this->_aSizes[$sFormat]),

+ 1 - 0
template/css/general.css

@@ -488,6 +488,7 @@ div.bx-account-unit-online {
 
 /* --------------- Author Info */
 
+audio.bx-player-embed,
 video.bx-player-embed {
     width:100vw;
     height:100vh;

+ 16 - 3
template/scripts/BxBasePlayerHTML5.php

@@ -23,6 +23,15 @@ class BxBasePlayerHTML5 extends BxDolPlayer
         </video>
     ";
 
+    /**
+     * Standard view initialization params for audio
+     */
+    protected static $CONF_STANDARD_AUDIO = "
+        <audio {attrs}>
+            {mp3}
+        </audio>
+    ";
+
     /**
      * Minimal view initialization params
      */
@@ -53,14 +62,16 @@ class BxBasePlayerHTML5 extends BxDolPlayer
 
     public function getCodeAudio ($iViewMode, $aParams, $bDynamicMode = false)
     {
-        // TODO:
+        return $this->_getCode(self::$CONF_STANDARD_AUDIO, 'bx-player', $iViewMode, $aParams, $bDynamicMode);
     }
 
     public function getCodeVideo ($iViewMode, $aParams, $bDynamicMode = false)
     {
-        $sInit = self::$CONF_STANDARD;
-        $sClass = 'bx-player';
+        return $this->_getCode(self::$CONF_STANDARD, 'bx-player', $iViewMode, $aParams, $bDynamicMode);
+    }
 
+    protected function _getCode ($sInit, $sClass, $iViewMode, $aParams, $bDynamicMode = false)
+    {
         // set visual mode
         switch ($iViewMode) {
         case BX_PLAYER_MINI:
@@ -93,6 +104,7 @@ class BxBasePlayerHTML5 extends BxDolPlayer
         $aTypes = array(
             'webm' => '<source type="video/webm; codecs=\'vp8, vorbis\'" src="{url}" />',
             'mp4' => '<source type="video/mp4" src="{url}" />',
+            'mp3' => '<source type="audio/mpeg" src="{url}" />',
         );
         foreach ($aTypes as $s => $ss) {
             if (!isset($aParams[$s]))
@@ -112,6 +124,7 @@ class BxBasePlayerHTML5 extends BxDolPlayer
             'attrs' => $sAttrs,
             'webm' => isset($aParams['webm']) ? $aParams['webm'] : '',
             'mp4' => isset($aParams['mp4']) ? $aParams['mp4'] : '',
+            'mp3' => isset($aParams['mp3']) ? $aParams['mp3'] : '',
         ));
 
         return $sCode;