It’s now or never

IT系の技術ブログです。気になったこと、勉強したことを備忘録的にまとめて行きます。

【Android】動画を再生する

Androidで動画を再生するためには、いくつか方法があるみたいですが、
基本的な方法であるMediaPlayerVideoViewを使った再生方法を試してみました。

MediaPlayerを使って再生する

MediaPlayerで動画を再生する為には、SurfaceViewを使用します。
SurfaceViewは、グラフィックを描画する為のViewで
SurfaceHolder.CallbackというInterfaceを使用してViewの管理を行います。

リファレンス

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

レイアウトの準備

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <SurfaceView android:id="@+id/surfaceView" 
        android:layout_width="wrap_content" 
        android:layout_height="wrap_content" />

</RelativeLayout>

実装ソース

public class MainActivity extends Activity implements SurfaceHolder.Callback {
    SurfaceView mSurfaceView;
    SurfaceHolder mSurfaceHolder;
    MediaPlayer mMediaPlayer;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        // Windowを透明にする
        getWindow().setFormat(PixelFormat.TRANSPARENT);
        mSurfaceView = (SurfaceView) findViewById(R.id.surfaceView);
        
        // SurfaceHolderを取得する
        mSurfaceHolder = mSurfaceView.getHolder();
        mSurfaceHolder.addCallback(this);
    }
    
    @Override
    protected void onDestroy() {
        // メディアプレーヤーを解放する
        if (mMediaPlayer != null) {
            mMediaPlayer.release();
            mMediaPlayer = null;
        }
        super.onDestroy();
    };

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width,
            int height) {
        // TODO Auto-generated method stub
    }

    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        String path = Environment.getExternalStorageDirectory().toString() + "/video.mp4";
        mMediaPlayer =  new MediaPlayer();
        try {
            mMediaPlayer.setDataSource(path);
            // 画面にSurfaceHolderを指定する
            mMediaPlayer.setDisplay(holder);
            mMediaPlayer.prepare();
            mMediaPlayer.setOnPreparedListener(new MediaPlayer. OnPreparedListener() {
                @Override
                public void onPrepared(MediaPlayer mp) {
                    mMediaPlayer.start();
                }
            });
            
        } catch (IllegalArgumentException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (SecurityException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IllegalStateException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        // メディアプレーヤーを解放する
        if(mMediaPlayer != null){
            mMediaPlayer.release();
            mMediaPlayer = null;
        }
    }
}

VideoViewで再生する

VideoViewは、内部でMediaPlayerを使用したウィジェット
MediaPlayerよりも簡易に動画の再生が可能です。

リファレンス

http://developer.android.com/reference/android/widget/VideoView.html

レイアウトの準備

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <VideoView android:id="@+id/videoView"
        android:layout_height="wrap_content"
        android:layout_width="wrap_content" />
</RelativeLayout>
    

ファイルPathから再生

VideoView view = (VideoView) findViewById(R.id.videoView);
videoView.setVideoPath(Environment.getExternalStorageDirectory().toString() + "/video.mp4");
videoView.start();

URLから再生

VideoView view = (VideoView) findViewById(R.id.videoView);
videoView.setVideoURI(Uri.parse("http://sample/sample.mp4"));
videoView.start();

再生コントローラを使用する

OSが準備する再生コントローラを使用するには、MediaControllerクラスを使用します。

videoView.setMediaController(new MediaController(this));

注意点

上記サンプルソースでは、setVideoPath()または、setVideoURI()直後にstart()を実行していますが、
setVideoXXメソッドは、非同期であるため準備ができるまで再生を待つ必要があります。
そのため、リスナーを設定し、準備が完了してから再生を行うのが正しい実装です。

VideoView view = (VideoView) findViewById(R.id.videoView);
videoView.setVideoPath(Environment.getExternalStorageDirectory().toString() + "/video.mp4");
videoView.setOnPreparedListener(new OnPreparedListener() {
    @Override
    public void onPrepared(MediaPlayer mp) {
        videoView.start();
    }
});

再生フォーマット

VideoViewおよびMediaPlayerの再生フォーマットは下記を参照して下さい。

http://developer.android.com/guide/appendix/media-formats.html