概述

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. Python 分支、循环、条件与枚举

    单行注释:# 注释内容多行注释:''' 注释内容 '''   Python 中有三种控制流语句: if for while 注:Python 中没有 Switch 这种开关语句 if 语句检测条件真, ...

  2. javascript数据结构

    学习数据结构非常重要.首要原因是数据结构和算法可以很高效的解决常见问题.作为前端,通过javascript学习数据结构和算法要比学习java和c版本容易的多. 在讲数据结构之前我们先了解一下ES6的一 ...

  3. JS---DOM---为元素解绑事件

    解绑事件 注意:用什么方式绑定事件, 就应该用对应的方式解绑事件 1.解绑事件 对象.on事件名字=事件处理函数--->绑定事件 对象.on事件名字=null;   //1 对象.on事件名字= ...

  4. Client error attempting to change layout margins of a private view

    从 iOS 11 开始,UINavigationBar 使用了自动布局,左右两边的按钮到屏幕之间会有 16 或 20 的边距. 为了避免点击到间距的空白处没有响应,通常做法是:定义一个 UINavig ...

  5. Python: simple code

    # !/usr/bin/env python3.6 # -*- coding: utf-8 -*- # visual studio 2017 # 2019 10 12 Geovin Du print ...

  6. IT兄弟连 HTML5教程 在移动设备上设置原始大小显示

    在iPhone系列和iPod Touch中使用的是Safari浏览器,它支持前面介绍的媒体查询表达式.例如,使用iPhone 320px×480px的分辨率去访问我们前面的布局示例,却无法得到我们想看 ...

  7. 从0系统学Android--3.7 聊天界面编写

    从0系统学Android--3.7 聊天界面编写 本系列文章目录:更多精品文章分类 本系列持续更新中.... 3.7 编写界面的最佳实践 前面学习了那么多 UI 开发的知识,下面来进行实践,做一个美观 ...

  8. 使用jeecg-boot心得

    使用jeecg-boot心得: Jeect-boot,采用主流最新的开发技术,是个强大的快速开发平台. 刚开始发现jeecg-boot时便对其精致美观的页面深深的迷住了.下载项目运行发现其中也有想要的 ...

  9. mysqld_safe error: log-error set to '/data/log/mysqld.log', however file don't exists. Create writable for user 'mysql'.The server quit without updating PID file (/data/mysql/mysqld.pid)

    [oot@cent65 bin]# service mysqld startStarting MySQL.2019-10-28T15:56:47.786960Z mysqld_safe error: ...

  10. How To Convert A Partitioned Table To A Non-Partitioned Table Using DataPump In 11g (Doc ID 1276049.1)

    How To Convert A Partitioned Table To A Non-Partitioned Table Using DataPump In 11g (Doc ID 1276049. ...