研究了一下Adobe家HDS的具体实现 OSMF。利用其中的一个核心方法 flash.net.NetStream.appendBytes()构建了我们自己的HTTP点直播播放框架。
但今年年初发现一个问题:新框架直播的时候有爆音。

经过一段时间的现象收集,问题总结出来是这样:
1、直播的时候,播放一段时间后出现爆音;
2、同时去听别的电脑,并不是每台电脑上都会出现爆音;
3、出现爆音的不同电脑之间,Mac的爆音现象比Windows明显;
4、出现爆音的同一台电脑上,Mac上Chrome的爆音现象比Safari明显,Windows上Chrome的爆音现象比IE明显;
5、如果不经过浏览器,本地打开swf来播放流,则无爆音。

首先,我们想到了浏览器问题。于是升级最新的浏览器和FP,无效。

然后,开始怀疑Ffmpeg的segment muxer,于是俺自己写了一个Flv segmenter,无效。

接着,尝试看看播放框架本身是不是有什么问题。

我们原有的逻辑是这样:每个flv片都自带flv头以及AVC和AAC的第0帧,每次调用appendBytes()都调用一次appendBytesAction(RESET_BEGIN)。

现在我先用gnu split将一个大的flv文件按照300k一个切开,这样就只有第一个文件片有flv头和AVC的AAC的第0帧了。再构造对应的假直播接口,然后将播放框架的改成只有下载到第一片的时候才调用flash.net.NetStream.appendBytesAction(RESET_BEGIN),而后所有的片都只调用flash.net.NetStream.appendBytes()。

此时我惊喜地发现,爆音现象解除了。

但出现了另一个问题,播放画面开始出现卡顿。于是继续查找卡顿的原因。

卡顿的原因很简单。appendBytes()方法自带了2个buffer。除开正常的IO buffer,还有一个FIFO的tag buffer。它最多存放一个flv tag,每拼装出一个完整的flv tag就将其推入IO buffer。这样它就可以负责保证虽然数据都是一片一片碎片拼装起来的,但IO buffer中都是完整的flv tag。

我之前使用gnu split切分出来的文件肯定不是按照tag的边缘切分的文件。经观察,在片间填充tag buffer的时候就会出现卡顿。

于是使用自己的flv segmenter严格按照tag边缘来切分文件。

卡顿消失!但爆音归来……

最后,我们就想到这爆音会不会跟buffer有点关系呢?

编写框架初期,我们为了让用户减少直播延迟,设置了bufferTimeMax为20,作用是让buffer太满的用户加速播放它们buffer中的流,以追上最新直播点。是不是这个机制导致的爆音呢?

查看OSMF,它是将bufferTimeMax写死为0的。于是我们也将bufferTimeMax设为0。

爆音消失。

反推出几个结论:
1、之前部分电脑无法再现爆音问题,很有可能是因为它们的网速没有快到可以填满buffer的地步;
2、我们可能要使用跳过一些片的方式让网速不稳定用户减少直播的延迟;
3、OSMF里面还是有很多营养值得去吸取的。

这是次历时月余的查错。

现在终于解除了纠结,这感觉真好,真好。

解决NetStream.appendBytes直播爆音的问题解决的更多相关文章

  1. Monster Audio 使用教程 (七) 防止声音过大,出现爆音

    有用户反映,如果音乐音量过大,会出现爆音. 这其实是音频信号过载了.只要最后输出的音量超过0db,就会出现爆音,这是数字音频都应该注意的问题. 所以,为了解决这个问题,限制器就出现了,它能把音频信号压 ...

  2. # 模乘(解决乘法取模爆long long)

    模乘(解决乘法取模爆long long) 二进制思想,变乘法为多次加法,具体思想跟着代码手算一遍就理解了,挺简单的 ll qmul(ll a,ll b,ll m) { ll ans=0; while( ...

  3. HMS Core Discovery第17期直播预告|音随我动,秒变音色造型师

    [导读] 随着音视频内容品类的不断丰富及音乐创作门槛不断降低,大量用户正热切的参与到全民创作的大潮中.我们应该怎么去拥抱移动端影音潜力市场?音频编辑又可以有什么新玩法? 本期直播<音随我动,秒变 ...

  4. NetStream.appendBytes, 走向Flash P2P VOD的第一步

    之前被告知可以自行实现Flash p2p的点播功能, 但一直疑惑, 印象中NetStream并未提供相关方法, 前天看订阅时发现的文章: ByteArray Access to NetStream i ...

  5. IntelliJ IDEA :解决idea导入项目爆红

    转:https://my.oschina.net/LevelCoder/blog/1802158 我们在导入一个新的项目到idea的时候,项目明明没有报错,但是会出现出了父包属于正常颜色外,其子包都会 ...

  6. Python利用带权重随机数解决抽奖和游戏爆装备问题

    关于带权随机数 为了帮助理解,先来看三类随机问题的对比: 1.已有n条记录,从中选取m条记录,选取出来的记录前后顺序不管. 实现思路:按行遍历所有记录,约隔n/m条取一个数据即可 2.在1类情况下,还 ...

  7. [Windows] 解决kmplayer播放rmvb文件音视不同步

    1. 到該帖子 http://www.kmplayer.com/forums/showthread.php?t=8755 下載附件中的4個檔案放到KMP 根 目錄下(此文件已在附件中上传) 2.於KM ...

  8. AndroidStudio 代码(导入类)报错但可正常运行,以及解决此问题后带来的系列问题解决

    首先是应用中很多导入的类都报红色异常显示找不到此类,但运行编译正常: 第一种方法: 点击AndroidStudio菜单File -> Invalidate Caches/Restar… ,在弹出 ...

  9. 12┃音视频直播系统之 WebRTC 实现1对1直播系统实战

    一.搭建 Web 服务器 前面我们已经实现过,但是没有详细说HTTPS服务 首先需要引入了 express 库,它的功能非常强大,用它来实现 Web 服务器非常方便 同时还需要引入 HTTPS 服务, ...

随机推荐

  1. Qt5:窗口居中显示

    QDesktopWidget* desktop = QApplication::desktop(); // =qApp->desktop();也可以move((desktop->width ...

  2. USACO Section 1.2 Palindromic Squares 解题报告

    题目 题目描述 输入一个基数B,现在要从1到300之间找出一些符合要求的数字N.如果N的平方转换成B进制数之后是一个回文串,那么N就符合要求.我们将N转换成B进制数输出,然后再将N的平方转换成B进制数 ...

  3. bootstrap-table 表头和内容对不齐解决办法

    偶然机会学习bootstrap,表格利用bootstrap-table实现,使用bootstrap-table过程中,发现了一个非常棘手的问题,在ie浏览器中,表格的表头和内容对不齐,特别是列比较多且 ...

  4. localStorage、sessionStorages 使用

    html5中的Web Storage包括了两种存储方式:sessionStorage和localStorage.sessionStorage用于本地存储一个会话(session)中的数据,这些数据只有 ...

  5. [iOS]Objective-C 第一节课

    Objective-C 第一节课 本节课的主要内容 创建Objective-C的第一个工程 HelloWorld Objective-C中的字符串 创建Objective-C的第一个工程 打开Xcod ...

  6. 学习Redis从这里开始

    本文主要内容 Redis与其他软件的相同之处和不同之处 Redis的用法 使用Python示例代码与Redis进行简单的互动 使用Redis解决实际问题 Redis是一个远程内存数据库,它不仅性能强劲 ...

  7. hibernate---一对一双向外键关联 (重要)

    husband--wife: one to one 双向外键关联: 主导方: @OneToOne @JoinColumn(name="wifeId") 被主导方: @OneToOn ...

  8. Github for Windows使用图文教程_西西软件资讯

    body{ font-family: "Microsoft YaHei UI","Microsoft YaHei",SimSun,"Segoe UI& ...

  9. Extraordinarily Tired Students UVA - 12108

    不知道叫什么,好像是模拟的方法,看懂了题就好办(英语硬伤←_←) 题意大概是当一个同学想睡觉的时候判断周围睡觉的人数,不睡的人数大于等于睡觉的话就死撑着,否则就睡觉. 一开始没有什么思路,就直接用了个 ...

  10. javascript之日期对象

    学习要点: 日期对象 将日期对象转换为字符串 将日期对象中的日期和时间转换为字符串 日期对象中的日期 日期对象中的时间 设置日期对象中的日期 设置日期对象中的时间 与毫秒相关的方法 一.日期对象 在j ...