文章目录

  • 1.前言
  • 2.思路
    • 思路一
    • 思路二

1.前言

之前项目中用Canvas+H5合并流实现录屏功能,但是因为视频流是一直保存到内存中,当你的合成的视频流越来越来,那么导致内存消耗越大(后面浏览器会卡死崩溃),所以必须做些优化,需要将一个大的视频切割成若干个小的视频,然后每个上传到ftp服务器!

2.思路

思路一

MediaRecorder使用start()方法,这个方法可以设置时间,比如start(1000)相当于把每隔个1000毫秒把媒体流存放到一个数组中,比如你需要200M,你可以去计算每隔1000毫秒添加进去的blob大小去计算,当blob的总的大小为200M就把这个视频上传,我之前是按这种方式去做的,但是后面发现有问题,这个分割出来的视频只有第一个视频能播放,后面的视频不能播放(无效视频),当时没发现啥问题,这个问题困扰了我一天,后来才发现原来是元数据的问题,元数据好比描述文件结构,那么可以理解一个文件里面需要元数据和实际的数据,在datavailable事件中data中获得的内容只是生成的整个文件的一部分. 第一个通常包含元数据和一些其他数据,但下一部分不包含元数据,这个就是问题所在,所以为什么只能播放第一个视频,后面的播放不了,因为后面的数据不包含元数据,所以这种方法果断放弃了!

思路二

需要生成多个独立文件,为此,意味着你需要在规定的间隔时间内(5000毫秒)生成一个新的MediaRecorder对象,这样生成出来的所有的文件都是单独独立的文件,包含元数据和实际的数据,项目中我就是用这种方法,大概测试了下1分钟大约需要30M,那么设置10分钟也就差不多300M,这个数据也不大,所以一般的内存300M足够了,下面看下我的代码核心部分

    // 开始录制isRecord() {let record = this.$refs.record;if (this.stopRecord) {record.title = "停止录制";let stream = this.mergeStream(),//注意要判断浏览器对webm的支持情况,有些时候video格式不对,在ondataavailable监听的时候会拿不到data数据(data的size为空)mime = MediaRecorder.isTypeSupported("video/webm; codecs=vp9")? "video/webm; codecs=vp9": "video/webm";//第一次建新的MediaRecorder对象this.recorder = this.recordAndUpload(stream, mime, this.recordTime);//后面每隔一分钟创建新的MediaRecorder对象this.setIntervalTimer = setInterval(() => {this.recorder = this.recordAndUpload(stream, mime, this.recordTime);}, this.recordTime * 1000);this.stopRecord = false;this.$message({message: "开始录制",type: "success",customClass: "message-alert",});} else {record.title = "开始录制";this.endCapture();this.$message({message: "录制完成",type: "success",customClass: "message-alert",});//取消动画window.cancelAnimationFrame(this.animationFrame);this.stopRecord = true;this.recorder = null;}},//每隔recordTime时间(60秒)录制一个视频recordAndUpload(stream, mime, recordTime) {let chunks = [],that = this,videoStartTime,//创建新的MediaRecorder对象recorder = new MediaRecorder(stream, {mimeType: mime,});//当触发start或者stop都会执行这个方法recorder.ondataavailable = function (e) {chunks.push(e.data);};recorder.onstop = () => {//因为设置了时间,所以文件的时间是确定的if (that.setTimeoutTimer) {that.uploadFile(chunks, recordTime * 1000);} else {//当手动点了停止,那么这个时间就不是确定的了,需要计算that.uploadFile(chunks, Date.now() - videoStartTime);}};//每隔recordTime时间(60秒)自动去触发停止stop录像事件this.setTimeoutTimer = setTimeout(() => {recorder.stop();}, recordTime * 1000);recorder.start();videoStartTime = Date.now();return recorder},//上传文件到服务,保存录像到数据库uploadFile(chunks, recordTime) {let blob = new Blob(chunks, {type: "video/mp4",}),that = this;//recordTime为文件的时间,fixWebmDuration方法为文件设置时间(可以快进,快退),第三个参数是一个回调函数fixWebmDuration(blob, recordTime, (fixedBlob) => {//下载MP4到本地let fileName = `file_${new Date().getTime()}.mp4`,file = new window.File([fixedBlob], fileName),formData = new FormData();let url = URL.createObjectURL(new Blob([fixedBlob], { type: "video/mp4" })),aLink = document.createElement("a");aLink.download = fileName;aLink.href = url;document.body.appendChild(aLink);aLink.click();aLink.remove();window.URL.revokeObjectURL(url);//上传到ftp服务器formData.append("file", file);that.axios.post(//接口`/ftp/ftpUpload`,formData,{headers: { "Content-Type": "multipart/form-data" },}).then((data) => {//保存录像到数据库let params = new URLSearchParams(); //装载post传值params.append("cameraID", that.cameraIdChanged);params.append("videoName", fileName);params.append("videoUrl", fileName);that.axios.post("/video/addVideo", params).then((data) => {console.log(data);}).catch((error) => {that.$message.error("服务器异常");console.log(error);});}).catch((error) => {that.$message.error("服务器异常");console.log(error);});});},//结束录制endCapture() {//清除定时器clearTimeout(this.setTimeoutTimer);clearInterval(this.setIntervalTimer);this.setTimeoutTimer = this.setIntervalTimer = null;this.recorder.stop();},

下面是效果图

利用MediaRecorder录制视频切片上传到ftp服务器相关推荐

  1. iOS 录制视频并上传

    调取系统录制视频并上传,获取第一帧显示在界面 1.调取系统摄像 self.imagePicker=[[UIImagePickerController alloc]init]; self.imagePi ...

  2. android 与后台实时视频,android选择视频文件上传到后台服务器

    本文实例为大家分享了android选择视频文件上传到后台服务器的具体代码,供大家参考,具体内容如下 选择本地视频文件 首先第一步打开打开相册选择视频文件: Intent intent = new In ...

  3. vb发送到文件服务器,VB实现文件上传到FTP服务器

    VB实现文件上传到FTP服务器 ftp.txt文件内容为: open 211.118.1.70 dongping sh12345 put ip.jpg bye VB内容为: Private Sub C ...

  4. java用itextPDF生成PDF文件保存至本地并上传至ftp服务器

    标题java用itextPDF生成PDF文件保存至本地并上传至ftp服务器 所需jar :itext-asian-5.2.0.jar,itextpdf-5.5.5.jar,commons-net-3. ...

  5. es+ftp服务器传文件怎么那么慢,es本地上传文件ftp服务器

    es本地上传文件ftp服务器 内容精选 换一换 上传的文件和上传的文件夹中包含的文件支持的格式请参见支持的文件格式.文件上传:从本地上传:在Projects Explorer视图中选中一个文件夹,依次 ...

  6. 将文件上传至ftp服务器,FTP文件上传工具类,将文件上传至服务器指定目录

    将文件上传至ftp服务器,传入File对象,将文件上传至ftp服务器 需要配置修改的点: 1. 服务器ip端口(服务器ip 端口22/21). 2. 服务器账号密码(服务器登录用户名密码). 3. 上 ...

  7. java ftp上传文件 linux_Java实现把文件上传至ftp服务器

    用Java实现ftp文件上传.我使用的是commons-net-1.4.1.zip.其中包含了众多的java网络编程的工具包. 1 把commons-net-1.4.1.jar包加载到项目工程中去. ...

  8. python 实现统计ftp服务器指定目录下文件夹数目、文件数目及所有文件大小 本次主要为满足应用方核对上传到ftp服务器的文件是否缺漏。 主要要求:指定目录下,文件夹数目/文件数目/所有文件大小

    python 实现统计ftp服务器指定目录下文件夹数目.文件数目及所有文件大小 本次主要为满足应用方核对上传到ftp服务器的文件是否缺漏. 主要要求:指定目录下,文件夹数目/文件数目/所有文件大小,类 ...

  9. 解决,文件上传到 ftp 服务器,中文出现乱码问题

    前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家.点击跳转到教程. 上传到 ftp 服务器,中文出现乱码解决,之前文件名  " 网关信息 " 始终不 ...

最新文章

  1. Linux系统时间和时序,什么是时序竞态 Linux系统时序竞态问题分析
  2. hbuilderx代码自动补全_DL时代的代码补全利器,北大出品,效果远超语言模型
  3. BZOJ 1121 science
  4. 在S/4HANA扩展字段的Available Fields列表里,看不到自己创建的扩展字段该怎么办
  5. 【TensorFlow-windows】扩展层之STN
  6. objects jdk8_JDK 9:NotNullOrElse方法已添加到Objects类
  7. junit 测试 异常_使用JUnit规则测试预期的异常
  8. centos6.5装mysql好难_CentOS6.5 下MySQL傻瓜式安装
  9. 洛谷 P1377 [TJOI2011]树的序 解题报告
  10. idc服务器管理系统勇士水花,idc管理系统
  11. 江苏省对口单招计算机原理,江苏省对口单招计算机原理教案
  12. GIT提交记录和Revert commit过程分析
  13. 如何处理word中字体和公式不在同一水平线上
  14. gzip: File too large错误
  15. position属性absolute(绝对定位),relatve(相对定位)
  16. poi 导出excel 中合并单元格
  17. MESI protocol digram
  18. qt自定义qtablemodel实现改变item的背景色
  19. win安装soapui
  20. 机载激光雷达原理与应用科普(七)

热门文章

  1. angular 中如何实现多态与继承
  2. 系统平台新店铺运营思路
  3. 显示商品分类列表页面
  4. EasyExcel3.0.5 导出多个sheet,批量下载打包成ZIP压缩包
  5. python进阶学习--- django框架解析 ---领悟编程语言共性与特性【后续详解】
  6. mysqli_connect(): (HY000/2002):
  7. 零基础可以学板绘吗?怎么自学板绘?
  8. Python3.8.5安装教程
  9. python 实现的 成语接龙
  10. 关于宠物饮水机的问题与设计