Android 使用MediaSync和MediaExtractor,播放速度快2倍

Android 使用MediaSync和MediaExtractor,播放速度快2倍,android,android-6.0-marshmallow,mediaextractor,Android,Android 6.0 Marshmallow,Mediaextractor,我正在使用MediaSync和MediaExtractor播放视频 为了开始播放,我写了下面的代码 MediaSync mediaSync = new MediaSync(); mediaSync.setSurface(surface); Surface inputSurface = mediaSync.createInputSurface(); mediaExtractor = new 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();
这不是正确的做法


如果有人能帮我找到以正常速度播放视频的正确方法。

不确定这是否能解决您的问题,但您正在拨打的释放OutputBuffer的电话似乎有以微秒为单位的时间戳。查看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);
 }
 // ...
}


这没有关系,但您可以使用Exoplayer
@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();
                }
            }
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);
 }
 // ...