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/";

音視頻開發問題建議可以發我郵件 [email protected]


本文來自電腦雜談,轉載請注明本文網址:
http://www.rtcsln.tw/a/bofangqi/article-128934-1.html

    相關閱讀
    發表評論  請自覺遵守互聯網相關的政策法規,嚴禁發布、暴力、反動的言論

    熱點圖片
    拼命載入中...
    黑龙江快乐十分开奖直播