ijkplayer源码---setDataSource

我们要让ijk能够进行播放,必须设置播放路径。可以是本地的也可以是网络的。

我们在

IMediaPlayer

 接口中可以看到下面的接口

@TargetApi(14)
void setDataSource(Context var1, Uri var2, Map<String, String> var3) throws IOException, IllegalArgumentException, SecurityException, IllegalStateException;

void setDataSource(FileDescriptor var1) throws IOException, IllegalArgumentException, IllegalStateException;

void setDataSource(String var1) throws IOException, IllegalArgumentException, SecurityException, IllegalStateException;

我们分析setDataSource,

setDataSource的实现在

public final class IjkMediaPlayer extends AbstractMediaPlayer 
private String mDataSource;
public void setDataSource(String path) throws IOException, IllegalArgumentException, SecurityException, IllegalStateException {
    this.mDataSource = path;
    this._setDataSource(path, (String[])null, (String[])null);
}
private native void _setDataSource(String var1, String[] var2, String[] var3) throws IOException, IllegalArgumentException, SecurityException, IllegalStateException;
}

 

可以看到,调用后先对播放的路径进行了下保存,然后又调用了_setDataSource的native方法。

我们接下来看下_setDataSource的实现

#define JNI_CLASS_IJKPLAYER     "tv/danmaku/ijk/media/player/IjkMediaPlayer"
static JNINativeMethod g_methods[] = {
    {
        "_setDataSource",
        "(Ljava/lang/String;[Ljava/lang/String;[Ljava/lang/String;)V",
        (void *) IjkMediaPlayer_setDataSourceAndHeaders
    },
    }
    
    JNIEXPORT jint JNI_OnLoad(JavaVM *vm, void *reserved)
{
    JNIEnv* env = NULL;
 
 
    g_jvm = vm;
    if ((*vm)->GetEnv(vm, (void**) &env, JNI_VERSION_1_4) != JNI_OK) {
        return -1;
    }
    assert(env != NULL);
 
 
    pthread_mutex_init(&g_clazz.mutex, NULL );
 
 
    // FindClass returns LocalReference
    IJK_FIND_JAVA_CLASS(env, g_clazz.clazz, JNI_CLASS_IJKPLAYER);
    (*env)->RegisterNatives(env, g_clazz.clazz, g_methods, NELEM(g_methods) );
 
 
    ijkmp_global_init();
    ijkmp_global_set_inject_callback(inject_callback);
 
 
    FFmpegApi_global_init(env);
 
 
    return JNI_VERSION_1_4;
}

通过上面的代码我们可以知道_setDataSource对应的函数是IjkMediaPlayer_setDataSourceAndHeaders

我们下面分析下这个函数

static void
IjkMediaPlayer_setDataSourceAndHeaders(
    JNIEnv *env, jobject thiz, jstring path,
    jobjectArray keys, jobjectArray values)
{
    MPTRACE("%s\n", __func__);
    int retval = 0;
    const char *c_path = NULL;
    //获得IjkMediaPlayer
    IjkMediaPlayer *mp = jni_get_media_player(env, thiz);
    JNI_CHECK_GOTO(path, env, "java/lang/IllegalArgumentException", "mpjni: setDataSource: null path", LABEL_RETURN);
    JNI_CHECK_GOTO(mp, env, "java/lang/IllegalStateException", "mpjni: setDataSource: null mp", LABEL_RETURN);


    //转化成char*类型
    c_path = (*env)->GetStringUTFChars(env, path, NULL );
    JNI_CHECK_GOTO(c_path, env, "java/lang/OutOfMemoryError", "mpjni: setDataSource: path.string oom", LABEL_RETURN);


    ALOGV("setDataSource: path %s", c_path);
    //将path设置禁mp当中
    retval = ijkmp_set_data_source(mp, c_path);
    (*env)->ReleaseStringUTFChars(env, path, c_path);


    IJK_CHECK_MPRET_GOTO(retval, env, LABEL_RETURN);


LABEL_RETURN:
    ijkmp_dec_ref_p(&mp);
}

我们接下来看

int ijkmp_set_data_source(IjkMediaPlayer *mp, const char *url)
{
    assert(mp);
    assert(url);
    MPTRACE("ijkmp_set_data_source(url=\"%s\")\n", url);
    pthread_mutex_lock(&mp->mutex);
    int retval = ijkmp_set_data_source_l(mp, url);
    pthread_mutex_unlock(&mp->mutex);
    MPTRACE("ijkmp_set_data_source(url=\"%s\")=%d\n", url, retval);
    return retval;
}

static int ijkmp_set_data_source_l(IjkMediaPlayer *mp, const char *url)
{
    assert(mp);
    assert(url);


    // MPST_RET_IF_EQ(mp->mp_state, MP_STATE_IDLE);
    MPST_RET_IF_EQ(mp->mp_state, MP_STATE_INITIALIZED);
    MPST_RET_IF_EQ(mp->mp_state, MP_STATE_ASYNC_PREPARING);
    MPST_RET_IF_EQ(mp->mp_state, MP_STATE_PREPARED);
    MPST_RET_IF_EQ(mp->mp_state, MP_STATE_STARTED);
    MPST_RET_IF_EQ(mp->mp_state, MP_STATE_PAUSED);
    MPST_RET_IF_EQ(mp->mp_state, MP_STATE_COMPLETED);
    MPST_RET_IF_EQ(mp->mp_state, MP_STATE_STOPPED);
    MPST_RET_IF_EQ(mp->mp_state, MP_STATE_ERROR);
    MPST_RET_IF_EQ(mp->mp_state, MP_STATE_END);


    freep((void**)&mp->data_source);
    mp->data_source = strdup(url);
    if (!mp->data_source)
        return EIJK_OUT_OF_MEMORY;


    ijkmp_change_state_l(mp, MP_STATE_INITIALIZED);
    return 0;
}

mp->data_source = strdup(url);

struct IjkMediaPlayer {
    volatile int ref_count;
    pthread_mutex_t mutex;
    FFPlayer *ffplayer;
 
 
    int (*msg_loop)(void*);
    SDL_Thread *msg_thread;
    SDL_Thread _msg_thread;
 
 
    int mp_state;
    char *data_source;
    void *weak_thiz;
 
 
    int restart;
    int restart_from_beginning;
    int seek_req;
    long seek_msec;
};

IjkMediaPlayer设置了源地址data_source

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值