首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >安卓MediaMuxer音频问题

安卓MediaMuxer音频问题
EN

Stack Overflow用户
提问于 2014-10-17 21:22:48
回答 1查看 1.3K关注 0票数 2

我正在尝试使用MediaMuxer向视频中添加音轨。以下代码可以工作,但音频在视频中途停止。视频和音频文件都只有一首曲目。音频和视频的播放速度似乎都很好。音频文件比视频文件长,所以我不认为这是问题所在。我在这方面已经有一段时间了,现在想不通了。

代码语言:javascript
复制
private void createFinalVideo(){

    String outputFile = "";

     try {

        File file = new File(Environment.getExternalStorageDirectory() + File.separator + "final.mp4");
        file.createNewFile();
        outputFile = file.getAbsolutePath();

        MediaExtractor videoExtractor = new MediaExtractor();
        videoExtractor.setDataSource(OUTPUT);

        MediaExtractor audioExtractor = new MediaExtractor();
        final AssetFileDescriptor afd = context.getAssets().openFd("audio.m4a");
        audioExtractor.setDataSource(afd.getFileDescriptor(),afd.getStartOffset(),afd.getLength());

        Log.d(TAG, "Video Extractor Track Count " + videoExtractor.getTrackCount() );
        Log.d(TAG, "Audio Extractor Track Count " + audioExtractor.getTrackCount() );

        MediaMuxer muxer = new MediaMuxer(outputFile, MediaMuxer.OutputFormat.MUXER_OUTPUT_MPEG_4);

        videoExtractor.selectTrack(0);
        MediaFormat videoFormat = videoExtractor.getTrackFormat(0);
        int videoTrack = muxer.addTrack(videoFormat);

        audioExtractor.selectTrack(0);
        MediaFormat audioFormat = audioExtractor.getTrackFormat(0);
        int audioTrack = muxer.addTrack(audioFormat);

        Log.d(TAG, "Video Format " + videoFormat.toString() );
        Log.d(TAG, "Audio Format " + audioFormat.toString() );

        boolean sawEOS = false;
        int frameCount = 0;
        int offset = 100;
        int sampleSize = 256 * 1024;
        ByteBuffer videoBuf = ByteBuffer.allocate(sampleSize);
        ByteBuffer audioBuf = ByteBuffer.allocate(sampleSize);
        BufferInfo videoBufferInfo = new BufferInfo();
        BufferInfo audioBufferInfo = new BufferInfo();

        videoExtractor.seekTo(0, MediaExtractor.SEEK_TO_CLOSEST_SYNC);
        audioExtractor.seekTo(0, MediaExtractor.SEEK_TO_CLOSEST_SYNC);

        muxer.start();

        while (!sawEOS) 
        {
            videoBufferInfo.offset = offset;
            audioBufferInfo.offset = offset;

            videoBufferInfo.size = videoExtractor.readSampleData(videoBuf, offset);
            audioBufferInfo.size = audioExtractor.readSampleData(audioBuf, offset);

            if (videoBufferInfo.size < 0 || audioBufferInfo.size < 0) 
            {
                Log.d(TAG, "saw input EOS.");
                sawEOS = true;
                videoBufferInfo.size = 0;
                audioBufferInfo.size = 0;
            } 
            else 
            {
                videoBufferInfo.presentationTimeUs = videoExtractor.getSampleTime();
                videoBufferInfo.flags = videoExtractor.getSampleFlags();
                muxer.writeSampleData(videoTrack, videoBuf, videoBufferInfo);
                videoExtractor.advance();

                audioBufferInfo.presentationTimeUs = audioExtractor.getSampleTime();
                audioBufferInfo.flags = audioExtractor.getSampleFlags();
                muxer.writeSampleData(audioTrack, audioBuf, audioBufferInfo);
                audioExtractor.advance();

                frameCount++;

                Log.d(TAG, "Frame (" + frameCount + ") Video PresentationTimeUs:" + videoBufferInfo.presentationTimeUs +" Flags:" + videoBufferInfo.flags +" Size(KB) " + videoBufferInfo.size / 1024);
                Log.d(TAG, "Frame (" + frameCount + ") Audio PresentationTimeUs:" + audioBufferInfo.presentationTimeUs +" Flags:" + audioBufferInfo.flags +" Size(KB) " + audioBufferInfo.size / 1024);

            }
        }
        muxer.stop();
        muxer.release();


     } catch (IOException e) {
         Log.d(TAG, "Mixer Error 1 " + e.getMessage());
     } catch (Exception e) {
         Log.d(TAG, "Mixer Error 2 " + e.getMessage());
     }

    return;
}

打印出来的媒体格式如下

代码语言:javascript
复制
Video Format {max-input-size=1572864, frame-rate=28, height=1920, csd-0=java.nio.ByteArrayBuffer[position=0,limit=18,capacity=18], width=1072, durationUs=2968688, csd-1=java.nio.ByteArrayBuffer[position=0,limit=8,capacity=8], mime=video/avc, isDMCMMExtractor=1}

Audio Format {max-input-size=1572864, encoder-padding=708, aac-profile=2, csd-0=java.nio.ByteArrayBuffer[position=0,limit=2,capacity=2], sample-rate=44100, durationUs=19783401, channel-count=2, encoder-delay=2112, mime=audio/mp4a-latm, isDMCMMExtractor=1}

任何指导都将不胜感激。

谢谢

EN

回答 1

Stack Overflow用户

发布于 2018-08-17 16:59:36

user346443:问题是视频提取器比音频提取器更快地提取数据。将音频和视频拆分为单独的循环修复了此问题。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/26426009

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档