title: How to merge audio and video using MediaMuxer?
body: <p>I'm developing an Android App with mp3 audio file and mp4 video file with(no sound).</p>
  
  <p>Now I want to mix them and create a new mp4 video file(with sound). From Android 4.3, Google suggests using the MediaMuxer class to mix stream audio and video. I have tried many times without success.</p>
  
  <p>Here is the code:</p>
  
  <pre><code>    private void muxing() {
  
      String outputFile = "";
  
      try {
  
          File file = new File(Environment.getExternalStorageDirectory() + "/final2.mp4");
          file.createNewFile();
          outputFile = file.getAbsolutePath();
          MediaExtractor videoExtractor = new MediaExtractor();
          videoExtractor.setDataSource(Environment.getExternalStorageDirectory().toString()+"/vd1.h264");
          MediaExtractor audioExtractor = new MediaExtractor();
          audioExtractor.setDataSource(Environment.getExternalStorageDirectory()+"/audioVideoDir/audio.m4a");
          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);
          boolean sawEOS = false;
          int frameCount = 0;
          int offset = 100;
          int sampleSize = 256 * 1024;
          ByteBuffer videoBuf = ByteBuffer.allocate(sampleSize);
          ByteBuffer audioBuf = ByteBuffer.allocate(sampleSize);
          MediaCodec.BufferInfo videoBufferInfo = new MediaCodec.BufferInfo();
          MediaCodec.BufferInfo audioBufferInfo = new MediaCodec.BufferInfo();
  
  
          videoExtractor.seekTo(0, MediaExtractor.SEEK_TO_CLOSEST_SYNC);
          audioExtractor.seekTo(0, MediaExtractor.SEEK_TO_CLOSEST_SYNC);
  
          muxer.start();
  
          while (!sawEOS)
          {
              videoBufferInfo.offset = offset;
              videoBufferInfo.size = videoExtractor.readSampleData(videoBuf, offset);
  
  
              if (videoBufferInfo.size &lt; 0 || audioBufferInfo.size &lt; 0)
              {
                 // Log.d(TAG, "saw input EOS.");
                  sawEOS = true;
                  videoBufferInfo.size = 0;
  
              }
              else
              {
                  videoBufferInfo.presentationTimeUs = videoExtractor.getSampleTime();
                  videoBufferInfo.flags = videoExtractor.getSampleFlags();
                  muxer.writeSampleData(videoTrack, videoBuf, videoBufferInfo);
                  videoExtractor.advance();
  
  
                  frameCount++;
  
              }
          }
  
          Toast.makeText(getApplicationContext() , "frame:" + frameCount , Toast.LENGTH_SHORT).show();
  
  
  
          boolean sawEOS2 = false;
          int frameCount2 =0;
          while (!sawEOS2)
          {
              frameCount2++;
  
              audioBufferInfo.offset = offset;
              audioBufferInfo.size = audioExtractor.readSampleData(audioBuf, offset);
  
              if (videoBufferInfo.size &lt; 0 || audioBufferInfo.size &lt; 0)
              {
                //  Log.d(TAG, "saw input EOS.");
                  sawEOS2 = true;
                  audioBufferInfo.size = 0;
              }
              else
              {
                  audioBufferInfo.presentationTimeUs = audioExtractor.getSampleTime();
                  audioBufferInfo.flags = audioExtractor.getSampleFlags();
                  muxer.writeSampleData(audioTrack, audioBuf, audioBufferInfo);
                  audioExtractor.advance();
  
              }
          }
  
          Toast.makeText(getApplicationContext() , "frame:" + frameCount2 , Toast.LENGTH_SHORT).show();
  
          muxer.stop();
          muxer.release();
  
  
      } catch (IOException e) {
  
      } catch (Exception e) {
  
      }
  }
  </code></pre>
  
  <p>I get the below error:</p>
  
  <p><strong>Unknown mime type 'audio/mpeg'. 12-09 11:58:33.569: A/MPEG4Writer(332): frameworks/av/media/libstagefright/MPEG4Writer.cpp:2699 CHECK(!"should not be here, unknown mime type.")</strong> </p>
  
  <p>Any solution to resolve my issue with MediaMuxer API from Google? Even i tried with ffmpeg after merging of audio and video together video doesn't plays in default video player of android device but it loads in Vlc player.</p>
  
  <p><strong>FFMPEG</strong> followed from here:<a href="https://github.com/WritingMinds/ffmpeg-android-java" rel="noreferrer">https://github.com/WritingMinds/ffmpeg-android-java</a></p>