android 視頻播放的三種方式

      android實現視頻的播放一般有三種方式,一:調用系統的播放器播放;二:利用VideoView播放;三:利用MediaPlayer和SurfaceView播放,此demo分別實現了這三種方式,其中VideoView的方式還支持播放內部存儲raw文件夾下的視頻。


demo:下載地址


MainActivity源碼(實現前兩種方式):

package fk.androiddemo_029;

import android.app.Activity;
import android.content.Intent;
import android.net.Uri;
import android.os.Environment;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.MediaController;
import android.widget.VideoView;

import java.io.File;

public class MainActivity extends Activity implements View.OnClickListener {
    Button but1, but2, but3;
    String SDCardRoot;

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

        but1 = (Button) findViewById(R.id.but1);
        but1.setOnClickListener(this);
        but2 = (Button) findViewById(R.id.but2);
        but2.setOnClickListener(this);
        but3 = (Button) findViewById(R.id.but3);
        but3.setOnClickListener(this);

        //得到當前外部存儲設備的目錄
        SDCardRoot = Environment.getExternalStorageDirectory().getPath() + File.separator;
        //File.separator爲文件分隔符”/“,方便之後在目錄下創建文件
    }

    @Override
    public void onClick(View view) {

        if (view == but1) {//調用系統的默認播放器
            Intent intent = new Intent("android.intent.action.VIEW");
            intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
            Uri uri = Uri.fromFile(new File(SDCardRoot+"test.mp4"));
            intent.setDataAndType(uri, "video/mp4");
            this.startActivity(intent);

        } else if (view == but2) {//VideoView方法
            VideoView videoView = (VideoView)this.findViewById(R.id.videoView);
            videoView.setMediaController(new MediaController(this));//設置控制面板

            //方法一:兩SD,一RAW
            //Uri uri = Uri.parse("android.resource://"+getPackageName()+"/"+R.raw.test);
            //Uri uri = Uri.parse(SDCardRoot+"test.mp4");
            //Uri uri = Uri.fromFile(new File(SDCardRoot+"test.mp4"));
            //videoView.setVideoURI(uri);

            //方法二:一SD,一RAW
            videoView.setVideoPath("android.resource://"+getPackageName()+"/"+R.raw.test);
            //videoView.setVideoPath(SDCardRoot+"test.mp4");

            videoView.start();
            videoView.requestFocus();//請求焦點

        } else {//MediaPlayer和Surface方法
            Intent intent=new Intent(this,VideoSurfaceDemo.class);
            intent.putExtra("videoPath",SDCardRoot+"test.mp4");
            startActivity(intent);
        }
    }

}

VideoSurfaceDemo源碼(實現第三種方式):

package fk.androiddemo_029;

import android.app.Activity;
import android.content.Intent;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.widget.Button;
import android.widget.SeekBar;

import java.io.IOException;
import java.util.Timer;
import java.util.TimerTask;

/**
 * 該實例中使用MediaPlayer完成播放,同時界面使用SurfaceView來實現
 *
 * 這裏我們實現MediaPlayer中很多狀態變化時的監聽器
 *
 * 使用Mediaplayer時,也可以使用MediaController類,但是需要實現MediaController.mediaController接口
 * 實現一些控制方法。
 *
 * 然後,設置controller.setMediaPlayer(),setAnchorView(),setEnabled(),show()就可以了,這裏不再實現
 * @author Administrator
 */
public class VideoSurfaceDemo extends Activity implements View.OnClickListener {
    private SurfaceView surface1;
    private Button start, stop, pause;
    private MediaPlayer mediaPlayer1;
    private int position = 0;
    private SeekBar seekBarVideo;
    Timer timer;
    TimerTask timerTask;
    String videoPath="";
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.video_surface);

        videoPath=getIntent().getStringExtra("videoPath");

        surface1 = (SurfaceView) findViewById(R.id.surface1);
        surface1.getHolder().setKeepScreenOn(true);//設置播放時打開屏幕
        surface1.getHolder().addCallback(new SurfaceViewLis());//設置監聽

        start = (Button) findViewById(R.id.start);
        stop = (Button) findViewById(R.id.stop);
        pause = (Button) findViewById(R.id.pause);
        start.setOnClickListener(this);
        stop.setOnClickListener(this);
        pause.setOnClickListener(this);

        seekBarVideo=(SeekBar)findViewById(R.id.seekBar_video);//進度條
        seekBarVideo.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {
                // TODO Auto-generated method stub
                position=seekBar.getProgress();
                if (mediaPlayer1!=null&&mediaPlayer1.isPlaying()) {
                    mediaPlayer1.seekTo(position);
                }
            }

            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {
                // TODO Auto-generated method stub
            }

            @Override
            public void onProgressChanged(SeekBar seekBar, int progress,
                                          boolean fromUser) {
                // TODO Auto-generated method stub
            }
        });

    }

    @Override
    public void onClick(View view) {
        switch (view.getId()) {
            case R.id.start://從新開始播放
                if(mediaPlayer1==null) play();
                else {
                    mediaPlayer1.seekTo(0);
                    mediaPlayer1.start();
                }
                break;
            case R.id.pause://暫停,播放
                if(mediaPlayer1!=null) {
                    if (mediaPlayer1.isPlaying()) mediaPlayer1.pause();
                    else mediaPlayer1.start();
                }
                break;
            case R.id.stop:
                if(mediaPlayer1!=null){//結束
                    if (mediaPlayer1.isPlaying()) mediaPlayer1.stop();
                    timer.cancel();//停止TimerTask
                    timer.purge();//清理cancel的TimerTask
                    mediaPlayer1.release();// 釋放mediaplayer否則的話會佔用內存
                    mediaPlayer1=null;
                }
                break;
            default:
                break;
        }

    }

    public void play()  {//重新播放函數
        mediaPlayer1 = new MediaPlayer();
        mediaPlayer1.reset();
        mediaPlayer1.setAudioStreamType(AudioManager.STREAM_MUSIC);
        mediaPlayer1.setDisplay(surface1.getHolder());//把視頻輸出到SurfaceView上
        try {
            mediaPlayer1.setDataSource(videoPath);//設置數據
            mediaPlayer1.prepare();
        } catch (IOException e) {
            e.printStackTrace();
        }

        //調整surface寬高,獲取視頻寬高都要在prepare()後調用,否則返回0
        int srceenW=getWindowManager().getDefaultDisplay().getWidth();//屏幕寬
        double hwRadio=(double)mediaPlayer1.getVideoHeight()/(double)mediaPlayer1.getVideoWidth();
        surface1.getHolder().setFixedSize(srceenW,(int)(hwRadio*srceenW));

        int max=mediaPlayer1.getDuration();//返回毫秒,要在prepare()後調用,否則返回-1
        seekBarVideo.setMax(max);//設置進度條的最大值
        timer=new Timer();//用定時器不停更新進度條
        timerTask=new TimerTask() {
            @Override
            public void run() {
                // TODO Auto-generated method stub
                seekBarVideo.setProgress(mediaPlayer1.getCurrentPosition());
            }
        };
        timer.schedule(timerTask, 0, 500);//(調用run方法,第一次延時,以後間隔毫秒)

        mediaPlayer1.start();//開始播放
    }

    private class SurfaceViewLis implements SurfaceHolder.Callback {
        @Override
        public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {}

        @Override
        public void surfaceCreated(SurfaceHolder holder) {
            if (position == 0) play();
        }

        @Override
        public void surfaceDestroyed(SurfaceHolder holder) {}
    }

}


權限:

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


VideoView佈局:

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



SurfaceView佈局:

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


注意:測試文件存放於項目raw文件夾下,和外部存儲的根部錄下。


運行截圖:






發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章