Hướng dẫn sử dụng Android MediaPlayer và VideoView
Công ty Vĩnh Cửu tuyển dụng lập trình viên Java

1- MediaPlayer

Android cung cấp sẵn một thành phần dùng để chơi nhạc, đó là MediaPlayer. MediaPlayer có thể chạy các file audio và video, với file nguồn nằm trên thiết bị của bạn hoặc từ một đường dẫn URL.

Cũng giống với các phần mềm chơi nhạc khác mà bạn biết, MediaPlayer cung cấp các phương thức để bản kiểm soát phát lại âm thanh (control playback of audio/video) bao gồm chạy, dừng, tua đi, tua lại,..

Bạn cũng có thể gọi tới MediaPlayer từ một dịch vụ.

MediaPlayer là một thành phần không có giao diện, nó dễ dàng giúp bạn chơi một file nhạc, tuy nhiên để chơi một file video bạn cần phải kết hợp nó với SuffaceView để hiển thị hình ảnh. 
 

2- VideoView

VideoView là một thành phần tùy biến sẵn có của Android, nó là sự kết hợp của MediaPlayerSuffaceView, giúp bạn thực hiện một video dễ dàng hơn.
Khi sử dụng VideoView bạn có thể sử dụng MediaController, đây là một thành phần có sẵn trong Android sử dụng để điều khiển media (Chẳng hạn start, stop, tua, tạm dừng,..)
Nếu bạn đặt VideoViewMediaController trong một FrameLayout, bạn có thể nhận được một giao diện giống dưới đây:

3- Ví dụ chơi nhạc với MediaPlayer

Ví dụ đơn giản sau đây, sử dụng MediaPlayer để chơi một file nhạc và một vài nút điều khiển việc chơi nhạc như chạy, tạm dừng, tua đi tua lại.
Tạo mới một project có tên MediaPlayerTutorial:
Tạo thư mục raw để chứa file nhạc.
Chuẩn bị một file nhạc, copy và paste vào thư mục raw.
Đây là giao diện của ví dụ:
Thiết kế giao diện:
Sét đặt tên phương thức sẽ được gọi khi click vào các button:
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<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"
   android:paddingBottom="@dimen/activity_vertical_margin"
   android:paddingLeft="@dimen/activity_horizontal_margin"
   android:paddingRight="@dimen/activity_horizontal_margin"
   android:paddingTop="@dimen/activity_vertical_margin"
   tools:context="org.o7planning.mediaplayertutorial.MainActivity">

   <Button
       style="?android:attr/buttonStyleSmall"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:text="&lt;&lt;"
       android:id="@+id/button_rewind"
       android:layout_marginLeft="60dp"
       android:layout_marginStart="60dp"
       android:layout_marginTop="81dp"
       android:layout_below="@+id/textView_currentPosion"
       android:layout_alignParentLeft="true"
       android:layout_alignParentStart="true"
       android:onClick="doRewind" />

   <Button
       style="?android:attr/buttonStyleSmall"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:text="Start"
       android:id="@+id/button_start"
       android:layout_alignBottom="@+id/button_rewind"
       android:layout_toRightOf="@+id/button_rewind"
       android:layout_toEndOf="@+id/button_rewind"
       android:onClick="doStart" />

   <Button
       style="?android:attr/buttonStyleSmall"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:text="Pause"
       android:id="@+id/button_pause"
       android:layout_alignBottom="@+id/button_start"
       android:layout_toRightOf="@+id/button_start"
       android:layout_toEndOf="@+id/button_start"
       android:onClick="doPause" />

   <Button
       style="?android:attr/buttonStyleSmall"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:text=">>"
       android:id="@+id/button_fastForward"
       android:layout_alignBottom="@+id/button_pause"
       android:layout_toRightOf="@+id/button_pause"
       android:layout_toEndOf="@+id/button_pause"
       android:onClick="doFastForward" />

   <SeekBar
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:id="@+id/seekBar"
       android:layout_alignParentLeft="true"
       android:layout_alignParentStart="true"
       android:layout_alignParentTop="true"
       android:layout_alignParentRight="true"
       android:layout_alignParentEnd="true" />

   <TextView
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:textAppearance="?android:attr/textAppearanceLarge"
       android:text="&lt;Current Position>"
       android:id="@+id/textView_currentPosion"
       android:layout_marginTop="65dp"
       android:gravity="center"
       android:layout_below="@+id/textView_maxTime"
       android:layout_centerHorizontal="true" />

   <TextView
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:textAppearance="?android:attr/textAppearanceLarge"
       android:text="&lt;Max Time>"
       android:id="@+id/textView_maxTime"
       android:layout_below="@+id/seekBar"
       android:layout_alignParentRight="true"
       android:layout_alignParentEnd="true"
       android:layout_marginTop="38dp"
       android:layout_alignParentLeft="true"
       android:layout_alignParentStart="true"
       android:gravity="center" />
</RelativeLayout>
MainActivity.java
package org.o7planning.mediaplayertutorial;

import android.media.MediaPlayer;
import android.os.Handler;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.SeekBar;
import android.widget.TextView;

import java.util.concurrent.TimeUnit;

public class MainActivity extends AppCompatActivity {

    private TextView textMaxTime;
    private TextView textCurrentPosition;
    private Button buttonPause;
    private Button buttonStart;
    private SeekBar seekBar;
    private Handler threadHandler = new Handler();

    private MediaPlayer mediaPlayer;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        this.textCurrentPosition = (TextView)this.findViewById(R.id.textView_currentPosion);
        this.textMaxTime=(TextView) this.findViewById(R.id.textView_maxTime);
        this.buttonStart= (Button) this.findViewById(R.id.button_start);
        this.buttonPause= (Button) this.findViewById(R.id.button_pause);

        this.buttonPause.setEnabled(false);

        this.seekBar= (SeekBar) this.findViewById(R.id.seekBar);
        this.seekBar.setClickable(false);


        // ID của file nhạc trong thư mục 'raw'.
        int songId = this.getRawResIdByName("mysong");

        // Tạo đối tượng MediaPlayer.
        this.mediaPlayer=   MediaPlayer.create(this, songId);
    }


    // Tìm ID của một file nguồn trong thư mục 'raw' theo tên.
    public int getRawResIdByName(String resName)  {
        String pkgName = this.getPackageName();
        // Return 0 if not found.
        // Trả về 0 nếu không tìm thấy.
        int resID = this.getResources().getIdentifier(resName, "raw", pkgName);
        return resID;
    }


    // Chuyển số lượng milli giây thành một String có ý nghĩa.
    private String millisecondsToString(int milliseconds)  {
        long minutes = TimeUnit.MILLISECONDS.toMinutes((long) milliseconds);
        long seconds =  TimeUnit.MILLISECONDS.toSeconds((long) milliseconds) ;
        return minutes+":"+ seconds;
    }

    // Khi người dùng click vào Button "Start".
    public void doStart(View view)  {
  
        // Khoảng thời gian của bài hát (Tính theo mili giây).
        int duration = this.mediaPlayer.getDuration();

        int currentPosition = this.mediaPlayer.getCurrentPosition();
        if(currentPosition== 0)  {
            this.seekBar.setMax(duration);
            String maxTimeString = this.millisecondsToString(duration);
            this.textMaxTime.setText(maxTimeString);
        } else if(currentPosition== duration)  {
      
            // Trở lại trạng thái ban đầu trước khi chơi.
            this.mediaPlayer.reset();
        }
        this.mediaPlayer.start();
 
        // Tạo một thread để update trạng thái của SeekBar.
        UpdateSeekBarThread updateSeekBarThread= new UpdateSeekBarThread();
        threadHandler.postDelayed(updateSeekBarThread,50);

        this.buttonPause.setEnabled(true);
        this.buttonStart.setEnabled(false);
    }

 
    // Thread sử dụng để Update trạng thái cho SeekBar.
    class UpdateSeekBarThread implements Runnable {

        public void run()  {
            int currentPosition = mediaPlayer.getCurrentPosition();
            String currentPositionStr = millisecondsToString(currentPosition);
            textCurrentPosition.setText(currentPositionStr);

            seekBar.setProgress(currentPosition);
      
            // Ngừng thread 50 mili giây.
            threadHandler.postDelayed(this, 50);
        }
    }

 
    // Khi người dùng Click vào nút tạm dừng (Pause).
    public void doPause(View view)  {
        this.mediaPlayer.pause();
        this.buttonPause.setEnabled(false);
        this.buttonStart.setEnabled(true);
    }

 
    // Khi người dùng Click vào nút tua lại (Rewind)
    public void doRewind(View view)  {
        int currentPosition = this.mediaPlayer.getCurrentPosition();
        int duration = this.mediaPlayer.getDuration();
     
        // 5 giây.
        int SUBTRACT_TIME = 5000;

        if(currentPosition - SUBTRACT_TIME > 0 )  {
            this.mediaPlayer.seekTo(currentPosition - SUBTRACT_TIME);
        }
    }

 
    // Khi người dùng Click vào nút tua đi (Fast-Forward).
    public void doFastForward(View view)  {
        int currentPosition = this.mediaPlayer.getCurrentPosition();
        int duration = this.mediaPlayer.getDuration();
  
        // 5 giây.
        int ADD_TIME = 5000;

        if(currentPosition + ADD_TIME < duration)  {
            this.mediaPlayer.seekTo(currentPosition + ADD_TIME);
        }
    }

}
Chạy ứng dụng:

4- Ví dụ chơi một file video với VideoView

Và bây giờ chúng ta có thể xem một ví dụ với VideoViewMediaController có vị trí nằm trên bề mặt của Video. Bạn có thể xem trước hình ảnh ví dụ sẽ làm dưới đây:
Tạo một Project có tên AndroidVideoView:
Tạo ra một thư mục raw để chứa file video.
Copy & Paste file video mp4 vào thư mục raw:
Thiết kế giao diện:
Kéo thả VideoView vào vị trí chính giữa (Center) của FrameView.
Chú ý rằng FrameLayout chỉ có duy nhất một ô để chứa mọi View con, 9 ô mà bạn nhìn thấy ở trên chỉ là 9 vị trí trọng lực (gravity)
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout 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"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="org.o7planning.androidvideoview.MainActivity">

    <VideoView
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:id="@+id/videoView"
        android:layout_gravity="center" />

</FrameLayout>
MainActivity.java
package org.o7planning.androidvideoview;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.res.Configuration;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnPreparedListener;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.widget.MediaController;
import android.widget.VideoView;

public class MainActivity extends AppCompatActivity {


   private VideoView videoView;
   private int position = 0;
   private MediaController mediaController;


   @Override
   protected void onCreate(Bundle savedInstanceState) {
       super.onCreate(savedInstanceState);
       setContentView(R.layout.activity_main);


       videoView = (VideoView) findViewById(R.id.videoView);

       // Tạo bộ điều khiển
       if (mediaController == null) {
           mediaController = new MediaController(MainActivity.this);

           // Neo vị trí của MediaController với VideoView.
           mediaController.setAnchorView(videoView);


           // Sét đặt bộ điều khiển cho VideoView.
           videoView.setMediaController(mediaController);
       }


       try {
           // ID của file video.
           int id = this.getRawResIdByName("myvideo");
           videoView.setVideoURI(Uri.parse("android.resource://" + getPackageName() + "/" + id));

       } catch (Exception e) {
           Log.e("Error", e.getMessage());
           e.printStackTrace();
       }

       videoView.requestFocus();

       // Sự kiện khi file video sẵn sàng để chơi.
       videoView.setOnPreparedListener(new OnPreparedListener() {

           public void onPrepared(MediaPlayer mediaPlayer) {


               videoView.seekTo(position);
               if (position == 0) {
                   videoView.start();
               }

               // Khi màn hình Video thay đổi kích thước
               mediaPlayer.setOnVideoSizeChangedListener(new MediaPlayer.OnVideoSizeChangedListener() {
                   @Override
                   public void onVideoSizeChanged(MediaPlayer mp, int width, int height) {

                       // Neo lại vị trí của bộ điều khiển của nó vào VideoView.
                       mediaController.setAnchorView(videoView);
                   }
               });
           }
       });

   }

   // Tìm ID ứng với tên của file nguồn (Trong thư mục raw).
   public int getRawResIdByName(String resName) {
       String pkgName = this.getPackageName();
 
       // Trả về 0 nếu không tìm thấy.
       int resID = this.getResources().getIdentifier(resName, "raw", pkgName);
       Log.i("AndroidVideoView", "Res Name: " + resName + "==> Res ID = " + resID);
       return resID;
   }



   // Khi bạn xoay điện thoại, phương thức này sẽ được gọi
   // nó lưu trữ lại ví trí file video đang chơi.
   @Override
   public void onSaveInstanceState(Bundle savedInstanceState) {
       super.onSaveInstanceState(savedInstanceState);

       // Lưu lại vị trí file video đang chơi.
       savedInstanceState.putInt("CurrentPosition", videoView.getCurrentPosition());
       videoView.pause();
   }


   // Sau khi điện thoại xoay chiều xong. Phương thức này được gọi,
   // bạn cần tái tạo lại ví trí file nhạc đang chơi.
   @Override
   public void onRestoreInstanceState(Bundle savedInstanceState) {
       super.onRestoreInstanceState(savedInstanceState);

       // Lấy lại ví trí video đã chơi.
       position = savedInstanceState.getInt("CurrentPosition");
       videoView.seekTo(position);
   }
}
Chạy ứng dụng của bạn:
Một số chú ý với code:
Hình ảnh khi bạn sử dụng setAnchorView() để neo MediaController vào VideoView:
Sử dụng nguồn Video từ URL:
Trước hết bạn phải khai báo quyền truy cập vào Internet ( android.permission.INTERNET) trong AndroidManifest.xml:
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
   package="org.o7planning.androidvideoview">

   <uses-permission android:name="android.permission.INTERNET"></uses-permission>

   <application
       android:allowBackup="true"
       android:icon="@mipmap/ic_launcher"
       android:label="@string/app_name"
       android:supportsRtl="true"
       android:theme="@style/AppTheme">



       <activity android:name=".MainActivity">
           <intent-filter>
               <action android:name="android.intent.action.MAIN" />

               <category android:name="android.intent.category.LAUNCHER" />
           </intent-filter>
       </activity>
   </application>

</manifest>
Java Code:
// Cách 1:

String videoUrl="http://www.youtubemaza.com/files/data/366/Tom%20And%20Jerry%20055%20Casanova%20Cat%20(1951).mp4";        
Uri video = Uri.parse(videoUrl);
videoView.setVideoURI(video);


// Cách 2:

String videoUrl="http://www.youtubemaza.com/files/data/366/Tom%20And%20Jerry%20055%20Casanova%20Cat%20(1951).mp4";    
videoView.setVideoPath(video);