全栈工程师开发手册 (作者:栾鹏)
安卓教程全解

安卓使用MediaPlayer,一般还要配置一个播放画面SurfaceView,和一个进度条SeekBar。

视频的播放会更改进度条的进度,也可以手动更改进度条来调节视频时间。MediaPlayer不想videoview以及集成了SurfaceView和MediaPlayer的相关准备,所以需要手动实现的功能还有很多。这里先实现一个播放器类。完成视频控制的功能。

下面的代码存储为Player.java类,内容中先

package com.lp.app.media;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.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.widget.SeekBar;//自定义视频播放器,使用MediaPlayer播放视频,需要制作视频界面,渲染数据的surfaceView(屏幕缓冲区)、滚动条SeekBar和播放前准备,public class Player implements OnBufferingUpdateListener,OnCompletionListener, MediaPlayer.OnPreparedListener,SurfaceHolder.Callback{private int videoWidth;private int videoHeight;public MediaPlayer mediaPlayer;          //媒体播放器private SurfaceHolder surfaceHolder;  //渲染画面private SeekBar skbProgress;         //播放进度private Timer mTimer=new Timer();public Player(SurfaceView surfaceView,SeekBar skbProgress){this.skbProgress=skbProgress;this.skbProgress.setOnSeekBarChangeListener(new SeekBarChangeEvent());surfaceHolder=surfaceView.getHolder();surfaceHolder.addCallback(this);surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);mTimer.schedule(mTimerTask, 0, 1000);}//通过定时器和Handler来更新进度条TimerTask mTimerTask = new TimerTask() {@Overridepublic void run() {if(mediaPlayer==null)return;if (mediaPlayer.isPlaying() && skbProgress.isPressed() == false) {handleProgress.sendEmptyMessage(0);}}};//主界面接收消息更新进度条uiHandler handleProgress = 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();mediaPlayer.setDataSource(videoUrl);mediaPlayer.prepare();//prepare之后自动播放//mediaPlayer.start();Log.v("mediaPlayer", "在线视频开始播放");} catch (IllegalArgumentException e) {e.printStackTrace();} catch (IllegalStateException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}}//暂停public void pause(){mediaPlayer.pause();}//停止播放public void stop(){if (mediaPlayer != null) { mediaPlayer.stop();mediaPlayer.release(); mediaPlayer = null; } }//跳转到多少毫秒public void seekTo(int ms){mediaPlayer.seekTo(ms);   //加载到多少毫秒}//SurfaceView创建时调用
@Override
public void surfaceCreated(SurfaceHolder holder) {try {mediaPlayer = new MediaPlayer();mediaPlayer.setDisplay(surfaceHolder);mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);mediaPlayer.setOnBufferingUpdateListener(this);mediaPlayer.setOnPreparedListener(this);   //视频准备就绪事件Log.v("mediaPlayer", "视频准备就绪");} catch (Exception e) {Log.e("mediaPlayer", "error", e);}}@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,int height) {Log.v("mediaPlayer", "surface变化");
}@Override
public void surfaceDestroyed(SurfaceHolder holder) {Log.v("mediaPlayer", "surface销毁");
}//视频准备就绪事件,启动播放
@Override
public void onPrepared(MediaPlayer mp) {videoWidth = mediaPlayer.getVideoWidth();videoHeight = mediaPlayer.getVideoHeight();if (videoHeight != 0 && videoWidth != 0) {mp.start();}Log.v("mediaPlayer", "视频启动");
}@Override
public void onCompletion(MediaPlayer mp) {Log.v("mediaPlayer", "视频完成");
}//缓冲进度变化事件(不是播放进度),其中percent是0~100的整数,代表已经缓冲好的多媒体数据的百分比
@Override
public void onBufferingUpdate(MediaPlayer mp, int percent) {skbProgress.setSecondaryProgress(percent);int currentProgress=skbProgress.getMax()*mediaPlayer.getCurrentPosition()/mediaPlayer.getDuration();Log.v("播放进度"+currentProgress+"% play", "缓冲进度"+percent + "% buffer");
}//进度条监控,进度条变化要更改进度显示和视频时间。
class SeekBarChangeEvent implements SeekBar.OnSeekBarChangeListener {int progress;@Overridepublic void onProgressChanged(SeekBar seekBar, int progress,boolean fromUser) {// 原本是(progress/seekBar.getMax())*player.mediaPlayer.getDuration()this.progress = progress * mediaPlayer.getDuration()/seekBar.getMax();}@Overridepublic void onStartTrackingTouch(SeekBar seekBar) {}@Overridepublic void onStopTrackingTouch(SeekBar seekBar) {// seekTo()的参数是相对与影片时间的数字,而不是与seekBar.getMax()相对的数字seekTo(progress);}}}

然后我要自定义实现一个视频播放画面。mediaplay.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="fill_parent"android:layout_height="fill_parent"><LinearLayoutandroid:layout_alignParentTop="true"android:id="@+id/mediaplay_linear"android:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="horizontal" ><Buttonandroid:id="@+id/mediaplay_start"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="启动" /><Buttonandroid:id="@+id/mediaplay_pause"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="暂停" /><Buttonandroid:id="@+id/mediaplay_stop"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="停止" /></LinearLayout><SurfaceViewandroid:layout_below="@id/mediaplay_linear"android:id="@+id/mediaplay_surfaceView"android:layout_width="match_parent"android:layout_height="wrap_content" /><SeekBarandroid:layout_below="@id/mediaplay_linear"android:id="@+id/mediaplay_seekbar"android:layout_width="match_parent"android:layout_height="wrap_content" /></RelativeLayout>

最后再activity中实现播放器类的调用和播放基本控制。
其中用户点击进度条调整观看的时间点,可以写在播放类player中,也可以写在activity中,而且最好写在activity中,因为除了点击进度条除了调整视频时间,可能还会调整其他UI。

package com.lp.app.media;import com.lp.app.R;
import android.app.Activity;
import android.content.Context;
import android.media.MediaPlayer;
import android.net.Uri;
import android.os.Bundle;
import android.view.SurfaceView;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.SeekBar;//使用MediaPlayer播放视频,需要将视频界面,渲染surface和播放前准备,//影片的时间变化,进度条变化,时间的提示变化要同步。用户可以通过进度条控制视频时间跳转.
public class MediaplayActivity extends Activity {Context context;SurfaceView surfaceView;public MediaPlayer mediaPlayer;   //媒体播放器private SeekBar skbProgress;private Player player;private Button btnPause, btnStart, btnStop;@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.mediaplay);context=this;surfaceView = (SurfaceView)findViewById(R.id.mediaplay_surfaceView);btnStart = (Button)findViewById(R.id.mediaplay_start);btnPause = (Button)findViewById(R.id.mediaplay_pause);btnStop = (Button)findViewById(R.id.mediaplay_stop);btnStart.setOnClickListener(new ClickEvent());btnPause.setOnClickListener(new ClickEvent());btnStop.setOnClickListener(new ClickEvent());skbProgress = (SeekBar) this.findViewById(R.id.mediaplay_seekbar);player = new Player(surfaceView, skbProgress);}//点击事件class ClickEvent implements OnClickListener {@Overridepublic void onClick(View view) {if (view == btnPause) {player.pause();} else if (view == btnStart) {String url="http://www.525heart.com/test.mp4";player.playUrl(url);} else if (view == btnStop) {player.stop();}}}

安卓使用MediaPlayer自定义音频视频播放器相关推荐

  1. 移动应用程序设计基础——安卓动画与视音频播放器的实现

    <移动应用程序设计基础>实验6 安卓动画与视音频播放器的实现 实验名称: 实验6 安卓动画与视音频播放器的实现 所使用的工具软件及环境: JDK1.8,Android Studio 一.实 ...

  2. MediaPlayer+SurfaceView实现视频播放器

    我这个人走得很慢,但是我从不后退. 之前给大家分享过使用MediaController类实现视频播放器,今天呢给大家分享可以自定义的视频播放器,那就是使用MediaPlayer+SurfaceView ...

  3. vue自定义音频播放组件_易于创建Vue的自定义音频播放器组件

    vue自定义音频播放组件 音频更好 (vue-audio-better) Easy to create custom audio player components for Vue.js. 易于为Vu ...

  4. android播放器竖屏,SurfaceView + MediaPlayer 实现的视频播放器,支持横竖屏切换,

    MNVideoPlayer SurfaceView + MediaPlayer 实现的视频播放器,支持横竖屏切换,手势快进快退.调节音量,亮度等.之前也发布过一个视频播放列表, 项目截图: 使用步骤: ...

  5. 自定义音频播放器_创建自定义HTML5音频播放器

    自定义音频播放器 在本教程中,我将向您介绍HTML5音频,并向您展示如何创建自己的播放器. 如果您想走捷径,请查看Envato市场上可用的现成的HTML5音频播放器 . 它使您可以从各种来源创建播放列 ...

  6. android音频视频播放器

    最近写了一个android简单的音频视频播放器,顺便开源了 1.扫描sdcard的音乐文件并播放 2.歌词同步功能(只能同步到行,因为是lrc格式,如果需要同步到每一个字,类似kogou那样则需要解析 ...

  7. Video标签自定义简易视频播放器

    Video标签自定义简易视频播放器 提示:以下是本篇文章正文内容,下面案例可供参考 一.Dom结构 <template><el-dialog :title="winTitl ...

  8. 自定义Android视频播放器 - 切换横竖屏

    前一篇自定义了SurfaceView,然后尝试横屏显示,虽然视频适配方面没有问题,但是没有占满整个屏幕. 我分析了一下一般的视频播放器,发现: 竖屏播放视频,播放器的宽度占满手机屏幕的宽度,播放器的高 ...

  9. MediaPlayer+TextureView实现视频播放器

    Android中实现视频播放器的途径有两种: 使用VideoView 通过MediaPlayer + SurfaceView/ TextureView 1. VideoView VideoView使用 ...

最新文章

  1. 售前比售后机器人控制逻辑更复杂,仅凭大规模数据后发优势难赶超!
  2. POJ 2480 (约数+欧拉函数)
  3. android accessibility 模拟键盘事件_H5 键盘兼容性小结
  4. [BZOJ 1588] [HNOI 2002] 营业额统计
  5. 保留小数点后两位小数
  6. python获取命令行参数_【整理】Python中如何获得并处理命令行参数
  7. delphi制作上下开幕效果_显示产业国际盛会开幕,广州新型显示产值将突破2500亿...
  8. Java时间格式转换输出实现代码示例
  9. 一个基于.NET Core3.1的开源项目帮你彻底搞懂WPF框架Prism
  10. es7 如何从项目resource读取index的mapping、setting.json文件
  11. SpringCloud2.0 集成分布式事务管理 LCN
  12. [转载]Android学习网站
  13. 为什么中国程序员工资那么高,连一个 MATLAB 的替代品都开发不出来?
  14. Scikit-learn_聚类算法_K均值聚类
  15. ESXi Arm Edition version 1.11更新,及安装Win11 Arm版
  16. 下载网页上的视频—Flash Video Downloader插件
  17. 湖北物联网产业标准联盟成立
  18. eclipse安装devstyle插件失败问题AN error occurred while colleting items tobe installed
  19. Coding and Paper Letter(六十)
  20. 福利来了!教你们怎么把整个网站的漂亮小姐姐视频都给爬下来!

热门文章

  1. 人物 | 当我们在谈论语音识别时,我们在谈些什么?——知乎达人、CMU博士生王赟...
  2. php10天速成培训,十天学会php之第九天
  3. 面试题 02.01. 移除重复节点(链表删除操作模板)
  4. H.264参考软件JM12.2RC代码详细流程
  5. java 综合练习_Java 之综合练习
  6. 2021牛客暑期多校训练营8,签到题ADEK
  7. 如何进行文件管理、备份
  8. 【编译器】G++相关编译命令
  9. msf 生成php马_PHP的性能优化方法总结
  10. Python入门--第三方模块的安装与使用,pip,import