Mp4提取aac音频

电脑杂谈  发布时间:2019-11-05 15:03:42  来源:网络整理

提取mp4中的音频_mp4文件提取音频_mp4文件提取音频

用到的API MediaExtractor MediaMuxer 放在子线程去做mp4文件提取音频,还要切记下手机兼容性(可以测试一下乐视的手机)

提取mp4中的音频_mp4文件提取音频_mp4文件提取音频

流程:从mp4中按照音频轨道的indexmp4文件提取音频,然后调用每一帧的数据起来,写入到文件

mp4文件提取音频_提取mp4中的音频_mp4文件提取音频

注意:1.手机兼容性,处理一下异常信息

mp4文件提取音频_提取mp4中的音频_mp4文件提取音频

2.写文件最终一帧也要处理一下

提取mp4中的音频_mp4文件提取音频_mp4文件提取音频

import android.media.MediaCodec;
import android.media.MediaExtractor;
import android.media.MediaFormat;
import android.media.MediaMuxer;
import android.os.Looper;
import java.io.File;
import java.io.IOException;
import java.nio.ByteBuffer;
import static android.media.MediaCodec.BUFFER_FLAG_END_OF_STREAM;
/**
 * Created by liugs on 2018/5/25.
 */
public class VideoMediaExtractorAac {
    private static final String AUDIO_MEDIA_TYPE = "audio/";
    private static final int BYTE_BUFFER_LENGTH = 2 * 1024 * 1024;
    private String videoPath;
    private String outputAacPath;
    private boolean isCanceled;
    private boolean isFinished;
    private MediaExtractor mediaExtractor;
    private MediaMuxer mediaMuxer;
    public VideoMediaExtractorAac() {
    }
    /**
     * 从视频文件中取出音频文件
     *
     * @param videoPath     输入视频路径
     * @param outputAacPath 输出音频路径
     * @return
     */
    public boolean getAacFile(String videoPath, String outputAacPath) {
        this.videoPath = videoPath;
        this.outputAacPath = outputAacPath;
        try {
            isFinished = run();
        } catch (IOException e) {
            e.printStackTrace();
            //失败就把任务取消吧!
            cancel();
            return isFinished;
        }
        return isFinished;
    }
    /**
     * 取消任务 并销毁所有资源
     *
     * @param canceled 控制参数 true 停止当前的任务,false 不停止当前的任务
     */
    public void cancel(boolean canceled) {
        isCanceled = canceled;
    }
    public boolean isCanceled() {
        return isCanceled;
    }
    public boolean isFinished() {
        return isFinished;
    }
    private boolean run() throws IOException {
        boolean checkWorkedChildThread = checkCurrentThreadIsChildThread();
        if (checkWorkedChildThread) {
            notifyError("You have to do this task in a subthread,for example user thread or Runnable");
            return false;
        }
        boolean fileExit = checkFileExit(videoPath);
        if (!fileExit) {
            notifyError("File not exist !");
            return false;
        }
        boolean isHaveAudio;
        mediaExtractor = new MediaExtractor();
        mediaExtractor.setDataSource(videoPath);
        if (mediaExtractor == null) {
            notifyError("mediaExtractor is null !");
            return false;
        }
        int audioTrackIndex = getMediaTrackIndex(mediaExtractor, AUDIO_MEDIA_TYPE);
        isHaveAudio = audioTrackIndex < 0;
        if (isHaveAudio) {
            notifyError("not find audio form video !");
            return false;
        }
        mediaExtractor.selectTrack(audioTrackIndex);
        MediaFormat audioFormat = mediaExtractor.getTrackFormat(audioTrackIndex);
        mediaMuxer = new MediaMuxer(outputAacPath, MediaMuxer.OutputFormat.MUXER_OUTPUT_MPEG_4);
        int audioIndex = mediaMuxer.addTrack(audioFormat);
        mediaMuxer.start();
        ByteBuffer audioBuffer = ByteBuffer.allocate(BYTE_BUFFER_LENGTH);
        boolean isAudioEnd = false;
        notifyPrepared();
        // init MediaExtractor MediaMuxer
        if (checkIsCanceled()) return false;
        while (true) {
            //working
            if (checkIsCanceled()) return false;
            int sampleSize = mediaExtractor.readSampleData(audioBuffer, 0);
            if (sampleSize <= 0) {
                isAudioEnd = true;
                MediaCodec.BufferInfo info = new MediaCodec.BufferInfo();
                info.offset = 0;
                info.size = 0;
                info.flags = BUFFER_FLAG_END_OF_STREAM;
                info.presentationTimeUs = 0;
                notifyWorking(info);
                mediaMuxer.writeSampleData(audioIndex, audioBuffer, info);
            } else {
                MediaCodec.BufferInfo info = new MediaCodec.BufferInfo();
                info.offset = 0;
                info.size = sampleSize;
                info.flags = mediaExtractor.getSampleFlags();
                info.presentationTimeUs = mediaExtractor.getSampleTime();
                notifyWorking(info);
                mediaMuxer.writeSampleData(audioIndex, audioBuffer, info);
            }
            if (isAudioEnd) {
                break;
            }
            mediaExtractor.advance();
        }
        release();
        isFinished = true;
        notifyCompletion();
        //工作结束
        return true;
    }
    private boolean checkCurrentThreadIsChildThread() {
        return Thread.currentThread() != Looper.getMainLooper().getThread();
    }
    private boolean checkIsCanceled() {
        if (isCanceled) {
            cancel();
            notifyError("the work is canceled !");
            return true;
        }
        return false;
    }
    private void cancel() {
        isCanceled = false;
        if (!isFinished) {
            release();
        }
        clearFile();
    }
    private void release() {
        try {
            if (mediaMuxer != null) {
                mediaMuxer.stop();
                mediaMuxer.release();
                mediaMuxer = null;
            }
            if (mediaExtractor != null) {
                mediaExtractor.release();
                mediaExtractor.release();
                mediaExtractor = null;
            }
        } catch (IllegalStateException e) {
            e.printStackTrace();
        }
    }
    private void clearFile() {
        File file = new File(outputAacPath);
        if (file.exists()) {
            file.deleteOnExit();
        }
    }
    private boolean checkFileExit(String filePath) {
        File file = new File(filePath);
        return file.exists();
    }
    private int getMediaTrackIndex(MediaExtractor videoExtractor, String mediaType) {
        int trackIndex = -1;
        for (int i = 0; i < videoExtractor.getTrackCount(); i++) {
            MediaFormat mediaFormat = videoExtractor.getTrackFormat(i);
            String mime = mediaFormat.getString(MediaFormat.KEY_MIME);
            if (mime.startsWith(mediaType)) {
                trackIndex = i;
                break;
            }
        }
        return trackIndex;
    }
    private OnWorkListener listener;
    public void setListener(OnWorkListener listener) {
        this.listener = listener;
    }
    private void notifyPrepared() {
        if (listener != null) {
            listener.onPrepared();
        }
    }
    private void notifyWorking(MediaCodec.BufferInfo info) {
        if (listener != null) {
            listener.onWorking(info.presentationTimeUs);
        }
    }
    private void notifyCompletion() {
        if (listener != null) {
            listener.onCompletion(videoPath, outputAacPath);
        }
    }
    private void notifyError(String errorStr) {
        if (listener != null) {
            listener.onError(errorStr);
        }
    }
    public interface OnWorkListener {
        void onPrepared();
        void onWorking(long presentationTimeUs);
        void onCompletion(String videoPath, String outPutAudioPath);
        void onError(String errorStr);
    }
}

同样,提取H264需要从视频轨道读取数据!

mediaType:
private static final String AUDIO_MEDIA_TYPE = "video/";

音视频开发问题建议可以发我邮件 liugstick@163.com


本文来自电脑杂谈,转载请注明本文网址:
https://www.pc-fly.com/a/bofangqi/article-128934-1.html

    相关阅读
      发表评论  请自觉遵守互联网相关的政策法规,严禁发布、暴力、反动的言论

      热点图片
      拼命载入中...