zoukankan      html  css  js  c++  java
  • 关于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參数来处理的。比如:

    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端的视频文件中,在開始播放时前端播放器非常难获得相关的数据。

    那你可能会问。既然对于播放器来说。位置偏移非常难获得,那么时间又是怎么获得的?以优酷为例:

    http://v.youku.com/v_show/id_XMTI3NjM1Nzk1Ng==_ev_1.html

    这仅仅是一个播放页的html文件,并非实际要播放的视频。这个请求非常关键,通过这次请求。播放器前端能够获得该视频的整体播放时长等信息。

    关于这个信息我们能够在这个html的源代码里得到:

    这里写图片描写叙述

    最后一样3611.82就是视频总时长。取整以后就是60分11秒。

    那么接下来我们拖动视频进度条的时候,前端就能够拿光标在播放条上的位置。按比例换算成时间,然后作为start的參数,发起HTTP请求来获取对应内容了。

    鼠标偏移(已知) / 进度条总长度(已知) = 偏移时间(未知) / 总时长(已知)

    (未完待续)

  • 相关阅读:
    HDU 4348 To the moon(可持久化线段树)
    HDU 5875 Function 大连网络赛 线段树
    HDU 5877 2016大连网络赛 Weak Pair(树状数组,线段树,动态开点,启发式合并,可持久化线段树)
    HDU 5876 大连网络赛 Sparse Graph
    HDU 5701 中位数计数 百度之星初赛
    CodeForces 708B Recover the String
    Java实现 蓝桥杯 算法提高 套正方形(暴力)
    ASP.NET生成验证码
    ASP.NET生成验证码
    ASP.NET生成验证码
  • 原文地址:https://www.cnblogs.com/slgkaifa/p/7190374.html
Copyright © 2011-2022 走看看