您的位置:首页 > 编程语言

读AN 视频播放器代码后感

2015-02-11 10:45 141 查看
原文出处:http://blog.csdn.net/hellogv/article/details/6429455

我把代码改了一丁点的贴了下: 主要是懒,所以加载了本地的视频

MainActivity.java

package com.example.mymediaplayer4video;

import java.io.File;

import android.app.Activity;
import android.content.pm.ActivityInfo;
import android.os.Bundle;
import android.os.Environment;
import android.view.SurfaceView;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.SeekBar;

public class MainActivity extends Activity {
private SurfaceView surfaceView;
private Button btnPause,btnPlayUrl,btnStop;
private SeekBar skbProgress;
private Player player;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
surfaceView = (SurfaceView)findViewById(R.id.surfaceView1);
btnPlayUrl = (Button)findViewById(R.id.btnPlayUrl);
btnPlayUrl.setOnClickListener(new ClickEvent());
btnPause = (Button)findViewById(R.id.btnPause);
btnPause.setOnClickListener(new ClickEvent());
skbProgress = (SeekBar)findViewById(R.id.skbProgress);
skbProgress.setOnSeekBarChangeListener(new SeekBarChangeEvent());
player = new Player(surfaceView,skbProgress);

}
public String getSdcardDir(){
File sdDir = null;
boolean sdcardExist = Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED);
if(sdcardExist)
sdDir = Environment.getExternalStorageDirectory();
return sdDir.toString();
}
class ClickEvent implements OnClickListener{
@Override
public void onClick(View v){
if(v==btnPause)
player.pause();
else if(v==btnPlayUrl){
String initDir = getSdcardDir();
String url=initDir+"/wildlife.mp4";
player.playUrl(url);
}else if(v==btnStop)
player.stop();

}
}
class SeekBarChangeEvent implements SeekBar.OnSeekBarChangeListener{
int progress;
@Override
public void onProgressChanged(SeekBar seekBar ,int progress,boolean fromUser){
this.progress = progress * player.mediaPlayer.getDuration()/seekBar.getMax();

}
@Override
public void onStartTrackingTouch(SeekBar seekBar){

}
@Override
public void onStopTrackingTouch(SeekBar seekBar){
player.mediaPlayer.seekTo(progress);
}
}

}
小结:mediaPlayer.seekTo函数参数为片源的时刻。这个函数使得可以从到随意拖动到的位置开始播放。

另外能够调用getMax必须得加载了seekBar的Max的属性。

这属性在XML文件里面有说明了。

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

<SurfaceView
android:id="@+id/surfaceView1"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
</SurfaceView>

<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:orientation="vertical" >

<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginTop="4.0dip"
android:orientation="horizontal" >

<Button
android:id="@+id/btnPlayUrl"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="play" >
</Button>

<Button
android:id="@+id/btnPause"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="pause" >
</Button>

<Button
android:id="@+id/btnStop"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="stop" >
</Button>
</LinearLayout>

<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="20dip" >

<SeekBar
android:id="@+id/skbProgress"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_weight="1.0"
android:paddingLeft="10dip"
android:paddingRight="10dip"
android:max="100" >
</SeekBar>
</LinearLayout>
</LinearLayout>

</FrameLayout>


这个SeekBar的max属性不能没有

package com.example.mymediaplayer4video;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Timer;
import java.util.TimerTask;

import android.media.AudioManager;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnBufferingUpdateListener;
import android.media.MediaPlayer.OnCompletionListener;
import android.os.Handler;
import android.os.Message;
import android.provider.MediaStore.Audio;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.widget.SeekBar;

public class Player implements OnBufferingUpdateListener,
OnCompletionListener,MediaPlayer.OnPreparedListener,
SurfaceHolder.Callback{
private int videoWidth,videoHeight;
public MediaPlayer mediaPlayer;
private SurfaceHolder surfaceHolder;
private SeekBar skbProgress;
private Timer mTimer = new Timer();
public Player(SurfaceView surfaceView,SeekBar skbProgress){
this.skbProgress =skbProgress;
surfaceHolder =surfaceView.getHolder();
surfaceHolder.addCallback(this);
surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
mTimer.schedule(mTimerTask, 0,1000);
}
TimerTask mTimerTask = new TimerTask() {

@Override
public void run() {
// TODO Auto-generated method stub
if(mediaPlayer==null)
return ;
if(mediaPlayer.isPlaying()&&skbProgress.isPressed()==false){
handlerProgress.sendEmptyMessage(0);
}

}
};

Handler handlerProgress = new Handler(){
public void handleMessage(Message msg){
int position = mediaPlayer.getCurrentPosition();
int duration = mediaPlayer.getDuration();
if(duration >0){
long pos = skbProgress.getMax()*position/duration;
skbProgress.setProgress((int)pos);
}
}
};
public void play(){
mediaPlayer.start();
}
public void playUrl(String videoUrl){
try{
mediaPlayer.reset();
File file = new File(videoUrl);
FileInputStream fis = new FileInputStream(file);
mediaPlayer.setDataSource(fis.getFD());
mediaPlayer.prepare();
}catch(IllegalArgumentException e){
e.printStackTrace();
}catch(IOException e){
e.printStackTrace();
}catch(IllegalStateException e){
e.printStackTrace();
}
}
public void pause(){
mediaPlayer.pause();
}
public void stop(){
if(mediaPlayer!=null){
mediaPlayer.stop();
mediaPlayer.release();
mediaPlayer=null;
}
}
@Override
public void surfaceChanged(SurfaceHolder sfh,int a1,int a2,int a3){

}
@Override
public void surfaceCreated(SurfaceHolder a){
try{
mediaPlayer = new MediaPlayer();
mediaPlayer.setDisplay(surfaceHolder);
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mediaPlayer.setOnBufferingUpdateListener(this);
mediaPlayer.setOnPreparedListener(this);
}catch(Exception e){
e.printStackTrace();
}
}
@Override
public void surfaceDestroyed(SurfaceHolder a){

}
@Override
public void onPrepared(MediaPlayer a){
videoWidth = mediaPlayer.getVideoWidth();
videoHeight = mediaPlayer.getVideoHeight();
if(videoHeight !=0 && videoHeight !=0){
a.start();
}
}
@Override
public void onCompletion(MediaPlayer a){

}

@Override
public void onBufferingUpdate(MediaPlayer a,int bufferingProgress){
skbProgress.setSecondaryProgress(bufferingProgress);
int currentProgress = skbProgress.getMax()*mediaPlayer.getCurrentPosition()/
mediaPlayer.getDuration();
}
}
1、
setAudioStreamType
     指定流媒体的类型

2、

mTimer.schedule(mTimerTask, 0,1000);
     开启了一个线程,每秒执行一次。

     不断地利用handler来刷新进度条。前提是还在播放视频

3、

public abstract void setType (int type)
设置Surface的类型,接收如下的参数:
SURFACE_TYPE_NORMAL:用RAM缓存原生数据的普通Surface
SURFACE_TYPE_HARDWARE:适用于DMA(Direct memory access )引擎和硬件加速的Surface
SURFACE_TYPE_GPU:适用于GPU加速的Surface
SURFACE_TYPE_PUSH_BUFFERS:表明该Surface不包含原生数据,Surface用到的数据由其他对象提供,在Camera图像预览中就使用该类型的Surface,有Camera负责提供给预览Surface数据,这样图像预览会比较流畅。如果设置这种类型则就不能调用lockCanvas来获取Canvas对象了。需要注意的是,在高版本的Android
SDK中,setType这个方法已经被depreciated了。

4、
   SurfaceHolder是一个接口,其作用就像一个关于Surface的监听器。在SurfaceView中有一个方法getHolder,可以很方便地获得SurfaceView所对应的Surface所对应的SurfaceHolder。
 
 所有SurfaceView和SurfaceHolder.Callback中声明的方法,必须在运行SurfaceView窗口中的线程中调用(典型地,就是应用的主线程。译注:即UI线程),因为它们需要正确地将同时被绘制线程访问的各种状态进行同步

 
 从设计模式的高度来看,Surface、SurfaceView和SurfaceHolder实质上就是广为人知的MVC,即Model-View-Controller。Model就是模型的意思,或者说是数据模型,或者更简单地说就是数据,也就是这里的Surface;View即视图,代表用户交互界面,也就是这里的SurfaceView;SurfaceHolder很明显可以理解为MVC中的Controller(控制器)。这样看起来三者之间的关系就清楚了很多。

3、4 出处:http://blog.csdn.net/pathuang68/article/details/7351317
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: