rrweb原理
rrweb 是一个实现web页面录制和回放的基础库 ,它可以将⻚⾯中的 DOM 以及⽤户操作保存为可序列化的数据,以实现远程回放。
RecordRTC原理
1.rrweb
安装npm i rrweb
直接上代码
<template>
<el-card shadow="never" class="aui-card--fill">
<div class="rrweb-create">
<el-button @click="crateWeb">开始录制</el-button>
<el-button @click="saveWeb">保存录制</el-button>
<el-button @click="getInfo">回放录屏</el-button>
</div>
<div id="replaycontent" style="width: 1000px;height: 500px;background-color: #cccccc"></div>
</el-card>
</template>
<script>
import { record } from 'rrweb'
import 'rrweb-player/dist/style.css'
import rrwebPlayer from 'rrweb-player'
export default {
name: 'Rrweb',
components: {},
data () {
return {
events: []
}
},
props: {},
watch: {},
methods: {
// 开始录屏
crateWeb () {
const _this = this
_this.events = []
record({
emit (event) {
// 用任意方式存储 event
_this.events.push(event)
_this.$store.commit('getEvents', _this.events)
}
})
},
// 保存录屏
saveWeb () {
// console.log(this.events)
// this.$http.post('/record/create/setCreate', {
// events: this.events
// }).then(({ data: res }) => {
// this.crateWeb()
// }).catch(() => {
// this.crateWeb()
// })
},
// 回放录屏
getInfo () {
console.log(this.$store.state.events)
var events = this.$store.state.events
// this.$http.get('/record/create/getInfo', {
// params: {
// id: 18
// }
// }).then(({ data: res }) => {
// const events = JSON.parse(res.data.events)
// eslint-disable-next-line no-new,new-cap
new rrwebPlayer({
target: document.getElementById('replaycontent'),
data: {
events
}
})
// }).catch(() => {
// this.crateWeb()
// })
}
},
computed: {},
created () {},
mounted () {}
}
</script>
<style lang="scss" scoped>
</style>
效果:
2.RecordRTC
npm i rrweb
npm i rrweb-player
直接上代码
<template>
<div class="record-page">
<div style="margin-bottom: 15px;">
<el-button @click="startRecording" :disabled="videoStart" size="small">开始录制</el-button>
<el-button @click="stopRecording" :disabled="!videoStart" size="small" id="btn-stop-recording">结束录制</el-button>
</div>
<video controls autoplay playsinline ref="video" width="400" height="300"></video>
</div>
</template>
<script>
import RecordRTC from 'recordrtc'
export default {
name: 'screenRecord',
data () {
return {
video: null,
videoStart: false,
recorder: null
}
},
created () {
console.log(navigator.getDisplayMedia)
if (!navigator.getDisplayMedia && !navigator.mediaDevices.getDisplayMedia) {
const error = 'Your browser does NOT support the getDisplayMedia API.'
throw new Error(error)
}
},
mounted () {
this.video = document.querySelector('video')
},
methods: {
// 调用获取显示媒体
invokeGetDisplayMedia (success, error) {
const displaymediastreamconstraints = {
video: {
displaySurface: 'window', // monitor, window, application, browser
logicalSurface: false,
cursor: 'always' // never, always, motion
}
}
// above constraints are NOT supported YET
// that's why overridnig them
// displaymediastreamconstraints = {
// video: true
// }
if (navigator.mediaDevices.getDisplayMedia) {
console.log(navigator.mediaDevices.getDisplayMedia(displaymediastreamconstraints))
navigator.mediaDevices.getDisplayMedia(displaymediastreamconstraints).then(success).catch(error)
} else {
navigator.getDisplayMedia(displaymediastreamconstraints).then(success).catch(error)
}
},
// 捕获屏幕
captureScreen (callback) {
this.invokeGetDisplayMedia(
screen => {
console.log(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(track => {
track.addEventListener(
'ended',
() => {
this.stopRecording()
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'
})
this.recorder.startRecording()
// release screen on stopRecording
this.recorder.screen = screen
this.videoStart = true
})
},
stopRecordingCallback () {
this.video.src = this.video.srcObject = null
this.video.src = URL.createObjectURL(this.recorder.getBlob())
// 如果需要下载录屏文件可加上下面代码
const url = URL.createObjectURL(this.recorder.getBlob())
const a = document.createElement('a')
document.body.appendChild(a)
a.style.display = 'none'
a.href = url
a.download = new Date() + '.mp4'
a.click()
window.URL.revokeObjectURL(url)
// 以上是下载所需代码
this.recorder.screen.stop()
this.recorder.destroy()
this.recorder = null
this.videoStart = false
},
stopRecording () {
this.recorder.stopRecording(this.stopRecordingCallback)
}
}
}
</script>
<style scoped>
</style>
效果: