美文网首页
Android 直播音频播放 Opensl+ffmpeg

Android 直播音频播放 Opensl+ffmpeg

作者: SuperTypeMen | 来源:发表于2020-04-17 12:02 被阅读0次

opensl的一般套路就不说了,网上都有,今天着重说一下callback调用的问题
先说一下opensl调用callback的原理:只有上一次callback时添加了数据才会自动会去调用下一次的callback,如果上一次callback没有获取到数据,那么就不会调用下一次callback,播放就会中断。
如果是播放录制好的音频文件是非常简单的,因为音频文件是连续不断的,opensl在初始化完成后直接手动调用一次callback开始获取音频解码文件,然后就会连续不断的调用callback,直至文件播放完。
如下

void Audio::pcmBufferCallBack1() {
    //int buffersize = audio->reSampleAudio();
    if(playstatus->exit)
        return;
    int buffersize = audio_buffer_fill(buffer, 48000 * 2 * 2);
    clock += buffersize / ((double) (sampleRate * 2 * 2));
    if (buffersize > 0) {
        (*pcmBufferQueue)->Enqueue(pcmBufferQueue, (char *) buffer,buffersize);
    }
}

但是如果是做直播类似的情况要播放实时音频流,情况就不一样了,因为音频是断断续续的,所以在没有音频数据后callback会自动断掉,然后在有新的音频数据来到的时候去手动调用callback。
我这边的例子是rtsp直播播放的音频,音频来了之后放入queue队列中,然后callback的时候会从queue中取数据解码播放

static void
play_audio(unsigned char *buffer, int bufsize, struct timeval pts) {
    ga_log("play_audio");
    if (!isAudioCom) {
        isAudioCom = true;
    }
    if (isVideoCom && isAudioCom) {
        AVPacket avpkt;
        av_init_packet(&avpkt);
        avpkt.data = buffer;
        avpkt.size = bufsize;
        if (avpkt.size > 0) {
            packet_queue_put(&audioq, &avpkt);
            packet_queue_drop(&audioq);
            pcount++;
            if (pcount == 1) {
                audio->pcmBufferCallBack1();
            }
        }
    }
    return;
}

没有音频数据的时候queue是空的,callback肯定获取不到数据,所以我的策略是在有新的音频数据包来的时候手动调用callback

相关文章

网友评论

      本文标题:Android 直播音频播放 Opensl+ffmpeg

      本文链接:https://www.haomeiwen.com/subject/jpsevhtx.html