之前使用IjkPlayer做播放器的使用的时候,在做倍速播放的时候,发现播放的声音音调明显变高了。问题的详情参见
在解决问题之前首先对倍速的代码做一次追踪
a. Android应用中Java层面调用的代码:
public void setSpeed(floatspeed) {
_setPropertyFloat(FFP_PROP_FLOAT_PLAYBACK_RATE, speed);
}public float getSpeed(floatspeed) {return_getPropertyFloat(FFP_PROP_FLOAT_PLAYBACK_RATE, .0f);
b.找到C库里面对应的方法:_setPropertyFloat (ijkplayer_jni.c)
static void ijkMediaPlayer_setPropertyFloat(JNIEnv *env, jobject thiz, jint id, jfloat value)
IjkMediaPlayer*mp =jni_get_media_player(env, thiz);
JNI_CHECK_GOTO(mp, env, NULL,"mpjni: setPropertyFloat: null mp", LABEL_RETURN);
ijkmp_set_property_float(mp, id, value);
LABEL_RETURN:
ijkmp_dec_ref_p(&mp);return;
c.找到C库中的对应的方法:ijkmp_set_property_float(ijkplayer.c)
void ijkmp_set_property_float(IjkMediaPlayer *mp, int id, floatvalue)
assert(mp);
pthread_mutex_lock(&mp->mutex);
ffp_set_property_float(mp->ffplayer, id, value);
pthread_mutex_unlock(&mp->mutex);
d.找到C库中对应的方法:ffp_set_property_float(ff_ffplay.c)
void ffp_set_property_float(FFPlayer *ffp, int id, floatvalue)
{switch(id) {caseFFP_PROP_FLOAT_PLAYBACK_RATE:
ffp_set_playback_rate(ffp, value);break;caseFFP_PROP_FLOAT_PLAYBACK_VOLUME:
ffp_set_playback_volume(ffp, value);break;default:return;
e.找到C库中对应的方法ffp_set_playback_rate:(ff_ffplay.c)
void ffp_set_playback_rate(FFPlayer *ffp, floatrate)
{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的代码做相关的调整。
同步下来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代码了,也可以,只不过,不管设置多少,都为变速不变调的状态了。
弱网丢帧策略:丢弃原始队列未编码的数据帧,丢弃编码队列的数据帧。
视频移动端播放内核技术;视频加载时长,秒播的体验.流畅度和清晰度都是用户最根本的诉求和最基础的产品体验。
播放器
的主要工作原理类似于编码的逆运算。
在做
音频
播放的时候,使用的是
开源
的
ijk
player
播放器
,
ijk
player
解码使用的是ffmpeg,声音输出使用的是audiotrack,在某机型上面播放遇到锁屏、返回后台、...
//生成一个新的surface view
surfaceView = new SurfaceView(mContext);
surfaceView.getHolder().addCallback(new LmnSurfaceCallback());
LayoutParams layoutParams = new LayoutParams(LayoutParams.MATCH_PARENT
, LayoutParams.MATCH_PARENT, Gravity.CENTER);
surfaceView.se
在做
音频
播放的时候,很多公司使用的是
开源
的
ijk
player
播放器
,
ijk
player
底层是基于ffmpeg,在某机型上面可能常常遇到各种
问题
。今天整理了大家在使用
ijk
player
中遇到的
问题
,以及根据
ijk
player
社区issue和solution方案。如下:
1、直播技术总结(三)
ijk
player
的一些
问题
优化记录
https://blog.csdn.net/hejjunlin/arti...
下面简单介绍一下
ijk
player
的使用
ijk
player
是b站基于FFmpeg
开源
的
播放器
,
ijk
player
提供了个
Ijk
Media
Player
,功能和用法跟Media
Player
类似,但是强大很多
官网Github
一、
ijk
player
使用
1、新建一个Android项目,并在app的gradle下的dependencies中添加下面代码,其中
ijk
player
-
java
是核心代码必...
wlmusic v1.2.6(讨论群:806397913)基于FFmpeg + OpenSL ES的
音频
播放SDK。可循环不间断播放短
音频
;播放raw和assets
音频
文件;可独立设置音量大小;可实时现在音量分贝大小(用于绘制波形图);可改变
音频
播放速度和音调(变速不
变调
、
变调
不变速、变速又
变调
);可设置播放声道(左声道、右声道和立体声);可边播边录留住美好音乐;可裁剪指定时间段的
音频
,制作自己的...
在听筒模式下am.setSpeakerphoneOn(false);setVolumeControlStream(AudioManager.STREAM_VOICE_CALL);am.setMode(AudioManager.MODE_IN_CALL);我用Media
player
AudioTrack调节音量总是失败at.setStereoVolume(vol, vol);
player
.setVo...
public void setSpeed(float speed) {
_setPropertyFloat(FFP_PROP_FLOAT_PLAYBACK_RATE, speed);
public float getSpeed(float speed) {
return _getPropertyFloat(FFP_PROP_FLOAT_PLAYBACK_RATE, .0f);
{ "_setPropertyFloat",
都稍微讲过变声的原理和具体实现。大家都知道,算法从实现到最后工程应用,中间的环节和
问题
特别多。尤其是编码的架构设计,好的数据结构和代码逻辑封装肯定是可复用,组件化的。我也提及到了。会做一些算法编码优化相关的分享。而有时候我总觉得文字表达很苍白,所以我尽可能地把代码写得简洁易懂,一方面是便于基础差的朋友学习。另一方面也是为了自己在编码以及思考的时候,能更加清晰。当然,变声算法绝大多数朋友都会选择一些...
FFmpeg打造Android万能
音频
播放器
视频教程,移植FFmpeg到Android平台,利用FFmpeg解码
音频
数据并用OpenSL ES来播放,打造Android万能
播放器
。
1、
ijk
player
编码
Ijk
Player
支持硬解码和软解码。 软解码时不会旋转视频角度这时需要你通过onInfo的what == IMedia
Player
.MEDIA_INFO_VIDEO_ROTATION_CHANGED去获取角度,自己旋转画面。或者
开启
硬解硬解码,不过硬解码容易造成黑屏无声(硬件兼容
问题
),下面是设置硬解码相关的代码
media
Player
.setOption(
Ijk
...
本文主要分析变速播放框架实现细节,不分析sonic以及
soun
dto
uch
变速算法。在我的sonic变速
变调
原理一文中会详细讲解基于基音周期来实现变速
变调
的原理
1.变速入口分析
从jni层的_setPropertyFloat函数
static void
ijk
Media
Player
_setPropertyFloat(JNIEnv *env, jobject thiz, jint id, jflo...
安装 ffmgeg 下载地址https://github.com/BtbN/FFmpeg-Builds/releases/
win系统下载ffmpeg-N-103272-g7bba0dd638-win64-gpl.zip
配置环境变量到 bin目录
新建maven程序加入两个引用
<!-- https://mvnrepository.com/artifact/com.github.st-h/TarsosDSP -->
<dep...