2016-12-07 366 views
1

我正在錄製音頻,然後嘗試合併aac音頻和mp4視頻文件(靜音,無音頻),並共享合併的mp4文件。合併後的mp4文件共享在Samsung J2和Xiaomi中可用,但mp4文件在Lenovo,Micromax和其他手機中無法播放。測試結果在此處提及: https://docs.google.com/spreadsheets/d/1eeJEM-v-smEUzY-bSxwIwFVOsAbv6KT2u3Kz3jdOb8o/edit?usp=sharing 我無法理解問題是由於共享或到期不適當的混合以及問題的原因是什麼。請幫忙。分享Android合併mp4和aac文件使用mediamuxer mediacodec和mediaextractor(沒有mp4parser)

代碼存在於recordAudio.java和是這樣的:

public void shareVroom(View view) { 
// Toast.makeText(this, "Share feature is temporarily disabled", android.widget.Toast.LENGTH_LONG).show(); 

// Toast.makeText(this, "Share feature is enabled", android.widget.Toast.LENGTH_LONG).show(); 
     // Code commented for UAT 

     try { 
      MediaMultiplexer mediaMultiplexer = new MediaMultiplexer(); 
      mediaMultiplexer.startMuxing(this); 

      Toast.makeText(this, "in share",Toast.LENGTH_SHORT).show(); 
      String shareableFileName = ""; 

      Intent intentShareFile = new Intent(Intent.ACTION_SEND); 
      shareableFileName = Environment.getExternalStorageDirectory().getAbsolutePath(); 
      shareableFileName += getString(R.string.vroom_video_output_file_name); 
      File fileWithinMyDir = new File(shareableFileName); 
      Uri videoUri=Uri.parse(shareableFileName); 
      if (fileWithinMyDir.exists()) { 
       intentShareFile.setType("video/mp4"); 
       intentShareFile.putExtra(Intent.EXTRA_STREAM, videoUri); 
       intentShareFile.putExtra(Intent.EXTRA_SUBJECT, "Listen to my VROOM"); 
       intentShareFile.putExtra(Intent.EXTRA_TEXT, "Vroom attached"); 
       startActivity(Intent.createChooser(intentShareFile, "Share your Vroom with")); 
      } 

     } catch (IllegalStateException e) { 
      e.printStackTrace(); 
      Log.e("tag", e.getMessage(), e); 
      Toast.makeText(this, "could not shared"+e.getMessage(),Toast.LENGTH_SHORT).show(); 
     } 


     //TODO:Use event to identify if muxing is done 

    } 

代碼複用:

public class MediaMultiplexer { 
    private static final int MAX_SAMPLE_SIZE = 256 * 1024; 

    public void startMuxing(Context context) { 
     MediaMuxer muxer = null; 
     MediaFormat VideoFormat = null; 
     Resources mResources = context.getResources(); 
     int sourceVideo = R.raw.vid; 
     String outputVideoFileName = Environment.getExternalStorageDirectory().getAbsolutePath(); 
     outputVideoFileName += context.getString(R.string.vroom_video_output_file_name); 
     try { 
      muxer = new MediaMuxer(outputVideoFileName, MediaMuxer.OutputFormat.MUXER_OUTPUT_MPEG_4); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
     MediaExtractor extractorVideo = new MediaExtractor(); 
     try { 
      AssetFileDescriptor srcVideoFd = mResources.openRawResourceFd(sourceVideo); 
      extractorVideo.setDataSource(srcVideoFd.getFileDescriptor(), srcVideoFd.getStartOffset(), srcVideoFd.getLength()); 
      int tracks = extractorVideo.getTrackCount(); 
      for (int i = 0; i < tracks; i++) { 
       MediaFormat mf = extractorVideo.getTrackFormat(i); 
       String mime = mf.getString(MediaFormat.KEY_MIME); 
       if (mime.startsWith("video/")) { 
        extractorVideo.selectTrack(i); 
        VideoFormat = extractorVideo.getTrackFormat(i); 
        break; 
       } 
      } 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 

     MediaExtractor extractorAudio = new MediaExtractor(); 
     try { 
      String audioFileName = Environment.getExternalStorageDirectory().getAbsolutePath(); 
      audioFileName += context.getString(R.string.vroom_audio_file_name); 
      extractorAudio.setDataSource(audioFileName); 
      int tracks = extractorAudio.getTrackCount(); 
//   Toast.makeText(context, "No of tracks::::" + String.valueOf(tracks), Toast.LENGTH_SHORT).show(); 
      extractorAudio.selectTrack(0); 

      MediaFormat AudioFormat = extractorAudio.getTrackFormat(0); 
      int audioTrackIndex = muxer.addTrack(AudioFormat); 
      int videoTrackIndex = muxer.addTrack(VideoFormat); 

      boolean sawEOS = false; 
      boolean sawAudioEOS = false; 
      int bufferSize = MAX_SAMPLE_SIZE; 
      ByteBuffer dstBuf = ByteBuffer.allocate(bufferSize); 
      int offset = 100; 
      MediaCodec.BufferInfo bufferInfo = new MediaCodec.BufferInfo(); 
      muxer.start(); 

      while (!sawEOS) { 
       bufferInfo.offset = offset; 
       bufferInfo.size = extractorVideo.readSampleData(dstBuf, offset); 
       if (bufferInfo.size < 0) { 
        sawEOS = true; 
        bufferInfo.size = 0; 
       } else { 
        bufferInfo.presentationTimeUs = extractorVideo.getSampleTime(); 
        bufferInfo.flags = extractorVideo.getSampleFlags(); 
        int trackIndex = extractorVideo.getSampleTrackIndex(); 
        muxer.writeSampleData(videoTrackIndex, dstBuf, bufferInfo); 
        extractorVideo.advance(); 
       } 
      } 
      ByteBuffer audioBuf = ByteBuffer.allocate(bufferSize); 
      while (!sawAudioEOS) { 
       bufferInfo.offset = offset; 
       bufferInfo.size = extractorAudio.readSampleData(audioBuf, offset); 
       if (bufferInfo.size < 0) { 
        sawAudioEOS = true; 
        bufferInfo.size = 0; 
       } else { 
        bufferInfo.presentationTimeUs = extractorAudio.getSampleTime(); 
        bufferInfo.flags = extractorAudio.getSampleFlags(); 
        int trackIndex = extractorAudio.getSampleTrackIndex(); 
        muxer.writeSampleData(audioTrackIndex, audioBuf, bufferInfo); 
        extractorAudio.advance(); 
       } 
      } 
      muxer.stop(); 
      muxer.release(); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } catch (Exception ex) { 
      ex.printStackTrace(); 
     } 

    } 

} 
+0

我定你代碼塊。在SO上格式化代碼塊的最簡單方法是將其粘貼到您的問題中,選擇它,然後按Ctrl + K或單擊「{}」按鈕。這將通過額外的四個空格縮進塊,這將告訴Stack Overflow將其視爲代碼。您可以在[幫助中心](https://stackoverflow.com/help/formatting)中閱讀有關格式設置的更多信息。 – Chris

+0

下載名爲'mediaInfo'的工具並告訴我們編解碼器設置。如果視頻的h.264配置文件爲「高」,則某些設備可能無法播放,請使用「基準」以獲得最大的設備兼容性。您的音頻AAC或MP3?還要檢查音頻的採樣率是44.1千赫,是立體聲等。 –

回答

0

改變音頻輸出格式和編碼器AMR_NB

相關問題