2015-11-05 112 views
2

我正在使用MediaSync和MediaExtractor播放視頻。使用MediaSync和MediaExtractor播放速度快兩倍

要開始播放我已經寫下面代碼

MediaSync mediaSync = new MediaSync(); 
      mediaSync.setSurface(surface); 
      Surface inputSurface = mediaSync.createInputSurface(); 

      mediaExtractor = new MediaExtractor(); 

      try { 
       mediaExtractor.setDataSource(this.clipPath); 
      } catch (IOException e1) { 
       e1.printStackTrace(); 
      } 


      for (int i = 0; i < mediaExtractor.getTrackCount(); i++) { 
       MediaFormat format = mediaExtractor.getTrackFormat(i); 
       String mime = format.getString(MediaFormat.KEY_MIME); 
       if (mime.startsWith("video/")) { 
        Log.d("Med","Formt data:" +format.toString()); 
        Log.d("Med","frame data:" +format.getInteger(MediaFormat.KEY_FRAME_RATE)); 
        ratio=format.getInteger(MediaFormat.KEY_FRAME_RATE); 
//     Log.d("Med","capture data:" +format.getInteger(MediaFormat.KEY_CAPTURE_RATE)); 

          mediaExtractor.selectTrack(i); 
//     ratio=1000f/format.getInteger(MediaFormat.KEY_FRAME_RATE); 
        try { 
         videoDecoder = MediaCodec.createDecoderByType(mime); 
        } catch (IOException e) { 
         e.printStackTrace(); 
        } 
        videoDecoder.configure(format, inputSurface, null, 0); 
        Log.d(LOG_TAG, "Found a video track."); 
        break; 
       } 
      } 

      SyncParams syncParams = new SyncParams(); 
      syncParams.allowDefaults(); 

      mediaSync.setPlaybackParams(new PlaybackParams().allowDefaults()); 
      mediaSync.setSyncParams(syncParams); 

      videoDecoder.setCallback(decoderCallback, null); 
      videoDecoder.start(); 

我已經使用以下代碼解碼器的回調:

MediaCodec.Callback decoderCallback = new MediaCodec.Callback() { 
      @Override 
      public void onInputBufferAvailable(MediaCodec codec, int index) { 
       if (index >= 0) { 
        ByteBuffer byteBuffer = codec.getInputBuffer(index); 
        int sampleSize = mediaExtractor.readSampleData(byteBuffer, 0); 
        Log.d(LOG_TAG, "SampleSize: " + sampleSize); 
        if (sampleSize < 0) { 
         //we're at end of file so submit EOS to the decoder input 
         Log.d(LOG_TAG, "Video Decoder input EOS reached"); 
         codec.queueInputBuffer(index, 0, 0, 0, MediaCodec.BUFFER_FLAG_END_OF_STREAM); 
        } else { 
         long sampleTime = mediaExtractor.getSampleTime(); 
         Log.d(LOG_TAG ,"ratio"+ratio+" sampletime"+sampleTime); 
         codec.queueInputBuffer(index, 0, sampleSize, sampleTime, 0); 
         mediaExtractor.advance(); 
        } 
       } 
      } 

      @Override 
      public void onError(MediaCodec codec, MediaCodec.CodecException e) { 

      } 



       @Override 
       public void onOutputFormatChanged(MediaCodec codec, MediaFormat format) { 

       } 

       @Override 
       public void onOutputBufferAvailable(MediaCodec codec, int index, MediaCodec.BufferInfo info) { 
        Log.d(LOG_TAG, "Rendering with preso time: " + info.presentationTimeUs); 
        codec.releaseOutputBuffer(index, info.presentationTimeUs); 

       } 
      }; 

如果我在onOutputBufferAvailable修改後的代碼,它起着與正常播放速度,

@Override 
      public void onOutputBufferAvailable(MediaCodec codec, int index, MediaCodec.BufferInfo info) { 
       Log.d(LOG_TAG, "Rendering with preso time: " + info.presentationTimeUs); 
       codec.releaseOutputBuffer(index, info.presentationTimeUs+(ratio+1000000L)); 
       try { 

        Thread.sleep((int)(1000/ratio)); 
       } catch (InterruptedException e) { 
        // TODO Auto-generated catch block 
        e.printStackTrace(); 
       } 
      } 

這是不正確的做法。

如果有人能幫我找到正常播放正常速度的正確方法。

+0

它不相關的,但你可以使用Exoplayer –

回答

0

不知道這是否會解決您的問題,但您正在對releaseOutputBuffer進行的調用似乎具有微秒的時間戳。查看MediaSync文檔中的示例,顯示此時間戳需要納秒。所以,你需要乘以info.presentationTimeUs * 1000

onOutputBufferAvailable(MediaCodec codec, int bufferId, BufferInfo info) { 
// ... 
if (codec == videoDecoder) { 
    // surface timestamp must contain media presentation time in nanoseconds. 
    codec.releaseOutputBuffer(bufferId, 1000 * info.presentationTime); 
} else { 
    ByteBuffer audioByteBuffer = codec.getOutputBuffer(bufferId); 
    sync.queueAudio(audioByteBuffer, bufferId, info.presentationTime); 
} 
// ... 

}

http://developer.android.com/reference/android/media/MediaSync.html

相關問題