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

#3081 Record Video Uploader: Refactoring, bitrate settings, graceful "Browser not supported" case handling

Alexander 5 лет назад
Родитель
Сommit
5642c80c80

+ 79 - 60
inc/js/classes/BxDolUploader.js

@@ -487,52 +487,75 @@ BxDolUploaderCrop.prototype = BxDolUploaderSimple.prototype;
  * Record Video Uploader js class
  */
 function BxDolUploaderRecordVideo (sUploaderObject, sStorageObject, sUniqId, options) {
-
-    this._video_preview = null;
     this._camera = null;
     this._blob = null;
     this._recorder = null
 
-    this.init(sUploaderObject, sStorageObject, sUniqId, options);
+    this._audio_bitrate = undefined !== options.audio_bitrate ? parseInt(options.audio_bitrate) : 128000;
+    this._video_bitrate = undefined !== options.video_bitrate ? parseInt(options.video_bitrate) : 1000000;
 
-    this.releaseCamera = function() {
-        if (this._camera) {
-            if (this._recorder) {
-                this._recorder.destroy();
-                this._recorder = null;
-            }
+    this.init(sUploaderObject, sStorageObject, sUniqId, options);
 
-            if (typeof this._camera.stop != 'undefined') this._camera.stop();
-            this._camera.getTracks().forEach(function (track) {
-                if (track.readyState == 'live') {
-                    track.stop();
-                }
-            });
+    this.showUploaderForm = function() {
+        if (typeof MediaRecorder == 'undefined' || !('requestData' in MediaRecorder.prototype)) {
+            bx_alert(_t('_sys_uploader_unsupported_browser'));
+            return;
         }
+
+        BxDolUploaderSimple.prototype.showUploaderForm.call(this);
+    }
+
+    this.onBeforeShowPopup = function() {
+        this._blob = null;
+        this._camera = null;
+        this._recorder = null
+        this._clearErrors();
+
+        $('#bx-upoloader-recording-preview').hide();
+        $('#bx-upoloader-camera-capture').show();
+
+        $('#' + this._sFormContainerId + ' .bx-uploader-record-video-controls').hide();
+    }
+
+    this.onShowPopup = function () {
+        var $this = this;
+        navigator.mediaDevices.getUserMedia({ audio: true, video: true }).then(function(camera) {
+            $this._camera = camera;
+            $this.showCameraCapture();
+
+            $('#' + $this._sFormContainerId + ' .bx-uploader-recording-start').show();
+            $('#' + $this._sFormContainerId + ' .bx-uploader-recording-stop').hide();
+            $('#' + $this._sFormContainerId + ' .bx-uploader-record-video-controls').show();
+        }).catch(function(error) {
+            $this._showError(_t('_sys_uploader_camera_capture_failed'));
+        });
     }
 
     this.onClickCancel = function () {
-        this._video_preview.src = this._video_preview.srcObject = null;
-        this._video_preview.removeAttribute('src');
         this.releaseCamera();
 
         BxDolUploaderSimple.prototype.onClickCancel.call(this);
     }
 
     this.startRecording = function() {
+        this._recorder = RecordRTC(this._camera, {
+            type: 'video',
+            audioBitsPerSecond: this._audio_bitrate,
+            videoBitsPerSecond: this._video_bitrate,
+            disableLogs: true
+        });
+
+        if (!this._recorder) {
+            this._showError(_t('_sys_uploader_unsupported_browser'));
+            return;
+        }
+
         $('#' + this._sFormContainerId + ' .bx-uploader-recording-start').hide();
         $('#' + this._sFormContainerId + ' .bx-uploader-recording-stop').show();
 
-        this._video_preview.controls = false;
-
-        this._recorder = RecordRTC(this._camera, {
-            type: 'video'
-        });
         this._recorder.startRecording();
 
-        this._video_preview.muted = true;
-        this._video_preview.volume = 0;
-        this._video_preview.srcObject = this._camera;
+        this.showCameraCapture();
     }
 
     this.stopRecording = function(bSubmitWhenReady) {
@@ -552,44 +575,21 @@ function BxDolUploaderRecordVideo (sUploaderObject, sStorageObject, sUniqId, opt
         });
     }
 
-
-    this.onShowPopup = function () {
-        this._blob = null;
-        this._camera = null;
-        this._recorder = null
-        this._video_preview = $('#' + this._sFormContainerId + ' .bx-record-video-preview video').get(0);
-
-
-        var $this = this;
-        navigator.mediaDevices.getUserMedia({ audio: true, video: true }).then(function(camera) {
-            $this._camera = camera;
-            $this.showCameraCapture();
-
-            $('#' + $this._sFormContainerId + ' .bx-uploader-recording-start').show();
-            $('#' + $this._sFormContainerId + ' .bx-uploader-recording-stop').hide();
-            $('#' + $this._sFormContainerId + ' .bx-uploader-record-video-controls').show();
-        }).catch(function(error) {
-            $this._showError(_t('_sys_uploader_camera_capture_failed'));
-            $('#' + $this._sFormContainerId + ' .bx-uploader-record-video-controls').hide();
-        });
-    }
-
     this.showCameraCapture = function() {
-        this._video_preview.muted = true;
-        this._video_preview.volume = 0;
-        this._video_preview.srcObject = this._camera;
-        this._video_preview.removeAttribute('src');
-        this._video_preview.controls = false;
-
+        var video = $('#bx-upoloader-recording-preview').hide().get(0);
+        if (video.pause !== 'undefined') video.pause();
+        video.removeAttribute('src');
+
+        video = $('#bx-upoloader-camera-capture').show().get(0);
+        video.srcObject = this._camera;
+        video.muted = true;
+        video.volume = 0;
         $('#' + this._sFormContainerId + ' .bx-record-video-preview .bx-record-video-preview-filesize').html('');
     }
 
     this.showRecordingPreview = function() {
-        this._video_preview.muted = false;
-        this._video_preview.volume = 1;
-        this._video_preview.src = URL.createObjectURL(this._blob);
-        this._video_preview.srcObject = null;
-        this._video_preview.controls = true;
+        $('#bx-upoloader-camera-capture').hide();
+        $('#bx-upoloader-recording-preview').show().get(0).src = URL.createObjectURL(this._blob);
 
         var mbytes = (this._blob.size/1024/1024).toFixed(2);
         $('#' + this._sFormContainerId + ' .bx-record-video-preview .bx-record-video-preview-filesize').html(mbytes + ' ' + _t('_sys_uploader_record_video_mb'));
@@ -616,13 +616,32 @@ function BxDolUploaderRecordVideo (sUploaderObject, sStorageObject, sUniqId, opt
             success:function(sErrorMsg, textStatus, jqXHR) {
                 $this.onUploadCompleted(sErrorMsg);
                 if (!sErrorMsg.length) {
-                    $this._video_preview.src = $this._video_preview.srcObject = null;
-                    $this._video_preview.removeAttribute('src');
                     $this.releaseCamera();
                 }
             },
         });
     }
+
+    this.releaseCamera = function() {
+        //stop playing recorded file
+        var video = $('#bx-upoloader-recording-preview').get(0);
+        if (video.pause != 'undefined') video.pause();
+        video.removeAttribute('src');
+
+        if (this._recorder) {
+            this._recorder.destroy();
+            this._recorder = null;
+        }
+
+        if (this._camera) {
+            if (typeof this._camera.stop != 'undefined') this._camera.stop();
+            this._camera.getTracks().forEach(function (track) {
+                if (track.readyState == 'live') {
+                    track.stop();
+                }
+            });
+        }
+    }
 }
 
 BxDolUploaderRecordVideo.prototype = BxDolUploaderSimple.prototype;

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

@@ -3335,6 +3335,7 @@ If it is not enabled then please consider implement this optimization, since it
 	<string name="_sys_uploader_record_video_mb"><![CDATA[Mb]]></string>
 	<string name="_sys_uploader_upload_canceled"><![CDATA[Too bad. Upload canceled.]]></string>
 	<string name="_sys_uploader_camera_capture_failed"><![CDATA[We were unable to initialize your camera.]]></string>
+	<string name="_sys_uploader_unsupported_browser"><![CDATA[Your browser doesn't support video recording. You can try <strong>Google Chrome</strong> or <strong>Mozilla FireFox</strong> instead.]]></string>
 	<string name="_sys_edit_profile"><![CDATA[Edit profile]]></string>    
 	<string name="_sys_exit"><![CDATA[Exit]]></string>    
 	<string name="_sys_warn"><![CDATA[warning]]></string>

+ 2 - 1
modules/boonex/russian/data/langs/system/ru.xml

@@ -3275,13 +3275,14 @@
 	<string name="_sys_uploader_simple_submit_button"><![CDATA[Загрузить]]></string>
 	<string name="_sys_uploader_simple_title"><![CDATA[Обычная загрузка]]></string>
 	<string name="_sys_uploader_record_video_button_name"><![CDATA[Записать Видео]]></string>
-	<string name="_sys_uploader_record_video_submit_button"><![CDATA[Запись]]></string>
+	<string name="_sys_uploader_record_video_submit_button"><![CDATA[Загрузить]]></string>
 	<string name="_sys_uploader_record_video_title"><![CDATA[Записать Видео]]></string>
 	<string name="_sys_uploader_upload_canceled"><![CDATA[Очень жаль. Загрузка прервана.]]></string>
 	<string name="_sys_uploader_camera_capture_failed"><![CDATA[Нам не удалось инициализировать вашу камеру.]]></string>
 	<string name="_sys_uploader_record_video_start_button"><![CDATA[Начать запись]]></string>
 	<string name="_sys_uploader_record_video_stop_button"><![CDATA[Прекратить запись]]></string>
 	<string name="_sys_uploader_record_video_mb"><![CDATA[Мб]]></string>
+	<string name="_sys_uploader_unsupported_browser"><![CDATA[Ваш браузер не поддерживает запись видео. Попробуйте <strong>Google Chrome</strong> или <strong>Mozilla FireFox</strong>.]]></string>
 	<string name="_sys_edit_profile"><![CDATA[Редактировать профиль]]></string>
 	<string name="_sys_exit"><![CDATA[Закончить]]></string>    
 	<string name="_sys_warn"><![CDATA[предупреждение]]></string>

+ 4 - 0
template/css/uploaders.css

@@ -80,6 +80,10 @@
     display: none;
 }
 
+#bx-upoloader-recording-preview {
+    display: none;
+}
+
 .bx-record-video-preview-filesize {
     text-align: center;
     margin: 0.2rem 0;

+ 11 - 3
template/scripts/BxBaseUploaderRecordVideo.php

@@ -11,6 +11,9 @@
  * Upload files using WebRTC webcam capture.
  * @see BxDolUploader
  */
+define('BX_UPLOADER_AUDIO_BITRATE', 128000); //128Kbit for audio
+define('BX_UPLOADER_VIDEO_BITRATE', 1000000); //1Mbit for video
+
 class BxBaseUploaderRecordVideo extends BxBaseUploaderSimple
 {
     protected $_sUploaderFormTemplate = 'uploader_form_record_video.html';
@@ -21,9 +24,13 @@ class BxBaseUploaderRecordVideo extends BxBaseUploaderSimple
         $this->_sButtonTemplate = 'uploader_button_record_video.html';
     }
 
-    /**
-     * Get uploader button title
-     */
+    public function getUploaderButton($mixedGhostTemplate, $isMultiple = true, $aParams = array(), $bDynamic = false) {
+        if (!$aParams) $aParams = [];
+        $aParams['audio_bitrate'] = BX_UPLOADER_AUDIO_BITRATE;
+        $aParams['video_bitrate'] = BX_UPLOADER_VIDEO_BITRATE;
+        return parent::getUploaderButton($mixedGhostTemplate, $isMultiple, $aParams, $bDynamic);
+    }
+
     public function getUploaderButtonTitle($mixed = false)
     {
         return _t('_sys_uploader_record_video_button_name');
@@ -34,6 +41,7 @@ class BxBaseUploaderRecordVideo extends BxBaseUploaderSimple
         $sAddon .= $this->_oTemplate->addJsTranslation([
             '_sys_uploader_camera_capture_failed',
             '_sys_uploader_record_video_mb',
+            '_sys_uploader_unsupported_browser',
         ], $bDynamic);
         return parent::addCssJs($bDynamic).($bDynamic ? $sAddon : '');
     }

+ 3 - 1
template/uploader_button_record_video_js.html

@@ -6,7 +6,9 @@
             'images_transcoder' : '__images_transcoder__',
             'storage_private' : '__storage_private__',
             'template_error_msg': '<div class="bx-uploader-msg-err">{error}</div>',
-            'template_ghost': __template_ghost__
+            'template_ghost': __template_ghost__,
+            'audio_bitrate': __audio_bitrate__,
+            'video_bitrate': __video_bitrate__,
         });
     });                
 </script>

+ 2 - 1
template/uploader_form_record_video.html

@@ -12,7 +12,8 @@
             <div class="bx-def-padding-sec-bottom" id="__errors_container_id__"></div>
 
             <div class="bx-record-video-preview">
-                <video autoplay style="width: 100%;"></video>
+                <video autoplay style="width: 100%;" id="bx-upoloader-camera-capture"></video>
+                <video autoplay controls style="width: 100%;" id="bx-upoloader-recording-preview"></video>
                 <div class="bx-record-video-preview-filesize"></div>
             </div>