一、如下相关网址1~4为普通播放视频方式

相关网址:

  1. 玩转 Android MediaPlayer之视频预加载(优化)

  2. 实现简单的Android的播放视频功能

  3. Android三种播放视频的方式

  4. Android VideoView 帮助文档

  5. Android OpenCore介绍

二、如果需要获取视频播放的每一帧,可以采用MediaCodec

MediaCodec分两种情况:

  1. 直接绘制到绑定的surface(suface view)上。

  2. 获取解码后的每帧图像(ByteBuffer或Image),可以进行解析或将Image绘制到view上。

第二种情况 sample code:

    import android.media.MediaCodec;
    import android.media.MediaExtractor;
    import android.media.MediaFormat;

    ...
    // start video decode in some function
    if (mplayer == null) {
        mplayer = new PlayerThread(syncToken_, this, appParentPath);
        mplayer.start();
    }
    ...

    private class MediaPlayerThread extends Thread {
        private MediaExtractor extractor;
        private MediaCodec decoder;

        public MediaPlayerThread() {
        }

        @Override
        public void run() {
            while (!Thread.interrupted()) {
                extractor = new MediaExtractor();
                try {
                    extractor.setDataSource("video.mp4");  // "video.MOV"
                } catch (IOException e) {
                    e.printStackTrace();
                }

                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);
                        try {
                            decoder = MediaCodec.createDecoderByType(mime);
                            decoder.configure(format, null, null, 0);
                        } catch (IOException e) {
                            e.printStackTrace();
                            Log.e("MediaPlayer", "Can't find video info!");
                            return;
                        }
                        break;
                    }
                }

                decoder.start();

                ByteBuffer[] inputBuffers = decoder.getInputBuffers();
                ByteBuffer[] outputBuffers = decoder.getOutputBuffers();
                MediaCodec.BufferInfo info = new MediaCodec.BufferInfo();
                boolean isEOS = false;

                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("MediaPlayer", "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("MediaPlayer", "INFO_OUTPUT_BUFFERS_CHANGED");
                            outputBuffers = decoder.getOutputBuffers();
                            break;
                        case MediaCodec.INFO_OUTPUT_FORMAT_CHANGED:
                            Log.d("MediaPlayer", "New format " + decoder.getOutputFormat());
                            // New format {image-data=java.nio.ByteArrayBuffer[position=0,limit=80,capacity=80], crop-top=0, crop-right=1279, color-format=21, vqzip-level=0, height=720, crop-left=0, stride=1280, mime=video/raw, vqzip-entropy=-36, slice-height=720, width=1280, what=1869968451, vqzip-profile=1382400, crop-bottom=719}
                            // color-format=21: COLOR_FormatYUV420SemiPlanar yuv420sp(NV21)
                            MediaFormat fmt = decoder.getOutputFormat();
                            //invoke fmt.getInteger("width") to get frame width
                            //invoke fmt.getInteger("height") to get frame height
                            break;
                        case MediaCodec.INFO_TRY_AGAIN_LATER:
                            Log.d("MediaPlayer", "dequeueOutputBuffer timed out!");
                            break;
                        default:
                            ByteBuffer buffer = outputBuffers[outIndex];
                            Log.v("MediaPlayer", "frame buffer " + buffer);
                            if (buffer.limit() > 0) {
                                // duplicate frame buffer
                                byte[] fBuff = new byte[buffer.limit()];
                                buffer.get(fBuff);
                                // TODO: pass "fBuff" to some function
                                ...
                            }
                            decoder.releaseOutputBuffer(outIndex, false);
                            break;
                    }

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

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

相关网址:

  1. Android 用MediaCodec实现视频硬解码

  2. android之View和SurfaceView

  3. Android MediaCodec 帮助文档

  4. Android MediaCodec小结

  5. MediaCodecExample/src/net/thdev/mediacodecexample/decoder/VideoDecoderThread.java

  6. A simple video only player with MediaExtractor and MediaCodec

  7. Android MediaCodec stuff/Demo