背景

浏览器支持的视频格式有限。而ffmpeg有很强的格式转换功能。那我们能不能通过ffmpeg把不支持的视频转成浏览器可以支持的视频呢?

方案

要实现以上方案要解决几个问题:

  1. 如何实时获取ffmpeg的转换后的数据
  2. 如何将数据实时传给浏览器
  3. 浏览器收到数据后如何播放

如何实时获取ffmpeg的转换后的数据

正常我们通过 ffmpeg 是可以将一个视频文件转换成另一种视频文件。
如下是将一个其他编码的mp4文件编码格式进行转换

ffmpeg -i 1.mp4  -c:v libx264 -f mp4 mp4-264.mp4

但我们怎么通过程序调用ffmpeg来获取转换后的数据呢。
ffmpeg 提供了一个pipe的功能可以将数据传给标准输入输出
nodejs 可以通过spawn来调用ffmpeg获取输出流

let ffmpeg = spawn('ffmpeg', //ffmpeg 自己从官网上载,改成自己路径,或配置成全局变量['-i', 'html/1.mp4','-c:v', 'libx264', // 如果原视频已经是264格式可以不转'-movflags', 'frag_keyframe+empty_moov+default_base_moof', // 转成fragment mp4'-f', 'mp4','pipe:1' // 输出流]);ffmpeg.stdout.on('data', chunk=>{console.log("data")})

如何将数据实时传给浏览器

现在转换后的视频数据拿到了,怎么将数据传给浏览器呢。
浏览器实时数据的传输一般想到的是用websocket.
我这边想到的是用两条websocket. 一条传输控制命令,一条传输视频数据。
websocket 支持二进制数据传输和文本数据传输。这里控制命令用文本类型。视频数据用的是二进制数据类型。

ffmpeg.stdout.on('data', chunk=>{console.log("data")//转码后的数据用二制制传输ws.send(chunk, {binary: true, mask: false});})

浏览器收到数据后如何播放

视频流的播放这里用到了MediaSourceExtension(MSE). https://developer.mozilla.org/en-US/docs/Web/API/MediaSource
需要注意的是,MSE只支持 fragmented mp4 用ffmpeg指定转framented mp4参数

 -movflags frag_keyframe+empty_moov+default_base_moof    // 转成fragment mp4
let video = document.querySelector('video');
let mediasource = new MediaSource();
video.src = URL.createObjectURL(mediasource);

可将websocket接收到数据传给Mediasource

 ws.onmessage = (event) => {sourceBuffer.appendBuffer(event.data);};

由于播放速度和转码的数据不一致,所以要根据播放进度来控制进度。这里用到刚提到的控制websocket, 通过监听播放进度和缓存的时间来判断是否要从后端拉取数据.

 function getData() {controlWs.send("get")}// updateend会在往MediaSource放数据后调用, 可以读取到缓存时间
sourceBuffer.addEventListener('updateend', () => {let buffered = sourceBuffer.bufferedfor (let i = 0; i < buffered.length; i++) {bufferTime = buffered.end(i); // 缓存了多少时间的数据}/***readyState* 0 = HAVE_NOTHING - 没有关于音频/视频是否就绪的信息1 = HAVE_METADATA - 关于音频/视频就绪的元数据2 = HAVE_CURRENT_DATA - 关于当前播放位置的数据是可用的,但没有足够的数据来播放下一帧/毫秒3 = HAVE_FUTURE_DATA - 当前及至少下一帧的数据是可用的4 = HAVE_ENOUGH_DATA - 可用数据足以开始播放* */if (video.readyState !== 4) {// 数据不够拉数据getData();}});video.addEventListener('timeupdate', (e)=>{console.log("timeupdate: " , bufferTime ,  video.currentTime,  video.readyState);// 缓存10秒if (bufferTime - video.currentTime < 10) {getData()}})

以上依赖ffmpeg强大的转码能力,可以将各种视频格式转成浏览器可识别的格式进行播放

完整代码

https://gitee.com/morris-mao/websocket-video

实现浏览器支持各种视频格式文件播放相关推荐

  1. video视频相关问题:火狐浏览器报错“没有找到支持的视频格式和MIME类型”

    1.需求:上传 .mp4 格式的视频到服务器,然后获取展示到前台页面. 2.遇到的问题:在谷歌浏览器上能正常显示视频,但是在火狐浏览器不能显示视频,提示:"没有找到支持的视频格式和MIME类 ...

  2. 如何在Windows 10上播放不受支持的视频格式

    Windows apps like Movies & TV and Windows Media Player allow the playback of certain types of vi ...

  3. 解决微信视频号 当前浏览器不支持此视频格式 的错误消息

    我试图用电脑端的微信视频号助手,上传一个后缀为 mp4 的视频时,遇到如下错误消息:当前浏览器不支持此视频格式,建议上传 MP4 或 H.264 格式文件. 然而我能肯定,我是使用格式工厂这款软件,将 ...

  4. 暴风影音能播放html视频吗,暴风影音播放器支持哪些视频格式

    暴风影音播放器是一款非常给力的视频播放器.该软件能够支持主流的视频格式,当然一些特殊的格式也基本支持,下面就和小编一起来看看到底都支持哪些格式吧! 暴风影音播放器支持哪些视频格式: 1.常规视频.DV ...

  5. 红米note3支持html,红米Note3支持什么视频格式?支持RMVB播放吗?

    红米Note3支持什么视频格式 红米Note3支持MP4.M4V.MKV.XVID.ASF视频格式. 红米Note3的指纹识别对手的湿度也有要求,需要保持手指干燥,潮湿的话就可能导致无法识别.红米No ...

  6. 让linux 支持视频格式,配置 Nginx 支持 f4v视频格式播放

    Nginx默认不支持f4v视频格式播放,解决方法为编辑mime.types文件,在video/mp4加上f4v即可 types { # Data interchange application/ato ...

  7. html 播放f4v,配置 nginx 支持 f4v视频格式播放

    Nginx默认不支持f4v视频格式播放,解决方法为编辑mime.types文件,在video/mp4加上f4v即可types { # Data interchange application/atom ...

  8. iphone保存html视频格式,iPhone6支持什么视频格式?iPhone6支持RMVB播放吗?

    iPhone6支持什么视频格式 iPhone6支持MP4,AVI,NAVI,DV-AVI,DIVX,MOV,ASF,WMV,RM,RMVB等视频格式. 关于iPhone6支持什么视频格式的疑问,下面将 ...

  9. Html 播放 mp4格式视频提示 没有发现支持的视频格式和mime类型

    转自原文 Html 播放 mp4格式视频提示 没有发现支持的视频格式和mime类型 播放mp4格式的时候提示 Html 播放 mp4格式视频提示 没有发现支持的视频格式和mime类型 原因是在IIS中 ...

最新文章

  1. Microsoft Surface Toolkit Beta 版发布
  2. 自然语言处理(NLP)之使用TF-IDF模型计算文本相似度
  3. merge r语言daframe_R语言读取多个excel文件后合并:rbind/merge/cmd合并
  4. 浅析网站设计风格对网站建设的重要性
  5. 五种网络管理技巧优化网络办公环境
  6. Python连接Mysql数据库SQL注入问题的解决
  7. marbin mysql_跨浏览器图像灰度(grayscale)解决方案
  8. 操作系统实验报告12:线程2
  9. ContactsContract.Contacts与ContactsContract.CommonDataKinds.Phone的区别
  10. 重新构想原子化 CSS
  11. 深入浅出分布式文件系统MogileFS集群
  12. 前端学习(2249)注册 创建 拉取
  13. grep 和 sed:linux经常使用工具 amp; 基本正則表達式
  14. python图像处理模块_Python图像处理库PIL的ImageEnhance模块使用介绍
  15. Caffe学习:使用pycaffe生成mean_file.py文件
  16. c语言打印%-6llu,C语言-输出指定个数的质数
  17. ydisk安卓版本_mydisktest
  18. J6412四网口迷你主机折腾虚拟机教程
  19. 房天下二手交易平台房源数据采集
  20. Redis——狂聊教程笔记

热门文章

  1. java 一年有多少周_java中如何计算一年总共有多少周
  2. nike blazer schweiz hinter dem Handtuch
  3. 缩略版muduo网络库(2):事件处理器 Chanel
  4. 菜鸟学习小程序之路(一)
  5. NLP之jieba分词原理简析
  6. 爱立信忙收5G专利费;中兴助力LPWAN物联网商用| IoT黑板报
  7. 机器学习#假设空间与版本空间
  8. 数学传奇丘成桐:《诗》明方向,《史记》教抉择
  9. 如何运用Common Neighbor方法进行链路预测
  10. idea超实用的设置——修改注释颜色、分割线