记录h5使用navigator.mediaDevices.getUserMedia录制音视频

!!!要在https环境下才行!!!

<video class="video" id="video" ref="recordRef" muted autoplay playsinline></video>

let stream

let mediaRecorder

let startTime

let recordSize = 0

let recordedChunks = []

mounted() {

this.init();

},

beforeDestroy() {

recordedChunks = []

if (stream) {

stream.getTracks().forEach(function (track) {

track.stop()

})

}

this.$refs.recordRef.srcObject = null

},

async init(){

this.$nextTick(async () => {

stream = await navigator.mediaDevices.getUserMedia({

video: {

// width:720,

// height:1280,

facingMode: 'user',

},

// video:true,

audio: true,

})

this.$refs.recordRef.srcObject = stream

mediaRecorder = new MediaRecorder(stream)

mediaRecorder.onstart = () => {

recordedChunks = []

recordSize = 0

startTime = new Date().getTime()

}

mediaRecorder.ondataavailable = (event) => {

recordSize += event.data.size

this.time = Math.round((new Date().getTime() - startTime) / 1000)

this.size = recordSize

if (event.data.size > 0) {

recordedChunks.push(event.data)

}

}

mediaRecorder.onstop = async () => {

if (stream) {

stream.getTracks().forEach(function (track) {

track.stop()

})

}

this.$refs.recordRef.srcObject = null

//上传到阿里云oss

getOss({}).then((ress)=>{

let resp = ress.data;

const formData = new FormData()

formData.append('key', resp.filename)

formData.append('OSSAccessKeyId', resp.accessid)

formData.append('policy', resp.policy)

formData.append('signature', resp.signature)

formData.append('file', new File(recordedChunks, 'file.webm', { type: mediaRecorder.mimeType }))

const video_url = resp.host + '/' + resp.mp4

this.percent = '0%'

const uploadRequestXHR = new XMLHttpRequest()

uploadRequestXHR.open('POST', resp.host, true)

uploadRequestXHR.onerror = (rejj) => {

Toast('上传失败')

}

uploadRequestXHR.upload.onprogress = (e) => {

let per = Math.floor((e.loaded / e.total) * 100)

// 控制进度条最大显示99%,最后请求结束后才变为100%

if (per > 99) {

per = 99

}

this.percent = per + '%'

}

uploadRequestXHR.onload = (rejj2) => {

if (uploadRequestXHR.status != 204) {

Toast('上传失败')

return

}

activationServiceRecording({family_member_id: this.family_member_id,family_service_id:this.family_service_id,recording:video_url}).then((res)=>{

if(res.code!==200){

return Toast(res.error);

}

this.percent = '100%'

Toast('录制已完成');

setTimeout(()=>{

this.$router.go(-1)

},800)

})

}

uploadRequestXHR.send(formData)

})

//上传到服务器

// const blob = new Blob(recordedChunks, {

// type: 'video/webm'

// });

// const formData = new FormData();

// formData.append('file[]', blob, 'recorded-video.webm');

// upFile(formData).then(ress => {

// console.log('数据:',ress)

// activationServiceRecording({family_member_id: this.family_member_id,family_service_id:this.family_service_id,recording:ress.data[0].path}).then((res)=>{

// console.log('数据:',res)

// if(res.code!==200){

// return Toast(res.error);

// }

// this.percent = '100%'

// Toast('录制已完成');

// setTimeout(()=>{

// this.$router.go(-1)

// },800)

// })

// })

// .catch((rej) => {

// console.log('上传错误:',rej)

// })

}

})

},

changeState(){

if (this.state == 'ready') {

this.state = 'recording'

// 开始录制

mediaRecorder.start(1000)

} else if (this.state == 'recording') {

this.state = 'uploading'

// 结束录制

mediaRecorder.stop()

}

},

附:

formatBytes(time){

return formatBytes(time)

},

formatSeconds(size){

return formatSeconds(size)

},

utils:

//录制的视频size

export function formatBytes(bytes, decimals = 2) {

if (bytes === 0) return '0 Bytes'

const k = 1024

const dm = decimals < 0 ? 0 : decimals

const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']

const i = Math.floor(Math.log(bytes) / Math.log(k))

return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + '' + sizes[i]

}

//录制时间

export function formatSeconds(seconds) {

const hours = Math.floor(seconds / 3600)

const minutes = Math.floor((seconds % 3600) / 60)

const secs = seconds % 60

const hoursStr = hours.toString().padStart(2, '0')

const minutesStr = minutes.toString().padStart(2, '0')

const secsStr = secs.toString().padStart(2, '0')

return `{hoursStr}:{minutesStr}:${secsStr}`

}

相关推荐
不能只会打代码3 分钟前
六十天前端强化训练之第三十一天之Webpack 基础配置 大师级讲解(接下来几天给大家讲讲工具链与工程化)
前端·webpack·node.js
_十六14 分钟前
TS 的 unknown 与 any:安全与灵活的平衡点
前端·typescript
yunteng52120 分钟前
音视频(二)ffmpeg编译及推流
ffmpeg·音视频·h264·媒体推流
三小河22 分钟前
tailwindcss @4和@3版本项目引入,及自定义配置
前端·javascript·vue.js
雪球工程师团队24 分钟前
用一句话完成回归测试——多模态大模型与Prompt工程在前端自动化中的融合探索
前端·架构·测试
关山月30 分钟前
React 中的静态渲染 SSG
前端
SuperherRo39 分钟前
Web开发-JS应用&微信小程序&源码架构&编译预览&逆向调试&嵌套资产&代码审计
前端·javascript·微信小程序·源码·逆向
关二哥拉二胡41 分钟前
Cursor Max:从“代码神器”到“账单刺客”——开发者成本控制指南
前端·javascript
就改了42 分钟前
Java进阶——Lombok的使用
java·服务器·前端
故事与他6451 小时前
电子文档安全管理系统V6.0接口backup存在任意文件下载漏洞
java·开发语言·前端·javascript·安全·网络安全