2017-02-25 45 views
0

我正在嘗試使用MediaCodec播放視頻。視頻正在播放,但音頻靜音。我想取消靜音。經過研究,我發現我們需要單獨解碼音頻和視頻。我只想使用一個Mediacodec和MediaExtractor對象來播放視頻和音頻。如何這可以實現嗎? 我用下面的代碼播放視頻。使用MediaCodec和MediaExtractor播放視頻和音頻

 extractor = new MediaExtractor(); 
     extractor.setDataSource(SAMPLE); 

     for (int i = 0; i < extractor.getTrackCount(); i++) { 
      MediaFormat format = extractor.getTrackFormat(i); 
      String mime = format.getString(MediaFormat.KEY_MIME); 
      if (mime.startsWith("video/")) { 
       extractor.selectTrack(i); 
       decoder = MediaCodec.createDecoderByType(mime); 
       decoder.configure(format, surface, null, 0); 
       break; 
      } 
     } 

     if (decoder == null) { 
      Log.e("DecodeActivity", "Can't find video info!"); 
      return; 
     } 

     decoder.start(); 

     ByteBuffer[] inputBuffers = decoder.getInputBuffers(); 
     ByteBuffer[] outputBuffers = decoder.getOutputBuffers(); 
     BufferInfo info = new BufferInfo(); 
     boolean isEOS = false; 
     long startMs = System.currentTimeMillis(); 

     while (!Thread.interrupted()) { 
      if (!isEOS) { 
       int inIndex = decoder.dequeueInputBuffer(10000); 
       if (inIndex >= 0) { 
        ByteBuffer buffer = inputBuffers[inIndex]; 
        int sampleSize = extractor.readSampleData(buffer, 0); 
        if (sampleSize < 0) { 
         // We shouldn't stop the playback at this point, just pass the EOS 
         // flag to decoder, we will get it again from the 
         // dequeueOutputBuffer 
         Log.d("DecodeActivity", "InputBuffer BUFFER_FLAG_END_OF_STREAM"); 
         decoder.queueInputBuffer(inIndex, 0, 0, 0, MediaCodec.BUFFER_FLAG_END_OF_STREAM); 
         isEOS = true; 
        } else { 
         decoder.queueInputBuffer(inIndex, 0, sampleSize, extractor.getSampleTime(), 0); 
         extractor.advance(); 
        } 
       } 
      } 

      int outIndex = decoder.dequeueOutputBuffer(info, 10000); 
      switch (outIndex) { 
      case MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED: 
       Log.d("DecodeActivity", "INFO_OUTPUT_BUFFERS_CHANGED"); 
       outputBuffers = decoder.getOutputBuffers(); 
       break; 
      case MediaCodec.INFO_OUTPUT_FORMAT_CHANGED: 
       Log.d("DecodeActivity", "New format " + decoder.getOutputFormat()); 
       break; 
      case MediaCodec.INFO_TRY_AGAIN_LATER: 
       Log.d("DecodeActivity", "dequeueOutputBuffer timed out!"); 
       break; 
      default: 
       ByteBuffer buffer = outputBuffers[outIndex]; 
       Log.v("DecodeActivity", "We can't use this buffer but render it due to the API limit, " + buffer); 

       // We use a very simple clock to keep the video FPS, or the video 
       // playback will be too fast 
       while (info.presentationTimeUs/1000 > System.currentTimeMillis() - startMs) { 
        try { 
         sleep(10); 
        } catch (InterruptedException e) { 
         e.printStackTrace(); 
         break; 
        } 
       } 
       decoder.releaseOutputBuffer(outIndex, true); 
       break; 
      } 

      // All decoded frames have been rendered, we can stop playing now 
      if ((info.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0) { 
       Log.d("DecodeActivity", "OutputBuffer BUFFER_FLAG_END_OF_STREAM"); 
       break; 
      } 
     } 

     decoder.stop(); 
     decoder.release(); 
     extractor.release(); 
    } 

回答

0

您可以使用一個提取器,但使用兩個mediacodec實例進行音頻和視頻播放。只有一個mediacodec實例不能這樣做。 對於分路器,一個提取器可以,它將文件解複用爲音頻流和視頻流。 但是音頻和視頻流應該使用不同的解碼器,如音頻AAC,視頻AVC等......而mediacodec不能動態更改解碼類型,因此您應該爲每個流創建不同的mediacodec實例。 玩家應該考慮AV同步...... 您可以參考:https://github.com/saki4510t/AudioVideoPlayerSample

+0

感謝您的feedback.I使用了兩個不同的mediacodec實例,它工作正常。 –