RecordRTC 打开设备录像并压缩文件

利用RecordRTC打开手机或者电脑摄像头,进行录像,完成后对视频文件进行压缩。

github地址:

https://github.com/muaz-khan/RecordRTC


git上的例子是比较复杂的,会对各种摄像参数进行选择和处理。这里提供一个简单并且能实现录像功能的例子。

页面:

<div style="width: 75%;" id="recording-player"></div>
<button id="btn-start-recording" ng-click="videoCapture()">开始</button>
<button id="save-to-disk">保存</button>

操作处理的js代码如下:

var video = document.createElement('video');
          video.controls = false;
          var mediaElement = getHTMLMediaElement(video, {
              buttons: ['full-screen'/!*, 'take-snapshot'*!/],
              showOnMouseEnter: false,
              width: 360,
          });
          document.getElementById('recording-player').appendChild(mediaElement);
          var div = document.createElement('section');
          mediaElement.media.parentNode.appendChild(div);
          div.appendChild(mediaElement.media);
          var recordingPlayer = mediaElement.media;
          var btnStartRecording = document.querySelector('#btn-start-recording');
          var saveRecording = document.querySelector('#save-to-disk');
          var mimeType = 'video/webm';
          var fileExtension = 'webm';
          var recorderType = null;
          var type = 'video';
          var videoBitsPerSecond = null;
          var button = btnStartRecording;

          function getURL(arg) {
              var url = arg;
              if(arg instanceof Blob || arg instanceof File) {
                  url = URL.createObjectURL(arg);
              }
              if(arg instanceof RecordRTC || arg.getBlob) {
                  url = URL.createObjectURL(arg.getBlob());
              }
              if(arg instanceof MediaStream || arg.getTracks || arg.getVideoTracks || arg.getAudioTracks) {
                  // url = URL.createObjectURL(arg);
              }
              return url;
          }

          function setVideoURL(arg, forceNonImage) {
              var url = getURL(arg);
              var parentNode = recordingPlayer.parentNode;
              parentNode.removeChild(recordingPlayer);
              parentNode.innerHTML = '';

              var elem = 'video';
              recordingPlayer = document.createElement(elem);

              if(arg instanceof MediaStream) {
                  recordingPlayer.muted = true;
              }
              recordingPlayer.addEventListener('loadedmetadata', function() {
                  if(navigator.userAgent.toLowerCase().indexOf('android') == -1) return;
                  // android
                  setTimeout(function() {
                      if(typeof recordingPlayer.play === 'function') {
                          recordingPlayer.play();
                      }
                  }, 2000);
              }, false);
              recordingPlayer.poster = '';
              if(arg instanceof MediaStream) {
                  recordingPlayer.srcObject = arg;
              }
              else {
                  recordingPlayer.src = url;
              }
              if(typeof recordingPlayer.play === 'function') {
                  recordingPlayer.play();
              }
              recordingPlayer.addEventListener('ended', function() {
                  url = getURL(arg);

                  if(arg instanceof MediaStream) {
                      recordingPlayer.srcObject = arg;
                  }
                  else {
                      recordingPlayer.src = url;
                  }
              });
              parentNode.appendChild(recordingPlayer);
          }

          button.mediaCapturedCallback = function() {

              var options = {
                  type: type,
                  mimeType: mimeType,
                  getNativeBlob: false, // enable it for longer recordings
                  video: recordingPlayer
              };
              options.ignoreMutedMedia = false;
              button.recordRTC = RecordRTC(button.stream, options);
              button.recordingEndedCallback = function(url) {
                  setVideoURL(url);
              };
              button.recordRTC.startRecording();




          }
          var commonConfig = {
              onMediaCaptured: function(stream) {
                  button.stream = stream;
                  if(button.mediaCapturedCallback) {
                      button.mediaCapturedCallback();
                  }

                  button.innerHTML = "停止";
                  button.disabled = false;
              },
              onMediaStopped: function() {
                  button.innerHTML = "开始";

                  if(!button.disableStateWaiting) {
                      button.disabled = false;
                  }
              },
              onMediaCapturingFailed: function(error) {
                  console.error('onMediaCapturingFailed:', error);

                  if(error.toString().indexOf('no audio or video tracks available') !== -1) {
                      alert('RecordRTC failed to start because there are no audio or video tracks available.');
                  }

                  if(DetectRTC.browser.name === 'Safari') return;

                  if(error.name === 'PermissionDeniedError' && DetectRTC.browser.name === 'Firefox') {
                      alert('Firefox requires version >= 52. Firefox also requires HTTPs.');
                  }

                  commonConfig.onMediaStopped();
              }
          };


          function captureUserMedia(mediaConstraints, successCallback, errorCallback) {
              if(mediaConstraints.video == true) {
                  mediaConstraints.video = {};
              }

              navigator.mediaDevices.getUserMedia(mediaConstraints).then(function(stream) {
                  successCallback(stream);
                  setVideoURL(stream, true);
              }).catch(function(error) {
                  if(error && error.name === 'ConstraintNotSatisfiedError') {
                      alert('Your camera or browser does NOT supports selected resolutions or frame-rates. \n\nPlease select "default" resolutions.');
                  }
                  errorCallback(error);
              });
          }

          function addStreamStopListener(stream, callback) {
              var streamEndedEvent = 'ended';
              if ('oninactive' in stream) {
                  streamEndedEvent = 'inactive';
              }
              stream.addEventListener(streamEndedEvent, function() {
                  callback();
                  callback = function() {};
              }, false);
              stream.getAudioTracks().forEach(function(track) {
                  track.addEventListener(streamEndedEvent, function() {
                      callback();
                      callback = function() {};
                  }, false);
              });
              stream.getVideoTracks().forEach(function(track) {
                  track.addEventListener(streamEndedEvent, function() {
                      callback();
                      callback = function() {};
                  }, false);
              });
          }

          function captureAudioPlusVideo(config) {
              captureUserMedia({video: true, audio: true}, function(audioVideoStream) {
                  config.onMediaCaptured(audioVideoStream);
                  if(audioVideoStream instanceof Array) {
                      audioVideoStream.forEach(function(stream) {
                          addStreamStopListener(stream, function() {
                              config.onMediaStopped();
                          });
                      });
                      return;
                  }
                  addStreamStopListener(audioVideoStream, function() {
                      config.onMediaStopped();
                  });
              }, function(error) {
                  config.onMediaCapturingFailed(error);
              });
          }

          function stopStream() {
              if(button.stream && button.stream.stop) {
                  button.stream.stop();
                  button.stream = null;
              }

              if(button.stream instanceof Array) {
                  button.stream.forEach(function(stream) {
                      stream.stop();
                  });
                  button.stream = null;
              }

              videoBitsPerSecond = null;
              var html = 'Recording status: stopped';
              html += '<br>Size: ' + bytesToSize(button.recordRTC.getBlob().size);
          }

          function getFileName(fileExtension) {
              var d = new Date();
              var year = d.getUTCFullYear();
              var month = d.getUTCMonth() + 1;
              var date = d.getUTCDate();
              return 'RecordRTC-' + year + month + date + '-' + fileExtension;
          }

          function saveToDiskOrOpenNewTab(recordRTC) {

              /!*if(!recordRTC.getBlob().size) {
               var info = getFailureReport();
               console.log('blob', recordRTC.getBlob());
               console.log('recordrtc instance', recordRTC);
               console.log('report', info);

               if(mediaContainerFormat.value !== 'default') {
               alert('RecordRTC seems failed recording using ' + mediaContainerFormat.value + '. Please choose "default" option from the drop down and record again.');
               }
               else {
               alert('RecordRTC seems failed. Unexpected issue. You can read the email in your console log. \n\nPlease report using disqus chat below.');
               }

               if(mediaContainerFormat.value !== 'vp9' && DetectRTC.browser.name === 'Chrome') {
               alert('Please record using VP9 encoder. (select from the dropdown)');
               }
               }*!/

              var fileName = getFileName(fileExtension);

              saveRecording.onclick = function(event) {
                  if(!recordRTC) return alert('No recording found.');

                  var file = new File([recordRTC.getBlob()], fileName, {
                      type: mimeType
                  });

                  invokeSaveAsDialog(file, file.name);

              }
          }


          //操作录像
          btnStartRecording.onclick = function(event) {
              if(button.innerHTML === "停止") {
                  button.disabled = true;
                  button.disableStateWaiting = true;
                  setTimeout(function() {
                      button.disabled = false;
                      button.disableStateWaiting = false;
                  }, 2000);

                  button.innerHTML = '开始';

                  if(button.recordRTC) {
                      if(button.recordRTC.length) {
                          button.recordRTC[0].stopRecording(function(url) {
                              if(!button.recordRTC[1]) {
                                  button.recordingEndedCallback(url);
                                  stopStream();

                                  saveToDiskOrOpenNewTab(button.recordRTC[0]);
                                  return;
                              }

                              button.recordRTC[1].stopRecording(function(url) {
                                  button.recordingEndedCallback(url);
                                  stopStream();
                              });
                          });
                      }
                      else {
                          button.recordRTC.stopRecording(function(url) {
                              button.recordingEndedCallback(url);
                              saveToDiskOrOpenNewTab(button.recordRTC);
                              stopStream();
                          });
                      }
                  }

                  return;
              }
              captureAudioPlusVideo(commonConfig);

          }

在你的index文件中需要引入两个相关文件:

<link href="https://cdn.webrtc-experiment.com/getHTMLMediaElement.css" rel="stylesheet">
<script src="https://cdn.webrtc-experiment.com/getHTMLMediaElement.js"></script>

还需要引入RecordRTC.js。这个从git上就可以找到。
以上是从git上扒下来的部分代码,可以简单实现录像,并将视频文件压缩的功能


  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
Vue2 本身并不提供视频压缩的功能,但是可以通过调用第三方库实现。以下是基于 `videojs-contrib-hls` 和 `videojs-record` 库实现视频压缩的示例代码: 1. 安装依赖: ```bash npm install videojs-contrib-hls videojs-record recordrtc --save ``` 2. 在 Vue 单文件组件中引入依赖: ```javascript import 'video.js/dist/video-js.css' import videojs from 'video.js' import 'videojs-record/dist/css/videojs.record.css' import RecordRTC from 'recordrtc' import Record from 'videojs-record/dist/videojs.record' import Hls from 'videojs-contrib-hls' export default { name: 'VideoCompression', data () { return { videoRef: null, player: null, recordOptions: { controls: true, width: 400, height: 300, fluid: false, plugins: { record: { audio: true, video: true, maxLength: 10, debug: true, videoMimeType: 'video/mp4', audioMimeType: 'audio/mp3' } } }, recordRTC: null } }, mounted () { this.initPlayer() }, methods: { initPlayer () { const options = { plugins: { record: this.recordOptions.plugins.record, hls: {} } } this.player = videojs(this.$refs.videoPlayer, options, () => { console.log('Video player is ready') }) this.player.on('startRecord', () => { console.log('Recording started') }) this.player.on('finishRecord', () => { console.log('Recording finished') this.compressVideo() }) }, startRecording () { this.player.record().getDevice() this.player.record().start() }, stopRecording () { this.player.record().stop() }, compressVideo () { this.recordRTC.getDataURL((dataURL) => { const blob = this.dataURItoBlob(dataURL) const formData = new FormData() formData.append('file', blob, 'video.mp4') // 发送压缩后的视频到服务器端 // ... }) }, dataURItoBlob (dataURI) { const byteString = atob(dataURI.split(',')[1]) const mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0] const ab = new ArrayBuffer(byteString.length) const ia = new Uint8Array(ab) for (let i = 0; i < byteString.length; i++) { ia[i] = byteString.charCodeAt(i) } return new Blob([ab], { type: mimeString }) } } } ``` 3. 在模板中添加视频播放器和控制按钮: ```html <template> <div> <video ref="videoPlayer" class="video-js vjs-default-skin"></video> <button @click="startRecording">Start Recording</button> <button @click="stopRecording">Stop Recording</button> </div> </template> ``` 上述代码中,`startRecording` 方法启动录制,`stopRecording` 方法停止录制,并调用 `compressVideo` 方法进行视频压缩。在 `compressVideo` 方法中,使用 `recordRTC.getDataURL` 方法获取录制的视频数据,将数据转化为 Blob 格式并发送到服务器端进行压缩处理。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值