使用mediaplayer + surfaceview來播放視頻


轉自:http://blog.csdn.net/jiahui524/article/details/7108358


步驟: 

 mediaPlayer+ surfaceView 例子的步驟:
 1,創建一個MediaPlayer,並創建三個按鈕
 2, 創建surfaceView,並設置surfaceView的getHolder.setType和getHolder.addCallback()
 3,在addCallback的三個函數中,這里是如果在播放中建立的,則把positon=0 ,然后重新開始。
 4,在按鈕中設置mediaplayer的播放,大概是:
    mediaPlayer.reset();
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
//設置需要播放的視頻
mediaPlayer.setDataSource("/mnt/sdcard/vid320X240.3gp");
//把視頻畫面輸出到SurfaceView
mediaPlayer.setDisplay(surfaceView.getHolder());   ///關鍵 的地方!!!!!!
mediaPlayer.prepare();
//播放
mediaPlayer.start();
 

xml源代碼:(注意需要三個png格式的圖片,更改名字為play.png pause.png stop.png)

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >

<SurfaceView
android:id="@+id/surfaceView"
android:layout_width="fill_parent"
android:layout_height="360px" />

<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:orientation="horizontal" >

<ImageButton
android:id="@+id/btnplay"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/play" />

<ImageButton
android:id="@+id/btnpause"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/pause" />

<ImageButton
android:id="@+id/btnstop"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/stop" />
</LinearLayout>

</LinearLayout>

java  代碼:

package com.example.tstmediaplaycontroller2;
/*
import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import android.view.MenuItem;
import android.support.v4.app.NavUtils;

public class MainActivity extends Activity {

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

@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}


}*/
import android.app.Activity;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.view.SurfaceHolder;
import android.view.SurfaceHolder.Callback;
import android.view.SurfaceView;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageButton;
import android.widget.Toast;

public class MainActivity extends Activity implements OnClickListener{

ImageButton btnplay, btnstop, btnpause;
SurfaceView surfaceView;
MediaPlayer mediaPlayer;
int position;

public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btnplay=(ImageButton)this.findViewById(R.id.btnplay);
btnstop=(ImageButton)this.findViewById(R.id.btnstop);
btnpause=(ImageButton)this.findViewById(R.id.btnpause);

btnstop.setOnClickListener(this);
btnplay.setOnClickListener(this);
btnpause.setOnClickListener(this);

mediaPlayer=new MediaPlayer();
surfaceView=(SurfaceView) this.findViewById(R.id.surfaceView);

//設置SurfaceView自己不管理的緩沖區
surfaceView.getHolder().setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
surfaceView.getHolder().addCallback(new Callback() {
@Override
public void surfaceDestroyed(SurfaceHolder holder) {

}

@Override
public void surfaceCreated(SurfaceHolder holder) {
if (position>0) {
try {
//開始播放

play();

//並直接從指定位置開始播放
mediaPlayer.seekTo(position);
position=0;
} catch (Exception e) {
// TODO: handle exception
}
}
System.out.println("surface create .............xxxxxxxxxxxxxxxx");

}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {

}
});
}
@Override
public void onClick(View v)
{
switch (v.getId()) {
case R.id.btnplay:
play();
break;

case R.id.btnpause:
if (mediaPlayer.isPlaying())
{
mediaPlayer.pause();
}
else
{
mediaPlayer.start();
}
break;

case R.id.btnstop:
if (mediaPlayer.isPlaying()) {
mediaPlayer.stop();
}

break;
default:
break;
}

}
@Override
protected void onPause() {
//先判斷是否正在播放
if (mediaPlayer.isPlaying()) {
//如果正在播放我們就先保存這個播放位置
position=mediaPlayer.getCurrentPosition()
;
mediaPlayer.stop();
}
super.onPause();
}

private void play() {
try {
mediaPlayer.reset();
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
//設置需要播放的視頻
mediaPlayer.setDataSource("/mnt/sdcard/vid320X240.3gp");
//把視頻畫面輸出到SurfaceView
mediaPlayer.setDisplay(surfaceView.getHolder());
mediaPlayer.prepare();
//播放
mediaPlayer.start();
Toast.makeText(this, "開始播放!", Toast.LENGTH_LONG).show();
} catch (Exception e) {
// TODO: handle exception
}
}
}



注:

MediaPlayer主要用於播放音頻,它是沒有提供輸出圖像的輸出界面,這時我們就用到了SurfaceView控件,將它與MediaPlayer結合起來,就能達到了視頻的輸出了。首先來了SurfaceView這個控件類

SurfaceView類


構造方法

方法名稱

描述

public SurfaceView(Context context)

通過Context創建SurfaceView對象

public SurfaceView(Context context, AttributeSet attrs)

通過Context對象和AttributeSet創建SurfaceView對象

public SurfaceView(Context context, AttributeSet attrs, int defStyle)

通過Context對象和AttributeSet創建並可以指定樣式,SurfaceView對象

 

常用方法

方法名稱

描述

public SurfaceHolder getHolder ()

得到SurfaceHolder對象用於管理SurfaceView

public void setVisibility (int visibility)

設置是否可見,其值可以是VISIBLE, INVISIBLE, GONE.

 

SurfaceHolder


它是一個接口,用於管理SurfaceView。里面有兩個常用的內部接口SurfaceHolder.Callback,SurfaceHolder.Callback2而Callback2是實現於Callback的

常用方法

方法名稱

描述

public abstract void addCallback (SurfaceHolder.Callback callback)

添加一個Callback對象監聽SurfaceView的變化

public abstract void removeCallback (SurfaceHolder.Callback callback)

移除Callback

public abstract void setType (int type)

設置SurfaceView的控制方式

public abstract Canvas lockCanvas ()

鎖定整個SurfaceView對象,獲取該Surface上的Canvas

public abstract Canvas lockCanvas (Rect dirty)

鎖定SurfaceView上Rect划分的區域,獲取該Surface上的Canvas

public abstract void unlockCanvasAndPost (Canvas canvas)

調用該方法,之前所繪制的圖形還處於緩沖之中,下一次的lockCanvas()方法鎖定的區域可能會“遮擋”它

 

SurfaceHolder.CallBack


在Callback里有三個抽象方法

方法名稱

描述

public abstract void surfaceChanged (SurfaceHolder holder, int format, int width, int height)

SurfaceView改變時觸發

public abstract void surfaceCreated (SurfaceHolder holder)

SurfaceView創建時觸發

public abstract void surfaceDestroyed (SurfaceHolder holder)

SurfaceView銷毀時觸發

 

如何理解這幾個類或者接口之間的關系?

這樣理解:

SurfaceView它用於顯示,SurfaceHolder就是用於用來管理這個顯示的SurfaceView對象的,但在SurfaceHolder是怎么樣去管理這個對象的呢?這就用到了SurfceHolder.addCallback()方法添加一個SurfaceHolder接口的內部接口的三個抽象方法用於管理或者說是用於監聽SurfaceView。這樣就達到了管理SurfaceView的目的。

 mediaPlayer 的方法是:


Valid and invalid states

Method Name

Valid Sates

Invalid States

Comments

attachAuxEffect

{Initialized, Prepared, Started, Paused, Stopped, PlaybackCompleted}

{Idle, Error}

This method must be called after setDataSource. Calling it does not change the object state.

getAudioSessionId

any

{}

This method can be called in any state and calling it does not change the object state.

getCurrentPosition

{Idle, Initialized, Prepared, Started, Paused, Stopped, PlaybackCompleted}

{Error}

Successful invoke of this method in a valid state does not change the state. Calling this method in an invalid state transfers the object to the Error state.

getDuration

{Prepared, Started, Paused, Stopped, PlaybackCompleted}

{Idle, Initialized, Error}

Successful invoke of this method in a valid state does not change the state. Calling this method in an invalid state transfers the object to the Error state.

getVideoHeight

{Idle, Initialized, Prepared, Started, Paused, Stopped, PlaybackCompleted}

{Error}

Successful invoke of this method in a valid state does not change the state. Calling this method in an invalid state transfers the object to the Error state.

getVideoWidth

{Idle, Initialized, Prepared, Started, Paused, Stopped, PlaybackCompleted}

{Error}

Successful invoke of this method in a valid state does not change the state. Calling this method in an invalid state transfers the object to the Error state.

isPlaying

{Idle, Initialized, Prepared, Started, Paused, Stopped, PlaybackCompleted}

{Error}

Successful invoke of this method in a valid state does not change the state. Calling this method in an invalid state transfers the object to the Error state.

pause

{Started, Paused}

{Idle, Initialized, Prepared, Stopped, PlaybackCompleted, Error}

Successful invoke of this method in a valid state transfers the object to the Paused state. Calling this method in an invalid state transfers the object to the Error state.

prepare

{Initialized, Stopped}

{Idle, Prepared, Started, Paused, PlaybackCompleted, Error}

Successful invoke of this method in a valid state transfers the object to the Prepared state. Calling this method in an invalid state throws an IllegalStateException.

prepareAsync

{Initialized, Stopped}

{Idle, Prepared, Started, Paused, PlaybackCompleted, Error}

Successful invoke of this method in a valid state transfers the object to the Preparing state. Calling this method in an invalid state throws an IllegalStateException.

release

any

{}

After release(), the object is no longer available.

reset

{Idle, Initialized, Prepared, Started, Paused, Stopped, PlaybackCompleted, Error}

{}

After reset(), the object is like being just created.

seekTo

{Prepared, Started, Paused, PlaybackCompleted}

{Idle, Initialized, Stopped, Error}

Successful invoke of this method in a valid state does not change the state. Calling this method in an invalid state transfers the object to the Error state.

setAudioSessionId

{Idle}

{Initialized, Prepared, Started, Paused, Stopped, PlaybackCompleted, Error}

This method must be called in idle state as the audio session ID must be known before calling setDataSource. Calling it does not change the object state.

setAudioStreamType

{Idle, Initialized, Stopped, Prepared, Started, Paused, PlaybackCompleted}

{Error}

Successful invoke of this method does not change the state. In order for the target audio stream type to become effective, this method must be called before prepare() or prepareAsync().

setAuxEffectSendLevel

any

{}

Calling this method does not change the object state.

setDataSource

{Idle}

{Initialized, Prepared, Started, Paused, Stopped, PlaybackCompleted, Error}

Successful invoke of this method in a valid state transfers the object to the Initialized state. Calling this method in an invalid state throws an IllegalStateException.

setDisplay

any

{}

This method can be called in any state and calling it does not change the object state.

setSurface

any

{}

This method can be called in any state and calling it does not change the object state.

setVideoScalingMode

{Initialized, Prepared, Started, Paused, Stopped, PlaybackCompleted}

{Idle, Error}

Successful invoke of this method does not change the state.

setLooping

{Idle, Initialized, Stopped, Prepared, Started, Paused, PlaybackCompleted}

{Error}

Successful invoke of this method in a valid state does not change the state. Calling this method in an invalid state transfers the object to the Error state.

isLooping

any

{}

This method can be called in any state and calling it does not change the object state.

setOnBufferingUpdateListener

any

{}

This method can be called in any state and calling it does not change the object state.

setOnCompletionListener

any

{}

This method can be called in any state and calling it does not change the object state.

setOnErrorListener

any

{}

This method can be called in any state and calling it does not change the object state.

setOnPreparedListener

any

{}

This method can be called in any state and calling it does not change the object state.

setOnSeekCompleteListener

any

{}

This method can be called in any state and calling it does not change the object state.

setScreenOnWhilePlaying any

{}

This method can be called in any state and calling it does not change the object state.

setVolume

{Idle, Initialized, Stopped, Prepared, Started, Paused, PlaybackCompleted}

{Error}

Successful invoke of this method does not change the state.
setWakeMode

any

{}

This method can be called in any state and calling it does not change the object state.

start

{Prepared, Started, Paused, PlaybackCompleted}

{Idle, Initialized, Stopped, Error}

Successful invoke of this method in a valid state transfers the object to the Started state. Calling this method in an invalid state transfers the object to the Error state.

stop

{Prepared, Started, Stopped, Paused, PlaybackCompleted}

{Idle, Initialized, Error}

Successful invoke of this method in a valid state transfers the object to the Stopped state. Calling this method in an invalid state transfers the object to the Error state.

getTrackInfo

{Prepared, Started, Stopped, Paused, PlaybackCompleted}

{Idle, Initialized, Error}

Successful invoke of this method does not change the state.

addTimedTextSource

{Prepared, Started, Stopped, Paused, PlaybackCompleted}

{Idle, Initialized, Error}

Successful invoke of this method does not change the state.

selectTrack

{Prepared, Started, Stopped, Paused, PlaybackCompleted}

{Idle, Initialized, Error}

Successful invoke of this method does not change the state.

deselectTrack

{Prepared, Started, Stopped, Paused, PlaybackCompleted}

{Idle, Initialized, Error}

Successful invoke of this method does not change the state.




注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
粤ICP备14056181号  © 2014-2020 ITdaan.com