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

webRCT—01—声音,视频播放 声音播放 在常见的HTML的网页中,我们可以选择添加 *audio* 标签来实现声音的播放 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <audio controls src="music.mp3"></audio> 阅读详情

背景

浏览器支持的视频格式有限。而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.buffered
          for (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

mediaRecorder-webSocket-mediaSource:浏览器到浏览器通过Web套接字进行的实时视频聊天测试 mediaRecorder-webSocket-mediaSource 描述 无需WebRTC的浏览器到浏览器视频聊天测试。 如何使用Web套接字服务器实时发送和接收数据。 整个过程将是这样的: 使用getUserMedia获取媒体流以访问本地计算机上的网络摄像头。 MediaRecorder编码媒体流并将其转换为Blob数据。(媒体段) 通过Web套接字将Blob数据发送到服务器。(Blob数据将转换为arrayBuffer) 服务器将数据返回给客户端。 通过使用appendBuffer ,将媒体段追加到MediaSource中的SourceBuffer中。 用法 通过npm install和npm start Web套接字服务器 $ cd backend $ npm install $ npm start 然后启动客户端 $ cd frontend $ npm inst 立即下载

相关推荐

MFC+ffmpeg+socket实时解码H.264码流

MFC+ffmpeg+socket实时解码H.264码流,具体的参考博客内容有说明

ffmpeg 转换x264到Fragmented MP4

ffmpeg -re -i d:\test.264 -g 52 -acodec libvo_aacenc -ab 64k -vcodec libx264 -vb 448k -f mp4 -movflags frag_keyframe+empty_moov d:\output.mp4 frag_keyframe 导致碎片输出,empty_moov将导致输出100%分段; 没有这个,第一个片段将被多

lilihli的专栏 5094

RocketMQ源码分析之消息轨迹

文章目录前言一、消息轨迹二、消息轨迹源码分析1、producer端2、consumer端三、消息轨迹中存储的信息1.TraceContext2.TraceBean3.TraceType四、总结 前言   本篇文章将会从以下方面介绍消息轨迹:什么是消息轨迹?如何启用消息轨迹?示例demo、消息轨迹的源码分析和消息轨迹中存储的信息。最后会用一张图来总结消息轨迹的工作原理。 一、消息轨迹 1.什么是消息轨迹? 消息轨迹是用来跟踪记录消息发送、消息消费的轨迹。 2.如何启用消息轨迹? broker端 需要在b

不爱学习的小妞博客 1076

在网页上实现任意格式的音视频快速播放功能的开发总结。

开发重点在pc端,手机端不考虑。 要实现用户上传音视频到服务器,上传完毕即可随意拖动进度条观看。 h5自带的video标签不支持大多数格式的音视频格式,不考虑。 考虑使用流媒体播放,把源视频转成视频流推到网页播放器。 使用nginx+nginx-rtmp-module+ffmpeg搭建了个流媒体服务器,使用rtmp和hls两种推流方式做实验,用vlc进行播放并成功,但是发现这是直播,没有进...

Last Dance ! 7351

改进爬山算法之六:随机重启爬山算法(Random-Restart Hill Climbing,RRHC)

随机重启爬山算法(Random-Restart Hill Climbing,RRHC)是爬山算法的一种改进策略,是一种启发式搜索算法,旨在通过随机重启来克服传统爬山算法容易陷入局部最优解的局限性,并增加找到全局最优解的概率。随机重启爬山算法通过在多次运行中不断尝试不同的初始解,并在每次运行中执行标准的爬山算法,最终选择所有运行中找到的最佳解作为最终结果。(1)计算复杂度:由于需要多次运行爬山算法,因此算法的计算复杂度可能较高,特别是在解空间较大或每次迭代需要较长时间的情况下。

搏博的专栏 2205

OpenClaw Windows 最详细安装指南

Windows上养龙虾:OpenClaw完整安装教程+钉钉接入,助你养只大龙虾

weixin_43405859的博客 2212

ffmpeg 实现多视频轨录制到同一个文件

在视频录制中,有时会碰到这样一个需求,将不同摄像头的画面写入到一个视频文件,这个叫法很多,有的厂家叫合流模式,有的叫多画面多流模式。无论如何,它们的实质都是在一个视频文件上实现多路不同分辨率视频的保存。经过调查,支持这种需求封装格式的有MP4、MOV、MKV 等,这里因为MP4 格式应用最广泛。

sinat_27720649的博客 1881

百度API实现人流量数量检测(动态)

百度的这个API还挺好用的,对与不追求高精度的人来说非常适用,结合他官方给的文档,极易上手。 需要做的就是通过API Key和Secret Key获取的access_token。 然后稍微修改下代码就行,但是他给的代码并没有直接从摄像头获取视频,而是读取一个文件夹,那么就需要自己先对摄像头的输出视频进行处理。 识别结果如下,"person_num"是当前画面的人数,in是累计进入的人数,out是累计走出去的人数。 他这个有个缺点就是返回值里边并没有实时返回in和out的值,而是都是0,但是这个图片上有,图片

qq_42479987的博客 3379

网页中播放RTSP(5) WebSocket播放视频

WebSocket播放视频是结合MediaSource的 总结:通过WebSocket获取视频流,提供给MediaSource,MediaSource结合video标签,播放视频。 这一套完全就是基于浏览器支持MediaSourceExtension(MSE)的,而我最终的目的是在unity3d里面播放视频,加入uinty3d不支持MediaSource和video标签,怎么折腾都没用。可能最...

llhswwha的专栏 7122

STM32掉电保存配置参数技巧

本文介绍了使用STM32内置备份寄存器(BKP)实现掉电保存配置参数的方法。相比外接EEPROM或Flash,备份寄存器无需外设但存储容量有限,需通过VBAT引脚连接纽扣电池供电。文章详细说明了初始化步骤,包括使能PWR时钟、允许访问备份寄存器等操作,并提供了RTC初始化的代码示例。同时介绍了HAL库中读写备份寄存器的函数使用方法,包括HAL_RTCEx_BKUPWrite和HAL_RTCEx_BKUPRead函数的具体参数和调用示例。该方法适用于需要小容量数据掉电保存的应用场景。

hanhanhan233的博客 946

Arduino安装图文教程:小白也能轻松上手

手把手带你完成Arduino安装全过程,无论你是编程新手还是硬件小白,都能快速搭建开发环境。结合arduino安装教程与实操步骤,避开常见错误,让创作即刻启程。

weixin_35509395的博客 1107

ffmpeg命令笔记

ffmpeg命令笔记 1. 生成fmp4: ffmpeg -i a.mp4 -vcodec copy -f mp4 -movflags frag_keyframe+empty_moov -codec copy b.mp4 2.

inpilen的专栏 881

MATLAB对pcap文件抓包的读取

应用范围 常用的雷达信号,无线网通信信号的格式大多为pcap、wj文件,这里记录一下MATLAB读取pcap文件的方法,具体处理过程及读取协议针对不同的雷达有不同的处理方式,在这里不做说明。 程序 clc;clear;close all; %% 文件位置 filename= 'E:\File\JOB\JOB_1\data.pcap'; fid = fopen(filename,'r'); % 打开包 tmpPack = fread(fid,1350); % 只读前1350个数 读到

诗酒趁年华的博客 3579

html5实现视频播放<video>

注意: 1.关于视频格式,不同浏览器支持的不一样,safari--mp4  chrome--webm firefox opera--ogv,ie8或更早的浏览器不支持 2.语句详解                                  Sorry, your browser doesn't support the video element 3.

andrewleeeeee的专栏 4281

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

让所有浏览器支持HTML5 video视频标签

原文地址:http://www.zhangxinxu.com/wordpress/?p=661 在HTML5的时代里,基本上只要一个标签加一个视频的src链接地址就可以播放视频了,对于开发人员来讲真是“酷毕了” 然而,当现实照进遐想,我们不得不去正视,现在,支持HTML5 video标签的浏览器寥寥无几。 要想让主流浏览器都支持video标签可使用下面的方法: 使用方法: 要想让

KongGuCanYin的专栏 871

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

本地视频播放器,支持大部分格式

这个播放器完全在浏览器中运行,支持所有现代浏览器(Chrome, Firefox, Edge, Safari等),只需将HTML文件保存到本地并双击打开即可使用。支持播放MP4、WebM、Ogg、MOV、AVI等多种视频格式。使用JavaScript File API处理本地文件。使用Blob URL技术直接播放本地文件。点击"打开视频"按钮选择本地视频文件。文件列表显示视频名称、大小和格式。从左侧文件列表中选择要播放的视频。使用底部的控制按钮控制播放。点击列表中的文件即可播放。清晰直观的播放控制界面。

辣香牛肉面的博客 665

MediaElement.js对不同浏览器的支持

目前已经有很多html5播放器可以使用,使用html5播放器可以轻松的在页面中插入媒体视频,从而使我们的web页面变得更加丰富多彩,所以今天向大家推荐一款非常优秀的html5播放器MediaElement.js,它不仅能够添加我们常用的html5视频格式(mp4,m4v,mov), 而且还支持回退方式,即一些低版本的浏览器不支持HTML5播放可以采取flash的方式进行播放,从而达到支持...

dazhuanqi8386的博客 162

Html5实现的简易视频播放器

HTML 代码是一个简单的包含视频播放的页面。

随意编程者 2306

终极指南:copyparty视频播放与WebM转码功能详解

copyparty是一款功能强大的便携式文件服务器,提供了完整的视频播放和WebM转码功能。这款工具支持多种视频格式的在线播放,并能智能地将音频文件转码为WebM格式,为用户提供流畅的媒体播放体验。 ## 🎬 强大的视频播放功能 copyparty内置了完整的视频播放器,支持直接在浏览器中播放多种视频格式。通过[浏览器界面](https://link.gitcode.com/i/075beb

gitblog_00289的博客 825

HTML5 视频播放demo

HTML5 视频播放demo     今天,大多数视频是通过插件(比如 Flash)来显示的。然而,并非所有浏览器都拥有同样的插件。     HTML5 规定了一种通过 video 元素来包含视频的标准方法。     在HTML5中,video元素目前支持三种格式的视频文件, 1.Ogg = 带有 Theora 视频编码和 Vorbis 音频编码的 Ogg 文件 2.MPEG4 = 带有

xiaochuandujun的专栏 2516

本地html5不能播放器,html5本地播放器

html5本地播放器使用html5中的video标签,因为video标签只支持ogg、webm和mp4格式的视频文件,所以这个播放器只能播放这3种格式的视频。苹果浏览器Safari只支持mp4格式的文件,并且不支持javascript获取本地文件的绝对路径,所以这个例子在Safari浏览器不能达到预期的效果,这个设想也没有达到原本的目的。function onInputFileChange() {...

weixin_33946999的博客 170

Java web 实现视频在线播放的常用几种方法

** 1. 使用jQuery库的 video.js (1) 首先我们要下载video.js 网址:http://www.jq22.com/jquery-info404 (2)然后在要播放的html/jsp 页面引入js (3)在要播放的div 加一个父div (m)并且定义它的样式 ** (4)播放器的位置 下面的代码只需要修改视频的地址就可以播放视频 <div class="m"> <video id="my-video" class="video-js" contro

m0_67392010的博客 1万+

ffmpeg实现web在线转码播放

前提: 公司项目中上传的视频编码格式不一,但是在浏览器播放中,却出现了黑屏(有声音)的情况,即使是MP4格式的视频,也存在无法播放,查询一番,了解到chrome浏览器的video标签仅对部分格式的视频支持播放通常我们使用MP4格式,但是MP4又分为“1.”、“2.”、“3.AVC(H264)”三种类型。其中只有H264类型的视频才能进行html播放 标签所支持的视频格式和编码:MP4MPEG 4文件使用H264视频编解码器和AAC音频编解码器WebMWebM文件使用VP8视频编解码器和Vorbis。

yinshipin007的博客 2412

java实现ftp跨服务器上传文件并用html5流媒体播放

两个服务器:Apache Tomcat和win2008 iis,要能ping通      要求从Tomcat的服务器上传视频文件到iis中,并且客户端浏览器能用流媒体播放,其实并不难,上传的话用ftp,common-net.jar提供了一系列用于ftp上传下载的方法,这要求iis的http网站中(一般用默认的就行)添加一个ftp发布,右击就能看到(不是新建一个ftp网站),不同版本iis可能不一

wobupeiai的博客 4714

使用video.js播放视频

1.下载video.js插件 2.引入相关标签,包括css、js等             _V_.options.flash.swf = "http://example.com/path/to/video-js.swf"   3、html页面播放视频部分   controls preload="auto" width="800" hei

asonFirst的博客 6233
上一篇: MSE播放fragmented mp4 问题记录
下一篇: kotlin如何配合动态代理使用
MorrisMao
博客等级 码龄18年 39粉丝 42原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值