RecordRTC网页录制视频无法播放以及无时长问题

在网页中录制屏幕
RecordRTC
文章后面贴在vue中的使用代码

2022.8.26更新此文:现在RecordRTC已经支持录制mkv格式的视频了,亲测mkv视频有时长还能自由拖动,害....

进入RecordRTC演示,第一个下拉框选择Full Screen,点击Start Recorfing开始录制

image.png

谷歌可以选择录制整个屏幕、某个应用窗口或者单个浏览器标签页,火狐只支持录制整个屏幕。其他没试过

停止录制后,点击Save to Disk保存视频,发现视频无法打开。
win10自带电视和电影、迅雷影音以及火狐浏览器都无法打开(仅谷歌浏览器能打开)

解决办法是第二个下拉框选中vp8格式进行录制。

但是问题又来了,视频能播放,但是视频没有时长,无法拖动进度条!!!

解决办法:

使用EBML.js处理视频blob,链接EBML.js
进入EBML.js,右键另存到项目中。

新建ebml.util.js

import { Decoder, tools, Reader } from './EBML.js'

/**
 * @param {Blob} file - File or Blob object.
 * @param {function} callback - Callback function.
 * @example
 * getSeekableBlob(blob or file, callback);
 * @see {@link https://github.com/muaz-khan/RecordRTC|RecordRTC Source Code}
 */
export function getSeekableBlob(inputBlob, callback) {
  const reader = new Reader()
  const decoder = new Decoder()
  const tool = tools

  const fileReader = new FileReader()
  fileReader.onload = function(e) {
    const ebmlElms = decoder.decode(this.result)
    ebmlElms.forEach(function(element) {
      reader.read(element)
    })
    reader.stop()
    const refinedMetadataBuf = tool.makeMetadataSeekable(
      reader.metadatas,
      reader.duration,
      reader.cues
    )
    const body = this.result.slice(reader.metadataSize)
    const newBlob = new Blob([refinedMetadataBuf, body], {
      type: 'video/webm'
    })

    callback(newBlob)
  }
  fileReader.readAsArrayBuffer(inputBlob)
}

在vue中使用:

npm install recordrtc -S

template:



script:

import RecordRTC from 'recordrtc'
import { getSeekableBlob } from './ebml.util.js'

export default {
  name: 'screenRecord',
  data() {
    return {
      video: null,
      isReacoding: false,
      isPaused: false,
      recorder: null
    }
  },

  //检测浏览器是否支持屏幕录制的api
  created() {
    if (!navigator.getDisplayMedia && !navigator.mediaDevices.getDisplayMedia) {
      let error = 'Your browser does NOT support the getDisplayMedia API.'
      throw new Error(error)
    }
  },

  mounted() {
    this.video = document.querySelector('video')
  },

  methods: {
    invokeGetDisplayMedia(success, error) {
      let displaymediastreamconstraints = {
        video: true
      }
      if (navigator.mediaDevices.getDisplayMedia) {
        navigator.mediaDevices
          .getDisplayMedia(displaymediastreamconstraints)
          .then(success)
          .catch(error)
      } else {
        navigator
          .getDisplayMedia(displaymediastreamconstraints)
          .then(success)
          .catch(error)
      }
    },

    captureScreen(callback) {
      this.invokeGetDisplayMedia(
        screen => {
          this.addStreamStopListener(screen, () => {
            //
          })
          callback(screen)
        },
        function(error) {
          console.error(error)
          alert(
            'Unable to capture your screen. Please check console logs./n' +
              error
          )
        }
      )
    },

    addStreamStopListener(stream, callback) {
      stream.addEventListener(
        'ended',
        function() {
          callback()
          callback = function() {}
        },
        false
      )
      stream.addEventListener(
        'inactive',
        function() {
          callback()
          callback = function() {}
        },
        false
      )
      stream.getTracks().forEach(function(track) {
        track.addEventListener(
          'ended',
          function() {
            callback()
            callback = function() {}
          },
          false
        )
        track.addEventListener(
          'inactive',
          function() {
            callback()
            callback = function() {}
          },
          false
        )
      })
    },

    // 开始录制
    startRecording() {
      this.captureScreen(screen => {
        this.video.srcObject = screen
        this.recorder = RecordRTC(screen, {
          type: 'video',
          mimeType: 'video/webm/;codecs=vp8',
          disableLogs: false,
          getNativeBlob: false
        })
        this.recorder.startRecording()
        // release screen on stopRecording
        this.recorder.screen = screen
        this.isReacoding = true
      })
    },

    stopRecordingCallback() {
      this.video.src = this.video.srcObject = null
      this.video.src = URL.createObjectURL(this.recorder.getBlob())
      this.download()
      this.recorder.screen.stop()
      this.recorder.destroy()
      this.recorder = null
      this.isReacoding = false
    },
    
    // 结束录制
    stopRecording() {
      this.recorder.stopRecording(this.stopRecordingCallback)
    },

    pauseRecord() {
      this.recorder.pauseRecording()
      this.isPaused = true
    },

    keepRecord() {
      this.recorder.resumeRecording()
      this.isPaused = false
    },

    // 结束后自动保存本地
    download() {
      getSeekableBlob(this.recorder.getBlob(), function(seekableBlob) {
        const url = window.URL.createObjectURL(seekableBlob)
        const link = document.createElement('a')
        link.style.display = 'none'
        link.href = url
        const fileName = Date.now() + '.webm'
        link.setAttribute('download', fileName)
        document.body.appendChild(link)
        link.click()
        document.body.removeChild(link)
      })
    }
  }
}

参考:https://github.com/muaz-khan/RecordRTC/issues/147

注意:受浏览器安全限制,只有localhost或者https的网站才支持录制屏幕,上线需要部署https

版权声明:
作者:Alex
链接:https://www.techfm.club/p/47254.html
来源:TechFM
文章版权归作者所有,未经允许请勿转载。

THE END
分享
二维码
< <上一篇
下一篇>>