栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

音视频5.2——MediaCodec 异步方式完成AAC硬解成PCM

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

音视频5.2——MediaCodec 异步方式完成AAC硬解成PCM

 音视频开发路线:

Android 音视频开发入门指南_Jhuster的专栏的技术博客_51CTO博客_android 音视频开发入门

demo地址:

GitHub - wygsqsj/videoPath: 音视频学习路线demo

MediaCodec异步方式

上一节使用同步方式使用MediaCodec总感觉比较麻烦,我们java中使用大量的回调来实现监听者模式,MediaCodec在sdk 19版本后也通过回调来告知使用者,input或者output已经准备好的情况,具体的api就是为MediaCodec设置CallBack,并实现其中的四个方法:

decodeCodec.setCallback(new MediaCodec.Callback() {
    @Override
    public void onInputBufferAvailable(@NonNull MediaCodec codec, int index) {
        Log.i(LOG_TAG, "input数据已准备好,当前index:" + index);
    }

    @Override
    public void onOutputBufferAvailable(@NonNull MediaCodec codec, int index, @NonNull MediaCodec.BufferInfo info) {
         Log.i(LOG_TAG, "outPut数据已准备好,当前index:" + index);
    }

    @Override
    public void onError(@NonNull MediaCodec codec, @NonNull MediaCodec.CodecException e) {
        Log.i(LOG_TAG, "编解码出错 onError" + e.toString());
    }

    @Override
    public void onOutputFormatChanged(@NonNull MediaCodec codec, @NonNull MediaFormat format) {
        Log.i(LOG_TAG, "format发生更改,onOutputFormatChanged" + format.toString());

    }
});
注意点:
  • 先设置callBack,再设置config
  • callBack回调发生再主线程,需要自己手动切换
使用

具体的使用流程跟上一节其实是一样的,就是while循环中手动获取现在改为回调通知了,切换线程我是通过在子线程中构建Handler,收到回调之后再通过Handler把消息发出去,回调的信息通过一个队列去记录一下,具体的代码如下:

package com.wish.videopath.demo5;

import android.content.Context;
import android.media.MediaCodec;
import android.media.MediaExtractor;
import android.media.MediaFormat;
import android.os.Build;
import android.os.Environment;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Looper;
import android.os.Message;
import android.util.Log;

import com.wish.videopath.R;

import org.jetbrains.annotations.NotNull;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.Queue;
import java.util.concurrent.linkedBlockingQueue;

import androidx.annotation.NonNull;
import androidx.annotation.RequiresApi;

import static com.wish.videopath.MainActivity.LOG_TAG;

public class DecodeAACAsyn extends Thread {

    private Context context;
    private MediaFormat audioFormat;
    private File pcmFile;
    private FileOutputStream fos = null;

    private MediaCodec decodeCodec = null;
    private Queue mOutDataQueue = new linkedBlockingQueue<>();
    private Queue mInputDataQueue = new linkedBlockingQueue<>();

    private MediaExtractor audioExtractor = new MediaExtractor();

    private Handler mHandler;

    private Runnable outRunnable = () -> {
        try {
            Log.e(LOG_TAG, "outRunnable,当前线程: " + Thread.currentThread().getName());
            byte[] pcmData = mOutDataQueue.poll();
            if (pcmData == null) {
                return;
            }
            Log.e(LOG_TAG, "Handler回调收到,当前数据大小:" + pcmData.length);
            //装车
            fos.write(pcmData);//数据写入文件中
            fos.flush();
        } catch (Exception e) {
            e.printStackTrace();
        }
    };

    private Runnable inputRunnable = () -> {
        try {
            Log.e(LOG_TAG, "inputRunnable,当前线程: " + Thread.currentThread().getName());

            Integer index = mInputDataQueue.poll();
            if (index == null) {
                return;
            }

            ByteBuffer buffer;
            if (Build.VE

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/358103.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号