at.wada811.app.fragment.VideoFragment.java Source code

Java tutorial

Introduction

Here is the source code for at.wada811.app.fragment.VideoFragment.java

Source

/*
 * Copyright 2013 wada811<at.wada811@gmail.com>
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package at.wada811.app.fragment;

import android.annotation.TargetApi;
import android.app.Activity;
import android.content.res.AssetManager;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnBufferingUpdateListener;
import android.media.MediaPlayer.OnCompletionListener;
import android.media.MediaPlayer.OnErrorListener;
import android.media.MediaPlayer.OnInfoListener;
import android.media.MediaPlayer.OnPreparedListener;
import android.media.MediaPlayer.OnVideoSizeChangedListener;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import at.wada811.android.library.R;
import at.wada811.utils.DisplayUtils;
import at.wada811.utils.LogUtils;
import java.io.FileDescriptor;
import java.io.IOException;
import java.util.Map;

public class VideoFragment extends Fragment implements SurfaceHolder.Callback, OnVideoSizeChangedListener,
        OnBufferingUpdateListener, OnPreparedListener, OnCompletionListener {

    public static final String TAG = VideoFragment.class.getSimpleName();

    private VideoCallback mCallback;

    public SurfaceView mSurfaceView;
    public SurfaceHolder mHolder;
    public MediaPlayer mMediaPlayer;

    public static final String KEY_RES_ID = "KEY_RES_ID";
    public static final String KEY_FILE_PATH = "KEY_FILE_PATH";

    private int mDisplayWidth = 0;
    private int mDisplayHeight = 0;
    private int mVideoWidth;
    private int mVideoHeight;
    private boolean mIsVideoSizeKnown = false;
    private boolean mIsVideoReadyToBePlayed = false;
    private boolean mIsVideoAutoPlay = false;

    public static interface VideoCallbackProvider {
        public VideoCallback getVideoCallback();
    }

    public static interface VideoCallback {

        public void onActivityCreated(VideoFragment videoFragment);

        public void onPrepared(VideoFragment videoFragment);

        public void onCompletion(VideoFragment videoFragment);

        public void surfaceDestroyed(VideoFragment videoFragment);
    }

    public static VideoFragment newInstance(int videoResId) {
        VideoFragment fragment = new VideoFragment();
        Bundle args = new Bundle();
        args.putInt(VideoFragment.KEY_RES_ID, videoResId);
        fragment.setArguments(args);
        return fragment;
    }

    public static VideoFragment newInstance(String videoFilePath) {
        VideoFragment fragment = new VideoFragment();
        Bundle args = new Bundle();
        args.putString(VideoFragment.KEY_FILE_PATH, videoFilePath);
        fragment.setArguments(args);
        return fragment;
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        LogUtils.i();
        setRetainInstance(true);
    }

    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
        LogUtils.i();

        if (activity instanceof VideoCallbackProvider == false) {
            throw new ClassCastException("activity must implements VideoCallbackPicker.");
        }
        VideoCallbackProvider picker = (VideoCallbackProvider) activity;
        mCallback = picker.getVideoCallback();
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        LogUtils.i();
        mSurfaceView = (SurfaceView) inflater.inflate(R.layout.fragment_video, null);
        mHolder = mSurfaceView.getHolder();
        mHolder.addCallback(this);
        return mSurfaceView;
    }

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        LogUtils.i();
        initMediaPlayer();
    }

    private void initMediaPlayer() {
        LogUtils.i();
        if (getArguments().keySet().contains(KEY_RES_ID)) {
            mMediaPlayer = MediaPlayer.create(getActivity(), getArguments().getInt(KEY_RES_ID));
        } else {
            mMediaPlayer = new MediaPlayer();
        }
        mMediaPlayer.setOnVideoSizeChangedListener(this);
        mMediaPlayer.setOnBufferingUpdateListener(this);
        mMediaPlayer.setOnPreparedListener(this);
        mMediaPlayer.setOnCompletionListener(this);
        mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
        mMediaPlayer.setOnInfoListener(new OnInfoListener() {
            @Override
            public boolean onInfo(MediaPlayer mp, int what, int extra) {
                switch (what) {
                case MediaPlayer.MEDIA_INFO_BAD_INTERLEAVING:
                    LogUtils.i("MediaPlayer.MEDIA_INFO_BAD_INTERLEAVING");
                    break;
                case MediaPlayer.MEDIA_INFO_BUFFERING_END:
                    LogUtils.i("MediaPlayer.MEDIA_INFO_BUFFERING_END");
                    break;
                case MediaPlayer.MEDIA_INFO_BUFFERING_START:
                    LogUtils.i("MediaPlayer.MEDIA_INFO_BUFFERING_START");
                    break;
                case MediaPlayer.MEDIA_INFO_METADATA_UPDATE:
                    LogUtils.i("MediaPlayer.MEDIA_INFO_METADATA_UPDATE");
                    break;
                case MediaPlayer.MEDIA_INFO_NOT_SEEKABLE:
                    LogUtils.i("MediaPlayer.MEDIA_INFO_NOT_SEEKABLE");
                    break;
                case MediaPlayer.MEDIA_INFO_SUBTITLE_TIMED_OUT:
                    LogUtils.i("MediaPlayer.MEDIA_INFO_SUBTITLE_TIMED_OUT");
                    break;
                case MediaPlayer.MEDIA_INFO_UNSUPPORTED_SUBTITLE:
                    LogUtils.i("MediaPlayer.MEDIA_INFO_UNSUPPORTED_SUBTITLE");
                    break;
                case MediaPlayer.MEDIA_INFO_VIDEO_RENDERING_START:
                    LogUtils.i("MediaPlayer.MEDIA_INFO_VIDEO_RENDERING_START");
                    break;
                case MediaPlayer.MEDIA_INFO_VIDEO_TRACK_LAGGING:
                    LogUtils.i("MediaPlayer.MEDIA_INFO_VIDEO_TRACK_LAGGING");
                    break;
                case MediaPlayer.MEDIA_INFO_UNKNOWN:
                default:
                    LogUtils.i("MediaPlayer.MEDIA_INFO_UNKNOWN");
                    break;
                }
                LogUtils.d("extra: " + extra);
                return false;
            }
        });
        mMediaPlayer.setOnErrorListener(new OnErrorListener() {
            @Override
            public boolean onError(MediaPlayer mp, int what, int extra) {
                switch (what) {
                case MediaPlayer.MEDIA_ERROR_SERVER_DIED:
                    LogUtils.e("MediaPlayer.MEDIA_ERROR_SERVER_DIED");
                    break;
                case MediaPlayer.MEDIA_ERROR_UNKNOWN:
                default:
                    LogUtils.e("MediaPlayer.MEDIA_ERROR_UNKNOWN");
                    break;
                }
                switch (extra) {
                case MediaPlayer.MEDIA_ERROR_IO:
                    LogUtils.e("MediaPlayer.MEDIA_ERROR_IO");
                    break;
                case MediaPlayer.MEDIA_ERROR_MALFORMED:
                    LogUtils.e("MediaPlayer.MEDIA_ERROR_MALFORMED");
                    break;
                case MediaPlayer.MEDIA_ERROR_NOT_VALID_FOR_PROGRESSIVE_PLAYBACK:
                    LogUtils.e("MediaPlayer.MEDIA_ERROR_NOT_VALID_FOR_PROGRESSIVE_PLAYBACK");
                    break;
                case MediaPlayer.MEDIA_ERROR_TIMED_OUT:
                    LogUtils.e("MediaPlayer.MEDIA_ERROR_TIMED_OUT");
                    break;
                case MediaPlayer.MEDIA_ERROR_UNSUPPORTED:
                    LogUtils.e("MediaPlayer.MEDIA_ERROR_UNSUPPORTED");
                    break;
                default:
                    LogUtils.e("extra: " + extra);
                    break;
                }
                return false;
            }
        });
        mCallback.onActivityCreated(this);
    }

    @Override
    public void onDetach() {
        super.onDetach();
        LogUtils.i();
        stop();
        reset();
        release();
        mHolder.removeCallback(this);
        doCleanUp();
    }

    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        LogUtils.i();
        mMediaPlayer.setDisplay(holder);
        if (getArguments().keySet().contains(KEY_FILE_PATH)) {
            LogUtils.d(getArguments().getString(KEY_FILE_PATH));
            try {
                setDateSource(getArguments().getString(KEY_FILE_PATH));
                prepare();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
        LogUtils.i("format: " + format);
        LogUtils.i("width: " + width + ", height: " + height);
    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        LogUtils.i();
        mCallback.surfaceDestroyed(this);
    }

    @Override
    public void onVideoSizeChanged(MediaPlayer mp, int width, int height) {
        LogUtils.i("width: " + width + ", height: " + height);
        if (width == 0 || height == 0) {
            LogUtils.e("invalid video width(" + width + ") or height(" + height + ")");
            return;
        }
        mIsVideoSizeKnown = true;
        mVideoWidth = width;
        mVideoHeight = height;
        if (mIsVideoReadyToBePlayed && mIsVideoSizeKnown && mIsVideoAutoPlay) {
            start();
        }
    }

    @Override
    public void onBufferingUpdate(MediaPlayer mp, int percent) {
        LogUtils.i("percent: " + percent);
    }

    @Override
    public void onPrepared(MediaPlayer mp) {
        LogUtils.i();
        mCallback.onPrepared(this);
        mIsVideoReadyToBePlayed = true;
        if (mIsVideoReadyToBePlayed && mIsVideoSizeKnown && mIsVideoAutoPlay) {
            start();
        }
    }

    @Override
    public void onCompletion(MediaPlayer mp) {
        LogUtils.i();
        mCallback.onCompletion(this);
    }

    public void setVideoAutoPlay(boolean isVideoAutoPlay) {
        mIsVideoAutoPlay = isVideoAutoPlay;
    }

    public void setDateSource(AssetManager assets, String fileName)
            throws IllegalArgumentException, IllegalStateException, IOException {
        mMediaPlayer.setDataSource(assets.openFd(fileName).getFileDescriptor());
    }

    public void setDateSource(FileDescriptor fd)
            throws IllegalArgumentException, IllegalStateException, IOException {
        mMediaPlayer.setDataSource(fd);
    }

    public void setDateSource(String path)
            throws IllegalArgumentException, SecurityException, IllegalStateException, IOException {
        mMediaPlayer.setDataSource(path);
    }

    public void setDateSource(Uri uri)
            throws IllegalArgumentException, SecurityException, IllegalStateException, IOException {
        mMediaPlayer.setDataSource(getActivity(), uri);
    }

    @TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH)
    public void setDateSource(Uri uri, Map<String, String> headers)
            throws IllegalArgumentException, SecurityException, IllegalStateException, IOException {
        mMediaPlayer.setDataSource(getActivity(), uri, headers);
    }

    public void setDateSource(FileDescriptor fd, long offset, long length)
            throws IllegalArgumentException, IllegalStateException, IOException {
        mMediaPlayer.setDataSource(fd, offset, length);
    }

    public void setDisplayWidth(int width) {
        mDisplayWidth = width;
    }

    public void setDisplayHeight(int height) {
        mDisplayHeight = height;
    }

    public void prepare() throws IllegalStateException, IOException {
        mMediaPlayer.prepare();
    }

    private void setSize() {
        LogUtils.i("width: " + mVideoWidth + ", height: " + mVideoHeight);
        int videoWidth = DisplayUtils.getWidth(getActivity());
        int videoHeight = DisplayUtils.getHeight(getActivity());
        if (mDisplayWidth == 0 && mDisplayHeight == 0) {
            videoHeight = mVideoHeight * videoWidth / mVideoWidth;
        } else if (mDisplayWidth != 0 && mDisplayHeight == 0) {
            videoWidth = mDisplayWidth;
            videoHeight = mVideoHeight * videoWidth / mVideoWidth;
        } else if (mDisplayWidth == 0 && mDisplayHeight != 0) {
            videoHeight = mDisplayHeight;
            videoWidth = mVideoWidth * videoHeight / mVideoHeight;
        } else if (mDisplayWidth != 0 && mDisplayHeight != 0) {
            videoWidth = mDisplayWidth;
            videoHeight = mDisplayHeight;
        }
        LogUtils.i("width: " + videoWidth + ", height: " + videoHeight);
        mSurfaceView.setLayoutParams(new FrameLayout.LayoutParams(videoWidth, videoHeight));
        mHolder.setFixedSize(videoWidth, videoHeight);
        LogUtils.d("CurrentPosition: " + mMediaPlayer.getCurrentPosition());
    }

    public void seekTo(int msec) {
        mMediaPlayer.seekTo(msec);
    }

    public void start() {
        setSize();
        mMediaPlayer.seekTo(mMediaPlayer.getCurrentPosition());
        mMediaPlayer.start();
    }

    public void pause() {
        if (mMediaPlayer != null) {
            if (mMediaPlayer.isPlaying()) {
                mMediaPlayer.pause();
            }
        }
    }

    public void stop() {
        if (mMediaPlayer != null) {
            pause();
            mMediaPlayer.stop();
        }
    }

    public void reset() {
        if (mMediaPlayer != null) {
            mMediaPlayer.reset();
        }
    }

    public void release() {
        if (mMediaPlayer != null) {
            mMediaPlayer.release();
            mMediaPlayer = null;
        }
    }

    private void doCleanUp() {
        mVideoWidth = 0;
        mVideoHeight = 0;
        mIsVideoReadyToBePlayed = false;
        mIsVideoSizeKnown = false;
    }

}