MediaCodec实现(不改格式)精致转码

此文仅用于学习MediaCodec及相关类很实用。

基于上一个文章   https://blog.csdn.net/h2948203216/article/details/103695128

花了一个半月进行修改,可以说很难找到毛病了,当然也不是自夸,主要是被导师逼着一直改这一个demo,一段时间后,想放弃也不想放弃,就干脆仔仔细细写下去了。

没有再沿用上篇转码的代码了,而是升级了新的方式,将decoder到encoder的这一个过程和encode,mux放在一个线程里,那么思路就变成了,read  & write,可谓简洁明了,而且read可以一直下去,write也可以一直下去,不用担心需要裁剪一段就要塞EOF指令阻塞编解码器。

之前的思路比较局限,考虑不周,将PST(播放时间戳)的计算放在了encode那里,结果就导致了,因为线程不同的原因,没办法精准控制,因为timeA/V要每段控制,startTime要每段控制,后者要保证当以视频帧为基准时,音频线程必须慢于视频线程才能保证startTime准确,反之视频比音频慢也是如此。而前者timeA/V控制就需要保证知道每段encode结束后的计算,那么只能通过塞EOF阻塞编解码器来达成目的。所以每段结束都需要重置codec,即类似于initxxxCodec()。

而新的思路就是read一直下去,write一直下去,直到最后一个TailTimer给出,当读完时再给出EOF指令阻塞编解码器。

话不多说,给出代码

public class TransCodeWrapper1 {

    private static final String TAG = TransCodeWrapper1.class.getName();
    private static final int AV_GAP = 500000; // 500MS

    private Thread inputLoop, outputLoop;
    private List<TailTimer> fileList;
    private AssetFileDescriptor srcFilePath;
    private String dstFilePath;
    private long startTime = 0;
    private long endTime = 0;
    private long TIMEUS = 70000L;

    private MediaExtractor audioExtractor, videoExtractor;
    private int audioTrackIndex = -1;
    private int videoTrackIndex = -1;
    private int videoIndex = -1;
    private int audioIndex = -1;
    private MediaCodec audioDecoder, audioEncoder;
    private MediaCodec videoDecoder, videoEncoder;
    private MediaMuxer mediaMuxer;

    private long audioEncoderInputTimestamp = 0, videoEncoderInputTimestamp = 0;
    private long audioReadTimestamp, videoReadTimestamp;

    private int width,height,bitRate,frameRate;
    private int iframeInterval = 1;
    private int sampleRate,audioBitRate,channelCount;
    private String audioFormatType,videoFormatType;
    private boolean pauseTime = false;
    private boolean isMuxerStarted = false;
    private long gapaA = 0;
    private long gapaV = 0;
    private long gapbA = 0;
    private long gapbV = 0;
    public TransCodeWrapper1(String dstFilePath , List<TailTimer> fileList) throws IOException{
        this.dstFilePath = dstFilePath;
        this.fileList = fileList;
        initExtractor();
        initAudioCodec();
        initVideoCodec();
        initMuxer();

        inputLoop = new Thread(new Runnable() {
            @Override
            public void run() {
                inputLoopInterface();
                while(!pauseTime){
                    try {
                        Thread.sleep(0L);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                audioExtractor.release();
                videoExtractor.release();
                Log.v(TAG , "extractor released");
                audioDecoder.stop();
                audioDecoder.release();
                Log.v(TAG,"released audioDecode");
                videoDecoder.stop();
                videoDecoder.release();
                Log.v(TAG,"released videoDecode");


            }
        });

        outputLoop = new Thread(new Runnable() {
            @Override
            public void run() {
                outputLoopInterface();
                audioEncoder.stop();
                videoEncoder.stop();
                audioEncoder.release();
                videoEncoder.release();
                mediaMuxer.stop();
                mediaMuxer.release();
                Log.v(TAG,"released mediaMuxer");
            }
        });
    }

    public int startTranscode() {
        inputLoop.start();
        outputLoop.start();
        return 0;
    }

    public int stop() {
        return 0;
    }

    private int initExtractor() throws IOException{
        if (videoExtractor == null){
            videoExtractor = new MediaExtractor();
        }
        if (audioExtractor == null){
            audioExtractor = new MediaExtractor();
        }
        videoExtractor.setDataSource(fileList.get(0).getSrcPath());
        audioExtractor.setDataSource(fileList.get(0).getSrcPath());
        for (int i = 0; i < videoExtra
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值