关于MP4视频拖动的原理与分析(一)
本来想说说关于mp4和一些常见视频文件格式方面的历史。
如今想想没啥必要。毕竟本文是在讲关于mp4点播拖动方面的技术细节。
绪论,前言神马的显得有点多余。
说起MP4。不得不提“Digital container format”的概念。
维基百科给出解释:
A container or wrapper format is a metafile format whose specification describes how different elements of data and metadata coexist in a computer file
我们这里简称为容器。
mp4事实上就是一个容器,它包括的信息描写叙述了在这个容器里面存放的东西。是怎么布局,哪个地方放着什么东西。放了多少等等的信息。
既然谈到容器。那么除了MP4,还有非常多相似的。比方3GP, ASF, AVI, MKV, RM等等非常多我们常见的视频格式。
这里推荐一个工具,叫mp4parse.exe,网上能够搜到。当你用这个工具打开一个mp4文件时。会看到mp4内部是酱紫的:
在这里图中我们能够看到相似windows注冊表一样的层次关系。’+’号能够点击展开,看到内部的结构。像图中的ftyp,moov,mvhd,trak。mdat这些在mp4中叫做box。box的基本结构由box header + box data组成。
由于mp4官方协议中的box种类非常多,网上也有文章在解说关于各个box的作用。
这里就不一一列出了。接下来我们在讲关于文件拖动原理的时候会慢慢接触到。
在处理拖动时,必定要去解析mp4的格式,我们假定文件已经存在于我们server的磁盘上。文件名称为test.mp4。所以我们解析文件格式,就须要去读取该文件。可是对于读取的策略有非常多种。能够一次read或者mmap将磁盘上的内容搬到内存上来,可是对于体积太大的文件来说。这种方式是不可行的。第二种常见方式。就是须要读的时候才读指定的一点内容。比方当前仅仅读取boxA。处理解析完之后再读boxB。我们这里的分析就以这种方式来展开。这种代价就是产生了大量的IO。
这里另一种方式就是每次读取一块固定大小的内容,然后再解析,解析完了再去读一块数据。这样能够在IO和内存的消耗之间获得一个折衷。这些一些跟优化相关的问题。我们先不做过多的讨论。
一般的mp4点播拖动业务,通常都是通过在url的參数的start和end參数来处理的。比如:
start=10.01&&end=100.00">http://test.com/vedio/mp4/test.mp4?
start=10.01&&end=100.00
这里的start和end从程序的角度来看,他们是似乎是double类型。
他们事实上是时间。单位为秒。也就是说这个请求是想获取test.mp4文件的(在播放时间角度上来看)从10.01秒到100.00秒之间的这部分内容。当然,你可能说比較普遍的应该是仅仅有start而没有end,毕竟别人播放器拖动视频的时候,仅仅是在找一个起始的播放点,end不须要带,默认是到文件的末尾。
可是非常有站点可能有这种需求,为了省带宽。他们在你拖动之后,仅仅给你载入5分钟的数据,即end=start+5min。这种话请求的start和end參数就会同一时候存在。
那问题来了。为什么不直接用位移来作为start和end的參数。这样请求到了视频server,就能够依照偏移直接把文件发给你了。首先,这种情况不须要使用url參数,直接发送带range的http请求就能够了。再者,由于尾随机拖动的很多关键位移信息在server端的视频文件中,在開始播放时前端播放器非常难获得相关的数据。
那你可能会问。既然对于播放器来说。位置偏移非常难获得,那么时间又是怎么获得的?以优酷为例:
这仅仅是一个播放页的html文件,并非实际要播放的视频。这个请求非常关键,通过这次请求。播放器前端能够获得该视频的整体播放时长等信息。
关于这个信息我们能够在这个html的源代码里得到:
最后一样3611.82就是视频总时长。取整以后就是60分11秒。
那么接下来我们拖动视频进度条的时候,前端就能够拿光标在播放条上的位置。按比例换算成时间,然后作为start的參数,发起HTTP请求来获取对应内容了。
鼠标偏移(已知) / 进度条总长度(已知) = 偏移时间(未知) / 总时长(已知)
(未完待续)
关于MP4视频拖动的原理与分析(一)的更多相关文章
- IIS6/IIS7环境下实现支持mp4视频随意拖动、预览播放、边下载边播放
前几天,一客户需要在IIS环境下实现MP4视频可以随意拖动观看,边下载边播放.一看这要求,IIS本身是无法实现,想着应该需要用插件,于是GG一番,还真找到这样的插件,此组件为H264-Streamin ...
- Python 下载网络mp4视频资源
最近着迷化学, 特别是古代的冶炼技术,感叹古人的聪明. 春秋时期的炼铁方法是块炼铁,即在较低的冶炼温度下,将铁矿石固态还原获得海绵铁,再经锻打成的铁块.冶炼块炼铁,一般采用地炉.平地筑炉和竖炉3种.铁 ...
- 20169210《Linux内核原理与分析》第二周作业
<Linux内核原理与分析>第二周作业 本周作业分为两部分:第一部分为观看学习视频并完成实验楼实验一:第二部分为看<Linux内核设计与实现>1.2.18章并安装配置内核. 第 ...
- 《Linux内核原理与分析》教学进程
目录 2019-2020-1 <Linux内核原理与分析>教学进程 考核方案 第一周: 第二周: 第三周: 第四周: 第五周 第六周 第七周: 第八周 第九周 第十周 第十一周: 第十二周 ...
- 视频透雾原理加视频增强Retinex算法介绍
(本文转自:http://www.syphong.cn/52-1.html#) 视频透雾原理加视频增强Retinex算法介绍 -上海凯视力成 钟建军 一. 视频增强的背景 视觉信息是人类获得外界信息的 ...
- 2019-2020-1 20199329《Linux内核原理与分析》第二周作业
<Linux内核原理与分析>第二周作业 一.上周问题总结: 未能及时整理笔记 Linux还需要多用 markdown格式不熟练 发布博客时间超过规定期限 二.本周学习内容: <庖丁解 ...
- Chrome使用video无法正常播放MP4视频的解决方案
H5的video标签让前端开发者用一行代码就可以实现视频和音频的播放,然而,有时候我们会突然发现,某些Mp4格式的视频在Chrome下居然无法正常播放?这究竟是什么原因呢?这篇文章主要分析了部分Mp4 ...
- 20169212《Linux内核原理与分析》课程总结
20169212<Linux内核原理与分析>课程总结 每周作业链接汇总 第一周作业:完成linux基础入门实验,了解一些基础的命令操作. 第二周作业:学习MOOC课程--计算机是如何工作的 ...
- 20169212《Linux内核原理与分析》第二周作业
<Linux内核原理与分析>第二周作业 这一周学习了MOOCLinux内核分析的第一讲,计算机是如何工作的?由于本科对相关知识的不熟悉,所以感觉有的知识理解起来了有一定的难度,不过多查查资 ...
随机推荐
- 【转】使用信号监控 Django 模型对象字段值的变化
转载出处:http://blog.csdn.net/pushiqiang/article/details/74949465 Django 信号 (Signals) 的功能类似于 WordPress 的 ...
- luogu3760 [TJOI2017]异或和
看这里 #include <iostream> #include <cstring> #include <cstdio> using namespace std; ...
- WordPress添加前台注册功能
一.添加注册表单 1.首先在当前主题的目录下新建一个php文件,命名为reg-page.php,然后将page.php中的所有代码复制到reg-page.php中: 2.删除reg-page.php开 ...
- [android篇]声明权限
要实施您自己的权限,必须先使用一个或多个 <permission> 元素在 AndroidManifest.xml 中声明它们. 实际上,在开发过程中,当我们使用了某些系统特性的功能,且此 ...
- POJ-3261 Milk Patterns,后缀数组+二分。。
Milk Patterns 题意:求可重叠的至少重复出现k次的最长的字串长. 这题的做法和上一题 ...
- BZOJ 2140 稳定婚姻 ——二分图
论二分图的可行边与必须边. 考虑用dinic增广之后的图,一些是必要的割边,一些是可行的割边. 我们首先求出一组可行的最大匹配,那么这些变都是可行的. 然后我们求一遍强连通分量. 如果 scc[u]! ...
- mybatis学习(四)——config全局配置文件解析
在全集配置文件中引入dtd约束“http://mybatis.org/dtd/mybatis-3-config.dtd”,主要有以下几个标签,现在详细解释下这几个标签的使用 1.properties属 ...
- Tengine的concat模块与js、css合并
首先,先走出一个误区 ,下面是tengine-cn邮件列表里的一篇邮件原文:“看了这个例子就了解了,这个所谓的合并请求只是把所有的CSS或JAVASCRIPT请求合并,必须是同一个文件类型的.我开始想 ...
- Laravel 之Cache缓存
写入缓存 Cache::put('key','value',10);//设置10分钟 获取缓存 Cache::get('key'); 增加缓存 Cache::add('key','value',10) ...
- Maven单元测试
// SKU码:系列前3位+6位年月日+3位序号(自动生产,取数据库中当天最大的,没有就赋值位001) // 订单编号:BRD+6位年月日+5位序号 // // 退单号:BRT+6位年月日+3位序号 ...