概述

Android多媒体框架支持各种常见的媒体类型,可以很容易地将音频、视频和图像集成到App中。通过MediaPlayer Api,可以从应用程序资源(RAW)、文件系统或网络上数据流资源来播放音频或视频。本文演示了如何通过Api播放音频和视频文件,来获得良好性能和愉快的用户体验,仅供学习分享使用,如有不足之处,还请指正。

涉及知识点

  1. MediaPlayer 可以用来控制audio/video文件或流播放的类。通过此类,可以方便的控制音频/视频文件的播放,暂停和停止等操作。
  2. Uri 统一资源标识符(Uniform Resource Identifier,或URI)是一个用于标识某一互联网资源名称的字符串。
  3. VideoView 自带的一种播放视频的组件。
  4. SurfaceView 可以通过后台绘制显示的视图组件。

Activity中播放音频

页面上播放音频文件,步骤如下:

1. 准备资源文件,并播放

 private MediaPlayer mMediaPlayer;

     /**
* 开始
* @param v
*/
public void bn_start(View v){
if(mMediaPlayer==null) {
ready();
}
mMediaPlayer.start();
} /**
* 创建MediaPlayer并到prepare状态
*/
private void ready(){
if(mMediaPlayer==null){
mMediaPlayer=new MediaPlayer();//Idle
//Log.i("TAG", "ready: "+filePath);
File file=new File(Environment.getExternalStorageDirectory(),"goldfallen.mp3");
Log.i("TAG", "ready: "+file.getPath());
Log.i("TAG", "ready: "+file.exists());
Uri uri= Uri.fromFile(file);
try {
mMediaPlayer.setDataSource(AudioActivity.this,uri);
mMediaPlayer.prepare();//Prepared
} catch (IOException e) {
Log.i("TAG", "ready: "+ e.getMessage());
e.printStackTrace();
}
}
}

2. 暂停播放

 /**
* 暂停
* @param v
*/
public void bn_pause(View v){
if(mMediaPlayer!=null && mMediaPlayer.isPlaying()){
mMediaPlayer.pause();
}
}

3. 停止

   /**
* 停止
* @param v
*/
public void bn_stop(View v){
if(mMediaPlayer!=null && mMediaPlayer.isPlaying()){
mMediaPlayer.stop();
mMediaPlayer.release();
mMediaPlayer=null;
}
}

4. 释放资源(当页面销毁时,播放资源也要同时释放)

  @Override
protected void onDestroy() {
if(mMediaPlayer!=null && mMediaPlayer.isPlaying()){
mMediaPlayer.stop();
mMediaPlayer.release();
mMediaPlayer=null;
}
super.onDestroy();
}

5. 通过静态函数创建对象

 /**
* D:\Android\Project\DemoMedia\app\src\main\res\raw\A2012.mp3:
* Error: 'A' is not a valid file-based resource name character:
* File-based resource names must contain only lowercase a-z, 0-9, or underscore
*/
private void ready2(){
if(mMediaPlayer==null){
mMediaPlayer= MediaPlayer.create(this,R.raw.ab2012);
}
}

通过服务来播放音频

当页面关闭时,音频文件还可以在后台播放。步骤如下:

1. 定义后台服务,当服务启动时,创建MediaPlayer对象,并注册服务接收对象。

 public class AudioService extends Service {

     private MediaPlayer mMediaPlayer;

     private OperatorReceiver mReceiver;

     public AudioService() {
} @Override
public void onCreate() {
super.onCreate();
mMediaPlayer=new MediaPlayer();
mReceiver=new OperatorReceiver();
IntentFilter filter=new IntentFilter("operator.receiver");
registerReceiver(mReceiver,filter);
} @Override
public IBinder onBind(Intent intent) {
return null;
} @Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.i("TAG", "onStartCommand: ----ready ");
ready();
return super.onStartCommand(intent, flags, startId);
} @Override
public void onDestroy() {
if(mMediaPlayer!=null && mMediaPlayer.isPlaying()){
mMediaPlayer.stop();
}
if(mMediaPlayer!=null){
mMediaPlayer.release();
mMediaPlayer=null;
}
unregisterReceiver(mReceiver);
super.onDestroy();
} private void start(){
mMediaPlayer.start();
} private void pause(){
mMediaPlayer.pause();
} private void stop(){
mMediaPlayer.stop();
ready();
} private void ready(){
mMediaPlayer.reset();
try {
String filePath= Environment.getExternalStorageDirectory()+"/ab2012.mp3";
Log.i("TAG", "ready: "+filePath);
File file=new File(filePath);
if(file.exists()) {
mMediaPlayer.setDataSource(filePath);
mMediaPlayer.prepare();
}else{
Log.i("TAG", "ready: 文件不存在 ");
}
} catch (IOException e) {
Log.i("TAG", "ready: "+e.getMessage());
e.printStackTrace();
}
}
}

2. 操作接收者定义如下:

  /**
* 操作接收器
*/
class OperatorReceiver extends BroadcastReceiver
{
@Override
public void onReceive(Context context, Intent intent) {
int cmd=intent.getIntExtra("cmd",-1);
Log.i("TAG", "onReceive: "+cmd);
switch (cmd){
case Tools.PLAY:
start();
break;
case Tools.PAUSE:
pause();
break;
case Tools.STOP:
stop();
break;
default:
start();
break; }
}
}

3. 启动服务

   Intent intent =new Intent(this,AudioService.class);
startService(intent);

4. 前台Activity通过发送广播命令进行控制音频的播放与暂停

 /**
* 开始
* @param v
*/
public void bn_start(View v){
Intent intent=new Intent("operator.receiver");
intent.putExtra("cmd",Tools.PLAY);
sendBroadcast(intent);
Log.i("TAG", "bn_start: "+"service");
} /**
* 暂停
* @param v
*/
public void bn_pause(View v){
Intent intent=new Intent("operator.receiver");
intent.putExtra("cmd",Tools.PAUSE);
sendBroadcast(intent);
} /**
* 停止
* @param v
*/
public void bn_stop(View v){
Intent intent=new Intent("operator.receiver");
intent.putExtra("cmd",Tools.STOP);
sendBroadcast(intent);
}

5.通过后台服务的方式,需要在AndroidManifest.xml文件中进行注册

  <service
android:name=".AudioService"
android:enabled="true"
android:exported="true">
</service>

通过VideoView来播放视频

通过VideoView进行播放视频文件,只需要设置资源URI即可,具体如下:

  private VideoView mVideoView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_video);
mVideoView= (VideoView) this.findViewById(R.id.vv_info);
//设置路径
File file=new File(Environment.getExternalStorageDirectory(),"DCIM/Camera/VID20190629142614.mp4");
Log.i("TAG", "onCreate: "+file.getPath());
if(!file.exists()){
Log.i("TAG", "onCreate: 文件不存在");
}
Uri uri=Uri.fromFile(file);
mVideoView.setVideoURI(uri);
//设置Media Controller
MediaController controller=new MediaController(this);
mVideoView.setMediaController(controller);
//获取焦点
mVideoView.requestFocus();
mVideoView.start();
//设置播放完成事件
mVideoView.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mp) {
Toast.makeText(VideoActivity.this, "播放完毕", Toast.LENGTH_SHORT).show();
}
});
}

通过MediaPlayer来播放视频

通过MediaPlayer来播放视频文件,然后通过SurfaceView来显示视频内容,具体步骤如下:

1.启动,通过setDisplay来设置显示内容

 public  void bn_start(View view)  {
mMediaPlayer.reset();//到Idle状态
//设置路径
File file=new File(Environment.getExternalStorageDirectory(),"DCIM/Camera/VID20190629142614.mp4");
Log.i("TAG", "onCreate: "+file.getPath());
if(!file.exists()){
Log.i("TAG", "onCreate: 文件不存在");
} else {
Log.i("TAG", "onCreate: 文件存在 ");
}
Uri uri=Uri.fromFile(file);
try {
mMediaPlayer.setDataSource(this,uri);
mMediaPlayer.setDisplay(mSurfaceView.getHolder());
mMediaPlayer.prepare();
mMediaPlayer.start();
} catch (IOException e) {
e.printStackTrace();
}
}

2. 暂停与停止

  public  void bn_pause(View view){
if(mMediaPlayer.isPlaying()){
mMediaPlayer.pause();
}
} public void bn_stop(View view){
if(mMediaPlayer.isPlaying()){
mMediaPlayer.stop();
}
}

3. 资源释放

  @Override
protected void onDestroy() {
if(mMediaPlayer!=null && mMediaPlayer.isPlaying()){
mMediaPlayer.stop();
}
if(mMediaPlayer!=null){
mMediaPlayer.release();
mMediaPlayer=null;
}
super.onDestroy();
}

权限设置

如果要播放视频,需要相应的权限设置,并在安装时获取请求权限

     <uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>

备注

合抱之木,生于毫末;九层之台,起于垒土;千里之行,始于足下。

一起学Android之音频视频的更多相关文章

  1. 【转】android如何浏览并选择图片 音频 视频

    转自:http://www.cnblogs.com/top5/archive/2012/03/06/2381986.html   这几天 在学习并开发android系统的图片浏览 音频 视频 的浏览 ...

  2. 【视频】零基础学Android开发:蓝牙聊天室APP(四)

    零基础学Android开发:蓝牙聊天室APP第四讲 4.1 ListView控件的使用 4.2 BaseAdapter具体解释 4.3 ListView分布与滚动事件 4.4 ListView事件监听 ...

  3. 【视频】零基础学Android开发:蓝牙聊天室APP(二)

    零基础学Android开发:蓝牙聊天室APP第二讲 2.1 课程内容应用场景 2.2 Android UI设计 2.3 组件布局:LinearLayout和RelativeLayout 2.4 Tex ...

  4. android基础---->音频和视频的使用

    Android 在播放音频和视频方面也是做了相当不错的支持,它提供了一套较为完整的API,使得开发者可以很轻松地编写出一个简易的音频或视频播放器.今天我们开始android中音频和视频使用的学习. 目 ...

  5. 【视频】零基础学Android开发:蓝牙聊天室APP(三)

    零基础学Android开发:蓝牙聊天室APP第三讲 3.1 ImageView.ImageButton控件具体解释 3.2 GridView控件具体解释 3.3 SimpleAdapter适配器具体解 ...

  6. 【视频】零基础学Android开发:蓝牙聊天室APP(一)

    零基础学Android开发:蓝牙聊天室APP第一讲 1. Android介绍与环境搭建:史上最高效Android入门学习 1.1 Google的大小战略 1.2 物联网与云计算 1.3 智能XX设备 ...

  7. 学Android开发 这19个开发工具助你顺风顺水

    学Android开发 这19个开发工具助你顺风顺水 要想快速开发一个Android应用,通常会用到很多工具,巧妙利用这些工具,能让我们的开发工作事半功倍,节省大量时间,下面大连Android开发培训小 ...

  8. android平台短视频技术之 视频编辑的经验分享.

    android平台短视频技术之 视频编辑的经验分享. 提示一: 各位看官,这里分享的是视频编辑,即剪切/拼接/分离/合并/涂鸦/标记/叠加/滤镜等对视频的编辑操作.不是流媒体网络播放等功能,请注意. ...

  9. Android开发 获取视频中的信息(例如预览图或视频时长) MediaMetadataRetriever媒体元数据检索器

    前言 在Android里获取视频的信息主要依靠MediaMetadataRetriever实现 获取最佳视频预览图 所谓的最佳就是MediaMetadataRetriever自己计算的 /** * 获 ...

随机推荐

  1. MySql数据库之连接查询

    在MySql数据库中连接查询分为以下几种方式: 1.内连接查询 内连接查询通过关键字 inner join 关键字来实现,通过代码实现: select * from 表1 inner join 表2 ...

  2. 办公达人私藏的EXCEL辅助工具,一人抵十人,高效办公就靠它了!

    有很多小伙伴在日常工作中都离不开EXCEL的使用,但EXCEL实在是有太多困难.又复杂的操作,时间紧任务重这一天又废柴了,哎! 别担心,今天将为您分享个逆天强大的EXCEL辅助工具,帮大家快速搞定—— ...

  3. MyBatis结果集一对多映射

    MyBatis结果集一对多映射 需求:重画二维码配置类,根据sizeCode将查询出来的imageCode分组. DROP TABLE IF EXISTS `size_code`; CREATE TA ...

  4. QForkMasterInit: system error caught. error code=0x000005af, message=VirtualAllocEx failed.(遇到还没试过)

    今天在使用Redis的时候出现以下错误: QForkMasterInit: system error caught. error code=0x000005af, message=VirtualAll ...

  5. Jmeter+Ant+Jenkins集成抛出异常java.lang.ClassNotFoundException: javax.mail.internet.MimeMessage

    一.问题描述 二.解决方法 下载javax.mail.jar插件,并将该插件放到%ANT_HOME%\lib目录下即可解决,下载地址:https://javaee.github.io/javamail ...

  6. WPF 3D Cube及点击交互

    在WPF中构建一个简单的立方体比较容易实现,可参考资料也比较众多.比较麻烦的是处理点击交互. 我在WPF中用两种方式实现了3DCube,效果图如下: 方式一: 最常见的3D内容构建模式,结构如下图. ...

  7. telerik reporting 在.net core api 使用

    工具要求:telerik reporting R3 2019..net core 2.2  .vs2017 最新版 从官网下载下来的的telerik reporting 的.net core  例子是 ...

  8. idea个性化配置

    .katex { display: block; text-align: center; white-space: nowrap; } .katex-display > .katex > ...

  9. vue中计算属性的get与set方法

    计算属性get set方法 在vue的计算属性中,所定义的都是属性,可以直接调用 正常情况下,计算属性中的每一个属性对应的都是一个对象,对象中包括了set方法与get方法 computed:{ ful ...

  10. iOS开发中全量日志的获取

    我们在app中对崩溃.卡顿.内存问题进行监控.一旦监控到问题,我们就需要记录下来,但是,很多问题的定位仅靠问题发生的那一刹那记录的信息是不够的,我们需要记录app的全量日志来获取更多的信息. 一,使用 ...