Android Open Source - Media-Pack Video Player






From Project

Back to project page Media-Pack.

License

The source code is released under:

Apache License

If you think the Android project Media-Pack listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

//
//               INTEL CORPORATION PROPRIETARY INFORMATION
//  This software is supplied under the terms of a license agreement or
//  nondisclosure agreement with Intel Corporation and may not be copied
//  or disclosed except in accordance with the terms of that agreement.
//        Copyright (c) 2013-2014 Intel Corporation. All Rights Reserved.
///*w  ww .  j a v a 2s .  c  om*/


package com.intel.inde.mp.samples.controls;

import android.media.MediaCodec;
import android.media.MediaExtractor;
import android.media.MediaFormat;
import android.os.Handler;
import android.os.Message;
import android.os.SystemClock;
import android.view.Surface;

import java.io.IOException;
import java.nio.ByteBuffer;

public class VideoPlayer {
    private final static int BufferTimeoutUs = 1000;

    private final static int DURATION_CHANGED = 1;
    private final static int POSITION_CHANGED = 2;
    private final static int RESUMED = 3;
    private final static int PAUSED = 4;

    public interface VideoPlayerEvents {
        void onVideoPlayerDurationChanged(long duration);

        void onVideoPlayerPositionChanged(boolean outside, long position);

        void onVideoPlayerPlaybackResumed();

        void onVideoPlayerPlaybackPaused();
    }

    VideoPlayerEvents events;
    Surface surface;

    MediaExtractor extractor;
    MediaCodec codec;

    int trackNumber;

    ByteBuffer[] inputBuffers;
    ByteBuffer[] outputBuffers;
    MediaCodec.BufferInfo bufferInfo;

    Object pauseLock;
    boolean pause;
    boolean stop;

    Object seekLock;
    long seekRequestedToMs;
    long currentPresentationTimeMs;

    Thread videoThread;

    public VideoPlayer(Surface surface) {
        this.surface = surface;

        pauseLock = new Object();
        pause = false;

        seekLock = new Object();
        seekRequestedToMs = -1;

        stop = false;
    }

    public void setEventListener(VideoPlayerEvents listener) {
        events = listener;
    }

    public void open(String path) throws IOException {
        close();

        pause = false;
        stop = false;
        seekRequestedToMs = -1;
        currentPresentationTimeMs = 0;

        extractor = new MediaExtractor();

        extractor.setDataSource(path);

        if (initWithTrackOfInterest("video/") == false) {
            throw new IOException("Can't open video file. Unsupported video format.");
        }

        if (codec == null) {
            throw new IOException("Can't open video file. Unsupported video format.");
        }

        pause();

        videoThread = new VideoThread();
        videoThread.start();
    }

    public void close() {
        stop = true;

        if (videoThread != null) {
            if (videoThread.isAlive()) {
                try {
                    Thread.sleep(500);
                } catch (InterruptedException e) {
                }

                videoThread.interrupt();
            }

            videoThread = null;
        }
    }

    public void resume() {
        if (pause == false || videoThread == null) {
            return;
        }

        synchronized (pauseLock) {
            pause = false;
            pauseLock.notifyAll();
        }

        Message msg = new Message();
        msg.what = RESUMED;
        uiHandler.sendMessage(msg);
    }

    public void pause() {
        if (pause) {
            return;
        }

        synchronized (pauseLock) {
            pause = true;
        }

        Message msg = new Message();
        msg.what = PAUSED;
        uiHandler.sendMessage(msg);
    }

    public void seekTo(long positionMs) {
        synchronized (seekLock) {
            seekRequestedToMs = positionMs;
        }
    }

    public boolean playing() {
        return (videoThread != null && pause == false);
    }

    private boolean initWithTrackOfInterest(String startsWith) {
        int numTracks = extractor.getTrackCount();

        for (int i = 0; i < numTracks; i++) {
            MediaFormat mediaFormat = extractor.getTrackFormat(i);
            String mime = mediaFormat.getString(MediaFormat.KEY_MIME);

            if (mime.startsWith(startsWith)) {
                trackNumber = i;

                extractor.selectTrack(trackNumber);

                codec = MediaCodec.createDecoderByType(mime);
                codec.configure(mediaFormat, surface, null, 0);

                long duration = (int) mediaFormat.getLong(MediaFormat.KEY_DURATION);

                Message msg = uiHandler.obtainMessage(DURATION_CHANGED, duration / 1000);
                uiHandler.sendMessage(msg);

                return true;
            }
        }

        return false;
    }

    protected boolean checkPause() {
        boolean paused = false;

        synchronized (pauseLock) {
            if (pause) {
                paused = true;

                while (pause && stop == false) {
                    try {
                        pauseLock.wait();
                    } catch (InterruptedException e) {
                    }
                }
            }
        }

        return paused;
    }

    final Handler uiHandler = new Handler() {
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case DURATION_CHANGED: {
                    final String longString = msg.obj.toString();
                    final Long theLongObj = new Long(longString);

                    long duration = theLongObj.longValue();

                    events.onVideoPlayerDurationChanged(duration);
                }
                break;

                case POSITION_CHANGED: {
                    final String longString = msg.obj.toString();
                    final Long theLongObj = new Long(longString);

                    long position = theLongObj.longValue();

                    events.onVideoPlayerPositionChanged(false, position);
                }
                break;

                case RESUMED: {
                    events.onVideoPlayerPlaybackResumed();
                }
                break;

                case PAUSED: {
                    events.onVideoPlayerPlaybackPaused();
                }
                break;
            }
        }
    };

    private class VideoThread extends Thread {
        public VideoThread() {
        }

        @Override
        public void run() {
            codec.start();

            inputBuffers = codec.getInputBuffers();
            outputBuffers = codec.getOutputBuffers();
            bufferInfo = new MediaCodec.BufferInfo();

            boolean isEOS = false;

            long startTimeMs = System.currentTimeMillis();

            currentPresentationTimeMs = 0;

            long lastNotificationTime = 0;

            while (stop == false) {
                if (checkPause()) {
                    startTimeMs = System.currentTimeMillis() - currentPresentationTimeMs;
                }

                if (stop) {
                    break;
                }

                synchronized (seekLock) {
                    if (seekRequestedToMs != -1) {
                        extractor.seekTo(seekRequestedToMs * 1000, MediaExtractor.SEEK_TO_CLOSEST_SYNC);
                        codec.flush();

                        currentPresentationTimeMs = seekRequestedToMs;

                        startTimeMs = System.currentTimeMillis() - currentPresentationTimeMs;

                        seekRequestedToMs = -1;
                    }
                }

                if (!isEOS) {
                    int inIndex = codec.dequeueInputBuffer(BufferTimeoutUs);

                    if (inIndex >= 0) {
                        ByteBuffer buffer = inputBuffers[inIndex];
                        int sampleSize = extractor.readSampleData(buffer, 0);

                        if (sampleSize < 0) {
                            codec.queueInputBuffer(inIndex, 0, 0, 0, MediaCodec.BUFFER_FLAG_END_OF_STREAM);
                            isEOS = true;
                        } else {
                            codec.queueInputBuffer(inIndex, 0, sampleSize, extractor.getSampleTime(), 0);
                            extractor.advance();
                        }
                    }
                }

                int outIndex = codec.dequeueOutputBuffer(bufferInfo, BufferTimeoutUs);

                switch (outIndex) {
                    case MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED: {
                        outputBuffers = codec.getOutputBuffers();
                    }
                    break;

                    case MediaCodec.INFO_OUTPUT_FORMAT_CHANGED: {
                    }
                    break;

                    case MediaCodec.INFO_TRY_AGAIN_LATER: {

                    }
                    break;

                    default: {
                        currentPresentationTimeMs = bufferInfo.presentationTimeUs / 1000;

                        if ((SystemClock.currentThreadTimeMillis() - lastNotificationTime) > 10) {
                            Message msg = uiHandler.obtainMessage(POSITION_CHANGED, currentPresentationTimeMs);
                            uiHandler.sendMessage(msg);

                            lastNotificationTime = SystemClock.currentThreadTimeMillis();
                        }

                        while (currentPresentationTimeMs > (System.currentTimeMillis() - startTimeMs)) {
                            try {
                                sleep(10);
                            } catch (InterruptedException e) {
                                break;
                            }

                            if (pause) {
                                break;
                            }

                            synchronized (seekLock) {
                                if (seekRequestedToMs != -1) {
                                    break;
                                }
                            }
                        }

                        codec.releaseOutputBuffer(outIndex, true);
                    }

                    break;
                }

                if (isEOS) {
                    pause();

                    seekTo(0);
                }
            }

            codec.stop();
            codec.release();

            extractor.release();
        }
    }
}




Java Source Code List

com.intel.inde.mp.android.graphics.EglUtil.java
com.intel.inde.mp.android.graphics.FrameBuffer.java
com.intel.inde.mp.android.graphics.FullFrameTexture.java
com.intel.inde.mp.android.graphics.ShaderProgram.java
com.intel.inde.mp.android.graphics.VideoEffect.java
com.intel.inde.mp.effects.AudioEffect.java
com.intel.inde.mp.effects.AudioReader.java
com.intel.inde.mp.effects.GrayScaleEffect.java
com.intel.inde.mp.effects.InverseEffect.java
com.intel.inde.mp.effects.JpegSubstituteEffect.java
com.intel.inde.mp.effects.OverlayEffect.java
com.intel.inde.mp.effects.RotateEffect.java
com.intel.inde.mp.effects.SepiaEffect.java
com.intel.inde.mp.effects.SubstituteAudioEffect.java
com.intel.inde.mp.effects.TextOverlayEffect.java
com.intel.inde.mp.samples.ActivityWithTimeline.java
com.intel.inde.mp.samples.CameraCapturerActivity.java
com.intel.inde.mp.samples.CameraStreamerActivity.java
com.intel.inde.mp.samples.ComposerAudioEffectActivity.java
com.intel.inde.mp.samples.ComposerAudioEffectCoreActivity.java
com.intel.inde.mp.samples.ComposerCutActivity.java
com.intel.inde.mp.samples.ComposerCutCoreActivity.java
com.intel.inde.mp.samples.ComposerJoinActivity.java
com.intel.inde.mp.samples.ComposerJoinCoreActivity.java
com.intel.inde.mp.samples.ComposerMediaFileInfoActivity.java
com.intel.inde.mp.samples.ComposerMediaFileInfoCoreActivity.java
com.intel.inde.mp.samples.ComposerTranscodeActivity.java
com.intel.inde.mp.samples.ComposerTranscodeCoreActivity.java
com.intel.inde.mp.samples.ComposerVideoEffectActivity.java
com.intel.inde.mp.samples.ComposerVideoEffectCoreActivity.java
com.intel.inde.mp.samples.DemoListAdapter.java
com.intel.inde.mp.samples.DemoListItem.java
com.intel.inde.mp.samples.ExpandableSamplesListAdapter.java
com.intel.inde.mp.samples.FPSCounter.java
com.intel.inde.mp.samples.Format.java
com.intel.inde.mp.samples.GameCapturing.java
com.intel.inde.mp.samples.GameRenderer.java
com.intel.inde.mp.samples.GameStreaming.java
com.intel.inde.mp.samples.MediaStreamerActivity.java
com.intel.inde.mp.samples.MediaStreamerCoreActivity.java
com.intel.inde.mp.samples.RecognitionActivity.java
com.intel.inde.mp.samples.SamplesMainActivity.java
com.intel.inde.mp.samples.VideoCapture.java
com.intel.inde.mp.samples.VideoPlayerActivity.java
com.intel.inde.mp.samples.VideoStreamPlayerActivity.java
com.intel.inde.mp.samples.controls.CameraCaptureSettingsPopup.java
com.intel.inde.mp.samples.controls.GameGLSurfaceView.java
com.intel.inde.mp.samples.controls.PlaybackToolbar.java
com.intel.inde.mp.samples.controls.PopupMessage.java
com.intel.inde.mp.samples.controls.Popup.java
com.intel.inde.mp.samples.controls.RangeSelector.java
com.intel.inde.mp.samples.controls.TimelineItem.java
com.intel.inde.mp.samples.controls.TranscodeSurfaceView.java
com.intel.inde.mp.samples.controls.VideoPlayer.java