• 开源播放器 ijkplayer (二) :ijkplayer倍速变调问题解决方案


    转载注明出处:http://www.cnblogs.com/renhui/p/6510872.html

    之前使用IjkPlayer做播放器的使用的时候,在做倍速播放的时候,发现播放的声音音调明显变高了。问题的详情参见/ijkplayer#2930#2785等。

    在解决问题之前首先对倍速的代码做一次追踪

    a. Android应用中Java层面调用的代码:

    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);
    }
    倍速代码

    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, float value)
    {
        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, float value)
    {
        switch (id) {
            case FFP_PROP_FLOAT_PLAYBACK_RATE:
                ffp_set_playback_rate(ffp, value);
                break;
            case FFP_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, 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代码了,也可以,只不过,不管设置多少,都为变速不变调的状态了。

  • 相关阅读:
    python3爬虫例子01(获取个人博客园的粉丝)
    python3基础10(操作日志)
    vmlinux,zImage 和 uImage
    zynq tcf-agent debug Linux application
    Vim 打开二进制文件,让它不自动加最后的换行符 0a
    pip 设置代理
    Linux 设置代理
    一个简单的备份方案 (Linux Server to Windows Server)
    解 RPM 归档的方法
    ZYNQ 从 QSPI-Flash 启动,更新 EMMC image
  • 原文地址:https://www.cnblogs.com/renhui/p/6510872.html
Copyright © 2020-2023  润新知