读AN 视频播放器代码后感
2015-02-11 10:45
141 查看
原文出处:http://blog.csdn.net/hellogv/article/details/6429455
我把代码改了一丁点的贴了下: 主要是懒,所以加载了本地的视频
MainActivity.java
另外能够调用getMax必须得加载了seekBar的Max的属性。
这属性在XML文件里面有说明了。
这个SeekBar的max属性不能没有
2、
不断地利用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
我把代码改了一丁点的贴了下: 主要是懒,所以加载了本地的视频
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
相关文章推荐
- Could not create an environment: OCIEnvCreate returned -1(OCIEnvCreate 失败, 返回代码为-1,但错误消息文本不可用)
- 网页视频播放器程序代码(通用代码)
- 如何基于FFMPEG和SDL写一个少于1000行代码的视频播放器
- Could not create an environment: OCIEnvCreate returned -1(OCIEnvCreate 失败, 返回代码为-1,但错误消息文本不可用)
- 视频播放器代码参数详解
- 网页视频播放器代码
- 网页嵌入视频播放器代码大全
- 网页上常用的视频播放器/音乐播放器代码(转载)
- 网页视频播放器代码集
- 网页视频播放器代码大全 网页mtv播放器代码
- 界面还可以的视频播放器代码
- 网页中插入视频播放器代码
- 处理【aspnet_merge.exe”已退出,代码为1。An error occurred when merging assemblies: 索引超出了数组界限。】
- 嵌入视频播放器代码
- 视频播放器html代码大全
- Tooltip 显示大图的代码(show an enlarge image in the tooltip of the image)
- 使用flv播放器 Vcastr 网页视频播放器代码中的参数说明
- 视频播放器常见的html代码
- iphone开发 如何用代码设置视频播放器的音量
- 网页视频播放器代码大全