Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

请教一下大神,ijkplayer播放本地视频,如何切换声道? #3964

Open
lm3515 opened this issue Jan 25, 2018 · 6 comments
Open

Comments

@lm3515
Copy link

lm3515 commented Jan 25, 2018

最近有个需求通过切换视频的声道来实现原唱伴唱模式,声道这一块不是很清楚,希望有大神来指点下,非常感谢!

@lm3515
Copy link
Author

lm3515 commented Jan 31, 2018

已解决,还是谢谢各位大神

@xksds
Copy link

xksds commented Jan 31, 2018

@lm3515 你切换的实时性好吗,能达到KTV的那种速度吗?

@401885064
Copy link

@lm3515 兄弟 你是怎么解决的? 调用什么方法吗?

@lm3515
Copy link
Author

lm3515 commented Mar 9, 2018

@401885064 通过更改framework层来实现的

@lm3515
Copy link
Author

lm3515 commented Mar 9, 2018

@xksds 性能很不错,让系统工程师更改了framework层来实现的

@lm3515
Copy link
Author

lm3515 commented Oct 19, 2021

ijkplayer-track

文件地址:https://github.com/lm3515/ijkplayer-track.git

通过ijkplayer实现切换音轨,适用于ios、android
4个文件为核心代码在ijkmedia/ijkplayer中实现

首先在ijkplayer.h中添加两个方法:

/* 获取音轨信息 */

int ijkmp_get_audio_track(IjkMediaPlayer *mp);

void ijkmp_switch_audio_track(IjkMediaPlayer *mp, int tracksNum, int index);

ijkplayer.c方法实现:

/*  -- 音轨信息----  */
int ijkmp_get_audio_track(IjkMediaPlayer *mp)
{
    assert(mp);
    pthread_mutex_lock(&mp->mutex);
    int ret = ffp_get_track_info_l(mp->ffplayer);
    pthread_mutex_unlock(&mp->mutex);
    
    return ret;
}

// 切换音轨
void ijkmp_switch_audio_track(IjkMediaPlayer *mp, int tracksNum, int index)
{
    assert(mp);
    pthread_mutex_lock(&mp->mutex);
    ffp_select_track_l(mp->ffplayer, tracksNum, index);
    pthread_mutex_unlock(&mp->mutex);
}

ff_ffplay.h中添加两个方法:

// 获取音轨信息
int ffp_get_track_info_l(FFPlayer *ffp);
void ffp_select_track_l(FFPlayer *ffp, int tracksNum, int index);

ff_ffplay.c实现:

/* 音轨信息 */
//获取音轨信息
int ffp_get_track_info_l(FFPlayer *ffp)
{
    if (!ffp)
        return 0;
    
    assert(ffp);
    VideoState *is = ffp->is;
    int total = 0;
    if (!is)
        return EIJK_NULL_IS_PTR;
    
    AVFormatContext *ic = is->ic;
    int stream_index;
    AVStream *st;
    int codec_type = AVMEDIA_TYPE_AUDIO;
    
    for (stream_index = 0; stream_index < is->ic->nb_streams; stream_index++)
    {
        st = ic->streams[stream_index];
        if (st->codecpar->codec_type == codec_type) {
            /* check that parameters are OK */
            switch(codec_type) {
                case AVMEDIA_TYPE_AUDIO:
                    if (st->codecpar->sample_rate != 0 && st->codecpar->channels != 0)
                        total++;
                    break;
            }
        }
    }
    
    return total;
}


void ffp_select_track_l(FFPlayer *ffp, int tracksNum, int index) {
    if (!ffp)
        return;
    
    assert(ffp);
    VideoState *is = ffp->is;
    int total = 0;
    if (!is)
        return;
    
    AVFormatContext *ic = is->ic;
    int start_index = 0, stream_index = 0;
    AVStream *st;
    int codec_type = AVMEDIA_TYPE_AUDIO;
    
    if (codec_type == AVMEDIA_TYPE_VIDEO)
        start_index = is->video_stream;
    else if (codec_type == AVMEDIA_TYPE_AUDIO)
        start_index = is->audio_stream;
    /*else
     start_index = is->subtitle_stream;
     if (start_index < (codec_type == AVMEDIA_TYPE_SUBTITLE ? -1 : 0))
     return;*/
    
    for (stream_index = 0; stream_index < is->ic->nb_streams; stream_index++)
    {
        st = ic->streams[stream_index];
        if (st->codecpar->codec_type == codec_type) {
            /* check that parameters are OK */
            switch (codec_type) {
                case AVMEDIA_TYPE_AUDIO:
                    if (st->codecpar->sample_rate != 0 && st->codecpar->channels != 0)
                        total++;
                    if (total == index)
                        //跳出循环
                        goto the_end;
                    break;
            }
        }
    }
    
    return;
    
the_end:
    stream_component_close(ffp, start_index);
    //传递两个参数tracksNum:音轨的个数,stream_index:第几个音轨
    ffp_set_stream_selected(ffp, tracksNum, stream_index);
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants