视频直播技术(五):使用Ijkplayer倍速变调问题解决方案
2017-03-06 17:12
1331 查看
转载注明出处:http://www.cnblogs.com/renhui/p/6510872.html
之前使用IjkPlayer做播放器的使用的时候,在做倍速播放的时候,发现播放的声音音调明显变高了。问题的详情参见Bilibili/ijkplayer的#2930、#2785等。
在解决问题之前首先对倍速的代码做一次追踪
a. Android应用中Java层面调用的代码:
倍速代码
追踪完毕,我们发现,基本上在Java层设置的倍速代码,会被一层一层的传递到FFPlayer上面去。在IjkPlayer 0.7.9版本之前,可以说,我们对变调的问题,没有头绪,因为IjkPlayer将音频的处理模块直接调用系统的音频处理模块进行输出,这样的话,我们就可以看到在Android 6.0以下的手机在用IjkPlayer跑倍速的时候,出现音调变高的情况。
近期,IjkPlayer的github上面发布了最新版本0.7.9版本。
下面引用一下IjkPlayer近几个版本的changelog(Android相关的):
发现,0.7.9版本支持了soundtouch机制了。而且给出了开启soundtouch机制的方式。
如果不开启,在音频播放的时候,还是使用系统提供的api做播放处理(那么声调问题还是存在)。开启后,如果不对IjkPlayer C层面的逻辑做更改,也会有声调的问题(因为B站对倍速的要求就是变调)。
那么后续的工作就是先了解soundtouch然后对IjkPlayer的代码做相关的调整。
了解和学习souchtouch:在 http://www.surina.net/soundtouch/index.html (官网) 里面了解和学习。辅助学习的博客:http://www.cnblogs.com/wangguchangqing/p/6003087.html。
同步下来0.7.9版本的代码后,可以看到,在extra目录下增加了soundtouch目录,这个目录下面就是soundtouch相关的逻辑。经过浏览代码发现只需要去调整soundtouch/source/SoundStretch/main.cpp里面的代码:
调用重新打so,引入,Java层开启soundtouch
使用倍速,此时变调的问题,应该解决了。
~~~~~~~~~~~~~~~~~~~~分割线~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
目前Ijk版本为0.8.1版本,这个版本下,不去做上面的那些事情,只需要设置1,就为变速变调的状态。
设置0,就是变速不变调的状态,
当然,如果按照上面的更改修改了C代码了,也可以,只不过,不管设置多少,都为变速不变调的状态了。
之前使用IjkPlayer做播放器的使用的时候,在做倍速播放的时候,发现播放的声音音调明显变高了。问题的详情参见Bilibili/ijkplayer的#2930、#2785等。
在解决问题之前首先对倍速的代码做一次追踪
a. Android应用中Java层面调用的代码:
void ffp_set_playback_rate(FFPlayer *ffp, float rate) { if (!ffp) return; ffp->pf_playback_rate = rate; ffp->pf_playback_rate_changed = 1; }
倍速代码
追踪完毕,我们发现,基本上在Java层设置的倍速代码,会被一层一层的传递到FFPlayer上面去。在IjkPlayer 0.7.9版本之前,可以说,我们对变调的问题,没有头绪,因为IjkPlayer将音频的处理模块直接调用系统的音频处理模块进行输出,这样的话,我们就可以看到在Android 6.0以下的手机在用IjkPlayer跑倍速的时候,出现音调变高的情况。
近期,IjkPlayer的github上面发布了最新版本0.7.9版本。
下面引用一下IjkPlayer近几个版本的changelog(Android相关的):
tag k0.7.9 ffmpeg: add tcp timeout control // 增加TCP超时控制逻辑 android: support soundtouch // Android端 支持soundtouch机制 tag k0.7.8 ffplay: support accurate seek // ffplay 支持更加精确的seek ijkio: fix some issue // 修复一些问题
发现,0.7.9版本支持了soundtouch机制了。而且给出了开启soundtouch机制的方式。
{ "soundtouch", "SoundTouch: enable", OPTION_OFFSET(soundtouch_enable), OPTION_INT(0, 0, 1) }
如果不开启,在音频播放的时候,还是使用系统提供的api做播放处理(那么声调问题还是存在)。开启后,如果不对IjkPlayer C层面的逻辑做更改,也会有声调的问题(因为B站对倍速的要求就是变调)。
那么后续的工作就是先了解soundtouch然后对IjkPlayer的代码做相关的调整。
了解和学习souchtouch:在 http://www.surina.net/soundtouch/index.html (官网) 里面了解和学习。辅助学习的博客:http://www.cnblogs.com/wangguchangqing/p/6003087.html。
同步下来0.7.9版本的代码后,可以看到,在extra目录下增加了soundtouch目录,这个目录下面就是soundtouch相关的逻辑。经过浏览代码发现只需要去调整soundtouch/source/SoundStretch/main.cpp里面的代码:
pSoundTouch->setSampleRate(sampleRate); pSoundTouch->setChannels(channels); pSoundTouch->setTempoChange(params->tempoDelta); pSoundTouch->setPitchSemiTones(0); // 更改这里,其他不变 pSoundTouch->setRateChange(params->rateDelta);
调用重新打so,引入,Java层开启soundtouch
ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "soundtouch", 1);
使用倍速,此时变调的问题,应该解决了。
~~~~~~~~~~~~~~~~~~~~分割线~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
目前Ijk版本为0.8.1版本,这个版本下,不去做上面的那些事情,只需要设置1,就为变速变调的状态。
ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "soundtouch", 1);
设置0,就是变速不变调的状态,
ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "soundtouch", 1);
当然,如果按照上面的更改修改了C代码了,也可以,只不过,不管设置多少,都为变速不变调的状态了。
相关文章推荐
- Java路径问题最终解决方案使用演示
- Ubuntu8.10安装使用问题解决方案集中
- 如何解决ASP使用FFMPEG进行视频截图时报出的“无法创建对象”问题
- 使用VS2005调试问题解决方案
- 在EJB3中使用AOP技术解决用户验证等公共问题
- 使用NEWSEQUENTIALID解决GUID聚集索引问题 SQLServer数据表主键的另一个方案
- 关于STM32的硬件IIC使用问题解决方案
- HessianCSharp 1.3.3版本前使用泛型以及接口interface继承问题解决方案!!(实例代码)
- 使用Z-Bias解决Z-Fighting问题的替代方案 Alternatives to Using Z-Bias to Fix Z-Fighting Issues
- VC使用双缓存技术,解决闪屏问题
- C#中使用多线程访问Winform问题解决方案
- C#中使用多线程访问Winform问题解决方案
- Spring3.0.2 使用 Annotation 与 @Transactional 冲突问题解决方案
- Java路径问题最终解决方案使用演示
- MFC 使用MsFlexGrid 控件发布后无法在其它机器运行问题解决方案
- 关于HUAWEI EG162G安装使用问题解决方案
- Ubuntu8.10安装使用问题解决方案集中
- C#中使用多线程访问Winform问题解决方案
- C#中使用多线程访问Winform问题解决方案
- 关于 Fiddler 使用的两个常见问题的解决视频