使用 MediaSource 实现视频边播放边加载效果

flv.js播放http-flv流时报错分析 错误描述: console 信息: Uncaught (in promise) DOMException flv.js:11675 [MSEController] > MediaSource onSourceOpen flv.js:11590 [TransmuxingController] > DemuxException: type = FormatError, info = Flv: Invalid AVCDecoderConfigurationRecord 错误的大致意思是:格式错误,无效 阅读详情
AI摘要

本文通过简单demo实现视频分段加载且边播放边加载的效果。整体思路是利用HTTP请求头的Range获取视频部分数据,通过MediaSource控制媒体片段加载缓存和播放。还解决了MP4视频无法播放的问题,介绍了后端基于SpringMVC的代码和前端代码,并进行了验证。

背景

打开B站看视频时,发现每个视频点进去后马上播放,并只加载视频一小段,然后在播放同时加载后面一小段,而且在拖动进度条也能快速加载并播放。
在这里插入图片描述

本文通过简单demo实现一下视频分段加载并且边播放边加载的效果。

整体思路是,通过 HTTP 请求头中添加 Range 获取视频的一部分数据,然后通过 MediaSource 控制媒体片段加载缓存和播放。

分析过程参考:
通过调试技术,我理清了 b 站视频播放很快的原理

代码参考:
MDN - WebAPI - MediaSource
一步一步学习使用 MediaSource 实现动态媒体流

MediaSource

演示源代码 ,直接全贴出来,加载全部如下

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8"/>
  </head>
  <body>
    <video controls></video>
    <script>
      var video = document.querySelector('video');

      var assetURL = 'frag_bunny.mp4';
      // Need to be specific for Blink regarding codecs
      // ./mp4info frag_bunny.mp4 | grep Codec
      var mimeCodec = 'video/mp4; codecs="avc1.42E01E, mp4a.40.2"';

      if ('MediaSource' in window && MediaSource.isTypeSupported(mimeCodec)) {
   
   
        var mediaSource = new MediaSource;
        //console.log(mediaSource.readyState); // closed
        video.src = URL.createObjectURL(mediaSource);
        mediaSource.addEventListener('sourceopen', sourceOpen);
      } else {
   
   
        console.error('Unsupported MIME type or codec: ', mimeCodec);
      }

      function sourceOpen (_) {
   
   
        //console.log(this.readyState); // open
        var mediaSource = this;
        var sourceBuffer = mediaSource.addSourceBuffer(mimeCodec);
        fetchAB(assetURL, function (buf) {
   
   
          sourceBuffer.addEventListener('updateend', function (_) {
   
   
            mediaSource.endOfStream();
            video.play();
            //console.log(mediaSource.readyState); // ended
          });
          sourceBuffer.appendBuffer(buf);
        });
      };

      function fetchAB (url, cb) {
   
   
        console.log(url);
        var xhr = new XMLHttpRequest;
        xhr.open('get', url);
        xhr.responseType = 'arraybuffer';
        xhr.onload = function () {
   
   
          cb(xhr.response);
        };
        xhr.send();
      };
    </script>
  </body>
</html>

播放过程中加载,如下

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8"/>
  </head>
  <body>
    <video controls></video>
    <script>
      var video = document.querySelector('video');

      var assetURL = 'frag_bunny.mp4';
      // Need to be specific for Blink regarding codecs
      // ./mp4info frag_bunny.mp4 | grep Codec
      var mimeCodec = 'video/mp4; codecs="avc1.42E01E, mp4a.40.2"';
      var totalSegments = 5;
      var segmentLength = 0;
      var segmentDuration = 0;
      var bytesFetched = 0;
      var requestedSegments = [];

      for (var i = 0; i < totalSegments; ++i) requestedSegments[i] = false;

      var mediaSource = null;
      if ('MediaSource' in window && MediaSource.isTypeSupported(mimeCodec)) {
   
   
        mediaSource = new MediaSource;
        //console.log(mediaSource.readyState); // closed
        video.src = URL.createObjectURL(mediaSource);
        mediaSource.addEventListener('sourceopen', sourceOpen);
      } else {
   
   
        console.error('Unsupported MIME type or codec: ', mimeCodec);
      }

      var sourceBuffer = null;
      function sourceOpen (_) {
   
   
        sourceBuffer = mediaSource.addSourceBuffer(mimeCodec);
        getFileLength(assetURL, function (fileLength) {
   
   
          console.log((fileLength / 1024 / 1024).toFixed(2), 'MB');
          //totalLengt
Exoplayer简介 Exoplayer是一个android平台的播放器,支持格式比android系统的mediaplayer更好,确定性更好,mediaplayer是可以进行厂家定制的,各平台一致性比较差,这里简单介绍一下Exoplayer的最基础的使用接口,方便之后阅读源码。 阅读详情

相关推荐

zlmediaKit中Mediasource解读

首先说明,都是一边看一边写,时间有限,错误难免,请见谅,可参考,具体以源码为准: 通过代码知道,媒体源是保存在一个全局变量 所谓媒体源注册就是把其内部的所有参数都初始化后添加到全局变量中,算是注册。 /** * 设置metadata */ virtual void setMetaData(const AMFValue &metadata) { _metadata = metadata; if (_ring) { regist(); } } 所有通道准备完毕后就可以去注册了 注册后rtmp/rtsp/

weixin_43360707的博客 2527

ExoPlayer进阶:如何自定义MediaSource实现无缝视频拼接与循环播放(2.11.7版本详解)

本文深入解析ExoPlayer 2.11.7版本中自定义MediaSource的实现方法,重点介绍如何通过Android平台实现视频无缝拼接与循环播放。内容涵盖核心架构解析、源码分析、性能优化技巧及高级应用场景,帮助开发者提升视频播放体验。

weixin_30832143的博客 93

UE5视频自动循环播放:蓝图实现与Electra插件配置指南

在实时渲染和交互式应用开发中,视频纹理的动态映射是提升场景真实感和信息承载能力的关键技术。其核心原理是通过媒体框架将视频流解码为连续的图像序列,并作为纹理资源实时应用到三维模型表面,实现动态视觉效果。这项技术的工程价值在于能够高效地将预录制或实时视频内容无缝集成到虚拟环境中,极大地扩展了数字孪生、虚拟展厅和游戏内信息展示的表现形式。在实际应用场景中,开发者常面临视频自动播放、循环控制以及现代编码格式兼容性等挑战。本文聚焦于UE5引擎,详细解析如何通过蓝图系统构建状态驱动的自动循环播放逻辑,并针对H.265等

weixin_30321709的博客 659

从浏览器缓存到本地:揭秘油猴脚本如何捕获并重组视频流

本文深入解析了如何通过油猴脚本捕获和重组浏览器视频流,详细介绍了MediaSource Hook技术实现、分片数据重组与导出方法,并提供了完整的油猴脚本实战代码。文章特别强调了视频下载技术的应用场景和合规性考量,为开发者提供了从理论到实践的全面指导。

flink9streamer的博客 791

vue2 - 详细实现“视频切片/分段加载“播放大视频,解决视频过大加载播放缓慢问题,vue处理超大视频进行切片请求加载、分段缓存方案,把视频分成很多小段逐步加载解决卡顿,类似影视网站大电影播放技术!

vue2,nuxt2,视频,video,分段加载,axios,切片,分片,视频太大,大视频,很长的视频播放太慢,电影网站,请求接口,后端,服务器,一段一段的请求,分片加载视频,边播放边加载,把大视频拆成多个小视频,vue使用video视频标签加载视频很卡,如何能把视频在前端进行分批请求,不要一次性都请求过来,而是一部分一部分请求,播放视频,太卡,不流畅,电影网站视频播放如何做到的流畅,分段加载video,vue视频分片上传,Range,vue视频切片加载,缓存,分片存储,播放按需加载小片段,视频分段渐进式播

✅ 精选推荐文章 1万+

vue3 - 详细实现“视频切片/分段加载“播放大视频,解决视频过大加载播放缓慢问题,vue处理超大视频进行切片请求加载、分段缓存方案,把视频分成很多小段逐步加载解决卡顿,类似影视网站大电影播放技术!

vue3,nuxt3,视频,video,分段加载,axios,切片,分片,视频太大,大视频,很长的视频播放太慢,电影网站,请求接口,后端,播放视频,太卡,不流畅,ts,电影网站视频播放如何做到的流畅,分段加载video,vue视频分片上传,Range,vue视频切片加载,缓存,分片存储,播放按需加载小片段,视频分段渐进式播放,服务器,一段一段的请求,分片加载视频,边播放边加载,把大视频拆成多个小视频,vue使用video视频标签加载视频很卡,如何能把视频在前端进行分批请求,不要一次性都请求过来,而是一部分一

✅ 精选推荐文章 6089

vue2/3 - 最新详细实现网页播放 flv 格式视频文件,vue在线播放flv视频流详细教程,播放本地或在线播放地址的flv流媒体功能,支持改造flv直播视频推流(详细示例代码,一键复制开箱即用)

vue2,vue3,nuxt,flv,视频,vue3播放flv格式的视频,播放视频,vue如何播放flv视频,RTMP协议,HTTP FLV协议,解决CORS跨域问题,flv跨域怎么办,vue如何播放RTMP协议的flv视频,黑屏报错,flv直播推流,flv播放器,flv在网页上播放有什么插件,详细教程,Vue3中使用 flv.js 播放视频,vue+flv.js 播放器播放flv视频流,接入flvjs播放视频,vue中播放flv流视频,b站,哔哩哔哩,Vue摄像头视频分屏,使用flv.js接收rtmp/f

✅ 精选推荐文章 1万+

实战STM32G0驱动DRV8870/AT8870:PWM+DMA精准调速与H桥衰减模式详解

本文详细介绍了如何使用STM32G0单片机结合DRV8870/AT8870电机驱动芯片实现直流有刷电机的精准控制。重点讲解了PWM与DMA结合实现高效调速的硬件配置与软件驱动方法,并深入剖析了H桥快衰减与慢衰减模式的工作原理及应用场景,为嵌入式电机控制项目提供了完整的实战解决方案。

c7d8e9的博客 595

【测试】echo发送和接收TCP/UDP数据包|shell 发送TCP/UDP数据包

目录 通过/dev/tcp、/dev/udp shell给tcp或udp服务发送16进制报文指令 通过/dev/tcp、/dev/udp (https://blog.youkuaiyun.com/u010039418/article/details/86251470) 通过/dev/tcp、/dev/udp可以直接在shell脚本中发起tcp、udp连接,方便又高效,平时用于测试啥的还是挺方便的。 直接发送 格式 /dev/udp/ip/port 比如要向本地10001端口发送数据,可以使用 ec.

我的笔记本 1万+

QT-使用ECharts显示地图,还有更多惊艳的图表等待你的使用

QT-使用ECharts显示地图前言一、使用步骤1.下载示例2. QT使用HTML文件配置3.使用HTML文件4. 数据交互及自适应总结注意:这个地图是百度的在线地图,需要百度API密钥和在联网的状态下使用。离线使用图表 前言 我上文QT图表chart-饼状图,使用qt自带的图表库charts来显示图表,实现数据可视化,但是QT自带的图表库显示效果并不佳,通俗说,就是不好看。 然而,有这么一个开源图表库,图表种类极多,并且效果良好,能够实现具有很好的视觉冲击的数据可视化。 它就是Apache ECharts

博咯的博客 4898

手把手教你用示波器实测CAN总线波形:快速区分高速、低速及常见故障

本文详细介绍了如何使用示波器实测CAN总线波形,快速区分高速CAN总线和低速CAN总线,并诊断常见故障。通过实战案例和波形分析,帮助工程师掌握CAN总线信号特征,提升故障排查效率,适用于汽车电子和工业控制领域。

weixin_33217202的博客 410

【C#程序员入门AI】必知的一些知识

2026年C#调用AI,核心就4个概念+3种方式4个概念:大模型(大脑)、嵌入(数字密码)、向量(载体)、Agent(超级助理)3种方式:云端API(快)、本地模型(隐私)、混合部署(最佳)不用怕复杂,跟着这个思路走,你就能从“AI小白”变成“C# AI开发能手”,把AI集成到你的.NET项目里,提升效率、创造价值!

人工智能AI技术 410

Amazon SES 移出沙盒完整指南 & 高通过率模板

AWS SES沙盒模式转正式模式申请指南 申请正式模式需通过AWS审核,常见被拒原因包括邮件用途不清晰、缺少退订机制或发送量不合理。人工申诉需登录AWS Support Center提交服务限额提升请求,填写详细的公司信息、邮件用途及合规措施。 高通过率申诉模板需包含: 公司信息:名称、网址及与AWS的合作情况。 邮件规范:明确类型(交易/营销)、退订链接及退信处理机制。 发送计划:合理预估发送量,确保合规。 关键点:真实信息、用途清晰、退订机制完善、发送量合理。首次被拒可修改后重新提交。

xianyinsuifeng的博客 329

基于深度学习的CT图像肺结节分割与检测系统[完整代码数据分享]

基于深度学习的CT图像肺结节分割与检测系统[完整代码数据分享]

269

Winform从入门到精通(2)——Button(史上最全)

本文介绍winform中Button控件的详细用法,包括所有属性和事件

qq_34059233的博客 1万+

visio安装包

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

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

上一篇: MySQL 事务默认隔离级别?能否解决幻读?
litte_frog
博客等级 码龄9年 39粉丝 50原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值