title: android - How to mux audio file and video file?
body: <p>i have a 3gp file that is recorded from the microphone and a mp4 video file.
  i want to mux audio file and video file in to a mp4 file and save it.
  i searched a lot but didn't find any thing helpful for using MediaMuxer api of android.
  <a href="http://developer.android.com/reference/android/media/MediaMuxer.html" rel="noreferrer">MediaMuxer api</a></p>
  
  <p>UPDATE : this is my method that mux two files , i have an Exception in it.
  and the reason is that the destination mp4 file doesn't have any track!
  can someOne help me with adding audio and video track to muxer??</p>
  
  <p>Exception </p>
  
  <pre><code>java.lang.IllegalStateException: Failed to stop the muxer
  </code></pre>
  
  <p>my code:</p>
  
  <pre><code>private void cloneMediaUsingMuxer( String dstMediaPath) throws IOException {
      // Set up MediaExtractor to read from the source.
      MediaExtractor soundExtractor = new MediaExtractor();
      soundExtractor.setDataSource(audioFilePath);
      MediaExtractor videoExtractor = new MediaExtractor();
      AssetFileDescriptor afd2 = getAssets().openFd("Produce.MP4");
      videoExtractor.setDataSource(afd2.getFileDescriptor() , afd2.getStartOffset(),afd2.getLength());
  
  
      //PATH
      //extractor.setDataSource();
      int trackCount = soundExtractor.getTrackCount();
      int trackCount2 = soundExtractor.getTrackCount();
  
      //assertEquals("wrong number of tracks", expectedTrackCount, trackCount);
      // Set up MediaMuxer for the destination.
      MediaMuxer muxer;
      muxer = new MediaMuxer(dstMediaPath, MediaMuxer.OutputFormat.MUXER_OUTPUT_MPEG_4);
      // Set up the tracks.
      HashMap&lt;Integer, Integer&gt; indexMap = new HashMap&lt;Integer, Integer&gt;(trackCount);
      for (int i = 0; i &lt; trackCount; i++) {
          soundExtractor.selectTrack(i);
          MediaFormat SoundFormat = soundExtractor.getTrackFormat(i);
          int dstIndex = muxer.addTrack(SoundFormat);
          indexMap.put(i, dstIndex);
      }
  
      HashMap&lt;Integer, Integer&gt; indexMap2 = new HashMap&lt;Integer, Integer&gt;(trackCount2);
      for (int i = 0; i &lt; trackCount2; i++) {
          videoExtractor.selectTrack(i);
          MediaFormat videoFormat = videoExtractor.getTrackFormat(i);
          int dstIndex2 = muxer.addTrack(videoFormat);
          indexMap.put(i, dstIndex2);
      }
  
  
      // Copy the samples from MediaExtractor to MediaMuxer.
      boolean sawEOS = false;
      int bufferSize = MAX_SAMPLE_SIZE;
      int frameCount = 0;
      int offset = 100;
      ByteBuffer dstBuf = ByteBuffer.allocate(bufferSize);
      MediaCodec.BufferInfo bufferInfo = new MediaCodec.BufferInfo();
      MediaCodec.BufferInfo bufferInfo2 = new MediaCodec.BufferInfo();
  
      muxer.start();
      while (!sawEOS) {
          bufferInfo.offset = offset;
          bufferInfo.size = soundExtractor.readSampleData(dstBuf, offset);
          bufferInfo2.offset = offset;
          bufferInfo2.size = videoExtractor.readSampleData(dstBuf, offset);
  
          if (bufferInfo.size &lt; 0) {
              sawEOS = true;
              bufferInfo.size = 0;
              bufferInfo2.size = 0;
          }else if(bufferInfo2.size &lt; 0){
              sawEOS = true;
              bufferInfo.size = 0;
              bufferInfo2.size = 0;
          }
          else {
              bufferInfo.presentationTimeUs = soundExtractor.getSampleTime();
              bufferInfo2.presentationTimeUs = videoExtractor.getSampleTime();
              //bufferInfo.flags = extractor.getSampleFlags();
              int trackIndex = soundExtractor.getSampleTrackIndex();
              int trackIndex2 = videoExtractor.getSampleTrackIndex();
              muxer.writeSampleData(indexMap.get(trackIndex), dstBuf,
                      bufferInfo);
  
              soundExtractor.advance();
              videoExtractor.advance();
              frameCount++;
  
          }
      }
  
      Toast.makeText(getApplicationContext(),"f:"+frameCount,Toast.LENGTH_SHORT).show();
  
      muxer.stop();
      muxer.release();
  
  }
  </code></pre>
  
  <p><strong>UPDATE 2: problem solved! check my answer to my question.</strong></p>
  
  <p>thanks for your help</p>