FFMPEG 解码音频

本文旨在通过FFMPEG库实现音频码流的解码,转化为PCM采样数据,并利用AudioTrack在Java端播放。主要步骤包括注册组件、打开文件、查找流信息、解码和转换为PCM,最后将解码后的音频数据写入AudioTrack进行播放。
摘要由CSDN通过智能技术生成

目的

通过FFMPEG解码音频的码流,得到PCM的音频采样数据并用AudioTraker播放

步骤

1.注册所有组件

av_register_all();

2.拿到封装格式上下文

AVFormatContext *avFormatContext = avformat_alloc_context();

3 打开文件

    if (avformat_open_input(&avFormatContext, src_cstr, NULL, NULL) < 0) {
        LOGE("%s", "打开文件失败");
        return; 
    }

4.查找流信息

avformat_find_stream_info(avFormatContext, NULL)

5.拿到解码器

avcodec_find_decoder(avCodecCtx->codec_id)

6.打开解码器

avcodec_open2(avCodecCtx, aVCodec, NULL)

7.读取一帧一帧的压缩音频数据

av_read_frame(avFormatContext, aVPacket)

8.开始解码

vcodec_decode_audio4(avCodecCtx, aVFrame, &got_frame_ptr,aVPacket)

9.解码得到的Frame数据,转成PCM

swr_convert(swrCtx, &outBuffer, MAX_AUDIO_FRME_SIZE,
aVFrame->data, aVFrame->nb_samples)

10.调用java端的方法,获取到AudioTraker对象

//java代码
public AudioTrack createAudio() {

    int sampleRateInHz = 44100;
    int channelConfig = AudioFormat.CHANNEL_OUT_STEREO;
    int audioFormat = AudioFormat.ENCODING_PCM_16BIT;
    int minBufferSize = AudioTrack.getMinBufferSize(sampleRateInHz,
            channelConfig, audioFormat);

    AudioTrack audio = new AudioTrack(AudioManager.STREAM_MUSIC, // 指定流的类型
            sampleRateInHz, // 设置音频数据的采样率 32k,如果是44.1k就是44100
            channelConfig, // 设置输出声道为双声道立体声,而CHANNEL_OUT_MONO类型是单声道
            audioFormat, // 设置音频数据块是8位还是16位,这里设置为16位。好像现在绝大多数的音频都是16位的了
            minBufferSize, AudioTrack.MODE_STREAM // 设置模式类型,在这里设置为流类型,另外一种MODE_STATIC貌似没有什么效果
    );
    // audio.play(); // 启动音频设备,下面就可以真正开始音频数据的播放了
    return audio;
}

// jni调用createAudio
jclass player_class = (*env)->GetObjectClass(env, jthis);
jmethodID createAudioMId = (*env)->GetMethodID(env, player_class,
        "createAudio", "()Landroid/media/AudioTrack;");

//JNIEnv*, jobject, jmethodID, ...
jobject audioTraker = (*env)->CallObjectMethod(env, jthis, createAudioMId);

11.调用AudioTrack.paly(),write()播放解码后的音频数据

javap反编译可以得到方法签名

// 调用play
jclass audio_class = (*env)->GetObjectClass(env, audioTraker);
jmethodID playMId = (*env)->GetMethodID(env, audio_class, "play", "()V");
(*env)->CallVoidMethod(env, audioTraker, playMId);
jmethodID writeMId = (*env)->GetMethodID(env, aud
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值