MediaPlayer简单使用,绑定surfaceView实现播放视频的功能
转载自
Android MediaPlayer使用方法简单介绍
播放音频
android中播放音频可以使用MediaPlayer类来实现,一下是它的一些方法:
方法名 功能描述
setDataSource() 设置要播放的音频文件的位置。
prepare() 在开始播放之前调用这个方法完成准备工作。
start() 开始或继续播放音频。
pause() 暂停播放音频。
reset() 将 MediaPlayer 对象重置到刚刚创建的状态。
seekTo() 从指定的位置开始播放音频。
stop() 停止播放音频。调用这个方法后的 MediaPlayer 对象无法再播放音频。
release() 释放掉与 MediaPlayer 对象相关的资源。
isPlaying() 判断当前 MediaPlayer 是否正在播放音频。
getDuration() 获取载入的音频文件的时长。
m_mediaPlayer.setDataSource(fileDescriptor.getFileDescriptor(),fileDescriptor.getStartOffset(), fileDescriptor.getLength());
1、创建MediaPlayer实例
有两种创建MediaPlayer实例的办法,
办法1:
MediaPlayer player = MediaPlayer.Create(this, Resource.Raw.test);
用MediaPlayer.Create创建实例时可直接指定数据源。
办法2:
MediaPlayer player = new MediaPlayer();
2、数据源
有3种。
(1)播放raw文件夹下的资源文件
应用程序自带的音乐资源一般保存到raw文件夹下,下面的代码演示了如何播放Resource/raw下的媒体文件:
MediaPlayer mPlayer=MediaPlayer.Create(this, Resource.Raw.MyAudio);
mPlayer.Start();
注意:这种方式主要适用于播放应用程序自带的容量较小的资源文件,例如接听电话时播放的音乐、按键音、开机启动音、信息提示音等都可以随应用程序一块发布。
(2)播放来自文件系统的媒体文件
指播放Android默认的系统标准文件夹下、Assets文件夹下、SD卡中的媒体文件,这些文件都属于文件系统。
以下描述了使用MediaPlayer从文件系统中播放音频的步骤:
- 初始化MediaPlayer对象。
- 通过SetDataSource方法(同步方式)或者SetDataSourceAsync方法(异步方式)设置要播放的文件。
- 调用Prepare方法(同步方式)或者PrepareAsync方法(异步方式)初始化播放器。
- 调用Start方法开始音频播放。
- 注意采用这种方式时,播放顺序非常重要:先设置数据源、同步播放设备,最后再调用Start方法播放。
利用MediaPlayer与surfaceView相结合实现视频播放的效果
- 加载本地资源
- /**加载本地资源
- * 主要步骤:
- * 1.创建MediaPlayer播放器
- * 1.MediaPlayer.create(this,"本地资源文件");
- * 2.得到SurfaceHolder对象,surfaceView.getHolder()
- * 3.surfaceHolder绑定生命周期 surfaceHodler.addCallBack(new CallBack(){...})
- * 4.在surfaceHolder监听的回调里面,与视频播放器进行绑定(surfaceCreated)
- * mediaPlayer.setDisplay(surfaceHolder)
- * 5.视频播放器播放视频
- * mediaPlayer.start();
- */
- 加载网络资源
- /**
- * 加载网络资源
- *主要步骤:
- * 1.创建MediaPlayer播放器
- * new MediaPlayer();
- * 2.设置数据源
- * mediaPlayer.setDataSource(context,uri);
- * // meidaPlayer.setDataSource(path)
- * 3. .得到SurfaceHolder对象,surfaceView.getHolder()
- * 4.surfaceHolder绑定生命周期 surfaceHodler.addCallBack(new CallBack(){...})
- * 5.在surfaceHolder监听的回调里面,与视频播放器进行绑定(surfaceCreated)
- * mediaPlayer.setDisplay(surfaceHolder)
- * 6.准备
- * mediaPlayer.prepareAsync()//异步准备
- * mediaPlayer.prepare()//同步准备
- * 7.设置准备监听器
- * mediaPlayer.setOnPreparedListener(new PreparedListener(){});
- * 8.在准备监听器里开启mediaPlayer
- * mediaPlayer.start();
- *
- *
- * //注意:
1.加载网络资源出现了bug,原因:设置异步准备时,会调用准备监听器来开启媒体播放器,同时主线程也会继续执行,通过播放器获取时长时,会出现媒体播放器无效的错误,因为播放器还没有开启播放.
解决:将异步准备后的操作都放在准备监听里面实现,
2.meidiaPlayer调用stop方法后可以再次播放视频,但需要用reset让meidiaPlayer对象回到初始状态,再重新设置资源- *
- */
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"
- tools:context="fanggao.qf.surfaceview_vedioplayer.MainActivity">
- <FrameLayout
- android:id="@+id/fl_layout"
- android:layout_width="match_parent"
- android:layout_height="300dp">
- <SurfaceView
- android:id="@+id/surfaceView"
- android:layout_width="match_parent"
- android:layout_height="300dp" />
- <ImageView
- android:id="@+id/iv_play"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:src="@android:drawable/ic_media_play"/>
- </FrameLayout>
- <LinearLayout
- android:layout_width="match_parent"
- android:layout_height="50dp"
- android:layout_below="@id/fl_layout">
- <ImageView
- android:id="@+id/iv_play_controll"
- android:layout_width="wrap_content"
- android:layout_height="match_parent"
- android:src="@android:drawable/ic_media_play"/>
- <SeekBar
- android:id="@+id/sb_progress"
- android:layout_width="0dp"
- android:layout_height="match_parent"
- android:layout_weight="1"/>
- <TextView
- android:id="@+id/tv_time"
- android:layout_width="wrap_content"
- android:layout_height="match_parent"
- android:text="00:00:00/00:00:00"
- android:gravity="center_vertical"/>
- </LinearLayout>
- </RelativeLayout>
案列分析:
- /**
- * 1.初始化控件
- * 0.初始化媒体播放器
- * 1.准备资源,并创建播放器
- * 1.找到surfaceView,并创建生命周期
- * 1.创建surfaceView
- * 1.surfaceView跟视频播放控件绑定
- * 2.销毁surfaceView
- * 释放资源
- * 2.播放图标显示
- * 3.控制台显示播放图标
- * 2.初始化事件
- * 1.点击播放按钮-变为播放
- * 1.当前播放按钮隐藏
- * 2.控制条显示暂停图标
- * 3.视频开始播放
- *
- * 2.点击控制台
- * 1.点击播放
- * 1.控制台显示暂停图标
- * 2.隐藏当前的播放按钮
- * 3.视频开始播放
- * 2.点击暂停
- * 1.控制台按钮显示播放图标
- * 2..当前播放按钮显示
- * 3.视频暂停播放
- * 3.拖到进度条
- * 1.跳到对应的位置播放
- * 2.更新时间
- *
- * 3.初始化动态视图
- * 2.更新控制台显示
- * 1..拿到视频总长度
- * 1.开启线程
- * 1.更新seekBar进度
- * 1.拿到当前进度
- * 2.计算当前seekBar的值
- * 3.发送到主线程
- * 4.更新
- * 1.更新seekBar的值
- * 2.更新时间进度
- * 1s更新一次
- * 3.播放完成设置监听
- * 4.释放资源
- */
源代码:
- public class MainActivity extends AppCompatActivity implements SurfaceHolder.Callback,View.OnClickListener,SeekBar.OnSeekBarChangeListener,MediaPlayer.OnCompletionListener{
- /*显示视频资源*/
- private SurfaceView surfaceView;
- /*拖动条显示当前进度*/
- private SeekBar sb_progress;
- /*surface的控制器,用来操纵surfaceView。处理它的Canvas上画的效果和动画,控制表面,大小,像素等。*/
- private SurfaceHolder holder;
- /*媒体播放器播放音频*/
- private MediaPlayer mediaPlayer;
- //显示暂停播放图标
- private ImageView imgPlay;
- //控制台显示暂停播放图标
- private ImageView imgControll;
- /*视频总长度*/
- private int duration;
- /*handler发送的成功的标识*/
- private final int UPDATE_PROGRESS = 0;
- /*让线程开始和结束的标记*/
- private boolean flag;
- /*设置显示的图片*/
- private TextView tvTime;
- /*更新进度条和时间*/
- private Handler handler = new Handler(){
- @Override
- public void handleMessage(Message msg) {
- switch (msg.what){
- case UPDATE_PROGRESS:
- int currentPosition = (int) msg.obj;
- Log.i("tag", "handleMessage: "+currentPosition);
- //更新seekBar
- sb_progress.setProgress(currentPosition);
- //更新时间
- updateTime(currentPosition,duration);
- break;
- default:
- break;
- }
- }
- };
- private UpdateThread updateThread;
- /**
- * 更新时间
- * @param currentPosition
- * @param duration
- */
- private void updateTime(int currentPosition, int duration) {
- tvTime.setText(formatTime(currentPosition)+"/"+formatTime(duration));
- }
- /**
- * 格式化时间
- * @param time
- * @return
- */
- private String formatTime(int time) {//格式化时间为00:00:00
- //两位数,小于两位数自动补0 例 09:09:00
- String format = "%02d:%02d:%02d";
- //time为ms
- int hour = time/1000/3600;
- int minute = time/1000%3600/60;
- int second = time/1000%60;
- return String.format(format,hour,minute,second);
- }
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- //初始化视频资源
- mediaPlayer =MediaPlayer.create(this,R.raw.hello);
- initView();
- initEvent();
- //获取视频的总长度(ms)
- duration = mediaPlayer.getDuration();
- //为seekBar设置初始值
- sb_progress.setMax(duration);
- }
- /**
- * 进度条拖动监听
- * @param seekBar
- * @param progress
- * @param fromUser
- */
- @Override
- public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
- }
- @Override
- public void onStartTrackingTouch(SeekBar seekBar) {
- }
- @Override
- public void onStopTrackingTouch(SeekBar seekBar) {
- //播放器跳到对应位置
- mediaPlayer.seekTo(seekBar.getProgress());
- }
- /**
- * 播放完成的时候监听
- * @param mp
- */
- @Override
- public void onCompletion(MediaPlayer mp) {
- //重置
- int position = 0;
- //让视频跳到最开始并暂停
- mp.seekTo(position);
- Message obtain = Message.obtain();
- obtain.what = UPDATE_PROGRESS;
- obtain.obj = position;
- handler.sendMessage(obtain);
- imgPlay.setVisibility(View.VISIBLE);
- imgControll.setImageResource(android.R.drawable.ic_media_play);
- }
- class UpdateThread extends Thread{
- @Override
- public void run(){
- while(flag){
- //获得当前的进度
- int currentPosition = mediaPlayer.getCurrentPosition();
- Message message = Message.obtain();
- message.what = UPDATE_PROGRESS;
- //计算seekbar的值
- message.obj = currentPosition;
- //handler发送进度
- handler.sendMessage(message);
- //1s一次
- SystemClock.sleep(1000);
- }
- }
- }
- private void initEvent() {
- //暂停按钮点击监听,点击播放视频或者暂停视频
- imgControll.setOnClickListener(this);
- imgPlay.setOnClickListener(this);
- //拖动监听,跳到对应的位置
- sb_progress.setOnSeekBarChangeListener(this);
- //播放完成监听,重置播放器,进度
- mediaPlayer.setOnCompletionListener(this);
- }
- private void initView() {
- surfaceView = (SurfaceView) findViewById(R.id.surfaceView);
- sb_progress = (SeekBar) findViewById(R.id.sb_progress);
- imgPlay= (ImageView) findViewById(R.id.iv_play);
- imgControll = (ImageView) findViewById(R.id.iv_play_controll);
- tvTime = (TextView) findViewById(R.id.tv_time);
- //surfaceView绑定生命周期
- holder = surfaceView.getHolder();
- holder.addCallback(this);
- //设置默认值
- imgPlay.setVisibility(View.VISIBLE);
- imgControll.setImageResource(android.R.drawable.ic_media_play);
- }
- /**
- * surfaceViewa绑定生命周期需要回调的方法
- * @param holder
- */
- @Override
- public void surfaceCreated(SurfaceHolder holder) {
- //播放器绑定surfaceView
- mediaPlayer.setDisplay(holder);
- //开启线程
- updateThread = new UpdateThread();
- updateThread.start();
- flag = true;
- }
- @Override
- public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
- }
- @Override
- public void surfaceDestroyed(SurfaceHolder holder) {
- //关闭线程,释放资源
- flag = false;
- if(mediaPlayer != null){
- mediaPlayer.stop();
- mediaPlayer.release();
- mediaPlayer = null;
- }
- }
- @Override
- public void onClick(View v) {
- switch (v.getId()){
- case R.id.iv_play:
- imgPlay.setVisibility(View.GONE);
- imgControll.setImageResource(android.R.drawable.ic_media_pause);
- mediaPlayer.start();
- break;
- case R.id.iv_play_controll:
- if(mediaPlayer.isPlaying()){//正在播放--暂停按钮
- imgPlay.setVisibility(View.VISIBLE);
- imgControll.setImageResource(android.R.drawable.ic_media_play);
- mediaPlayer.pause();
- }else{//暂停播放
- imgPlay.setVisibility(View.GONE);
- imgControll.setImageResource(android.R.drawable.ic_media_pause);
- mediaPlayer.start();
- }
- break;
- }
- }
- @Override
- protected void onDestroy() {
- //
- super.onDestroy();
- }
- }
效果:
MediaPlayer简单使用,绑定surfaceView实现播放视频的功能的更多相关文章
- 使用MediaPlayer类和SurfaceView来播放视频
MediaPlayer可以播放视频,只需需要SurfaceView的配合,SurfaceView主要用于显示MediaPlayer播放的视频流媒体的画面渲染. SurfaceView是配合MediaP ...
- 运用surfaceView与MediaPlayer实现播放视频的功能
该程序运用了surfaceView与MediaPlayer结合,实现播放视频,surfaceView详情请见 SurfaceView的使用 使用了第三方包Volly里面的方法StringQueue下载 ...
- android SurfaceView中播放视频 按视频的原始比例播放
OnPreparedListener mediaPlayerOnPreparedListener = new OnPreparedListener() { @Override public void ...
- Android--SurfaceView播放视频
前言 本篇博客讲解一下如何在Android下,使用SurfaceView播放一个视频流媒体.之前有讲到如何使用MediaPlayer播放音频流媒体,其实MediaPlayer还可以播放视频,只需需要S ...
- android 98 MediaPlayer+SurfaceView播放视频
package com.itheima.videoplayer; import java.io.IOException; import android.media.MediaPlayer; impor ...
- WPF播放视频
在现在的项目中需要使用到播放视频的功能,本来打算使用VLC来做的.后来发现WPF 4.0之后新增了MediaElement类,可以实现视频播放. <Grid> <Grid.RowDe ...
- [转]Android WebView播放视频(包括全屏播放),androidwebview
Android WebView播放视频(包括全屏播放),androidwebview 最近项目开发中用到了WebView播放视频的功能,总结了开发中犯过的错误,这些错误在开发是及容易遇到的,所以我这里 ...
- 使用MediaPlayer和SurfaceView播放视频
使用VideoView播放视频简单.方便,丹有些早期的开发者更喜欢使用MediaPlayer来播放视频,但由于MediaPlayer主要用于播放音频,因此它没有提供图像输出界面,此时 需要借助于Sur ...
- Android MediaPlayer和SurfaceView播放视频
昨天介绍了VideoView播放视频,今天再介绍一种播放视频的方法MediaPlayer和SurfaceView,MediaPlayer播放音频,SurfaceView来显示图像,具体步骤如下: 1. ...
随机推荐
- Dapper基础用法
假如你喜欢原生的Sql语句,又喜欢ORM的简单,那你一定会喜欢上Dapper这款ROM.点击下载Dapper的优势:1,Dapper是一个轻型的ORM类.代码就一个SqlMapper.cs文件,编译后 ...
- 软件工程第一次个人项目——词频统计by11061153柴泽华
一.预计工程设计时间 明确要求: 15min: 查阅资料: 1h: 学习C++基础知识与特性: 4-5h: 主函数编写及输入输出部分: 0.5h: 文件的遍历: 1h: 编写两种模式的词频统计函数: ...
- JDBC学习笔记(8)——数据库连接池(dbcp&C3P0)
JDBC数据库连接池的必要性 一.在使用开发基于数据库的web程序时,传统的模式基本是按一下步骤: 1)在主程序(如servlet/beans)中建立数据库连接 2)进行sql操作 3)断开数据库连接 ...
- Android实例-屏幕操持常亮(XE8+小米2)
相关资料: http://www.bubuko.com/infodetail-163304.html 结果: 1.打开权限Wake lock为True. 第三方单元: unit Android.JNI ...
- oracle中DECODE与CASE的用法区别
对于CASE与DECODE其实并没有太多的区别,他们都是用来实现逻辑判断.Oracle的DECODE函数功能很强,灵活运用的话可以避免多次扫描,从而提高查询的性能.而CASE是9i以后提供的语法,这个 ...
- UVALive 7278 Game of Cards (sg函数)
Game of Cards 题目链接: http://acm.hust.edu.cn/vjudge/contest/127406#problem/G Description Alice and Bob ...
- mysql优化(一)
1.选取最适用的字段属性 MySQL可以很好的支持大数据量的存取,但是一般说来,数据库中的表越小,在它上面执行的查询也就会越快.因此,在创建表的时候,为了获得更好的性能,我们可以将表中字段的宽度设得 ...
- [Xcode使用 - 3] 复制Xcode5.1.1中的项目模板到Xcode6.1
由于Xcode6中精简了许多的项目和文件模板,导致开发非常不方便,所以这里简单介绍了怎么复制旧版本Xcode中的模板到新的Xcode中 这里要复制的是项目模板Empty Appli ...
- php-fpm占用系统资源分析
故障检测 1.别的先不管,先top看一下cpu.ram.swap哪个比较紧张. 由上图分析,可以看出共有602个进程,其中有601个进程休眠了.这好像有点不对劲,内核进程也就80个左右,加上memca ...
- Tomcat参数配置
一.调整JVM参数 JAVA_OPTS= -server -Xms256m -Xmx1024m 注: -server: 启用服务器模式 一定要作为第一个参数,如果CPU多,服务器机建议使用此项 -Xm ...