一起学Android之音频视频
概述
Android多媒体框架支持各种常见的媒体类型,可以很容易地将音频、视频和图像集成到App中。通过MediaPlayer Api,可以从应用程序资源(RAW)、文件系统或网络上数据流资源来播放音频或视频。本文演示了如何通过Api播放音频和视频文件,来获得良好性能和愉快的用户体验,仅供学习分享使用,如有不足之处,还请指正。
涉及知识点
- MediaPlayer 可以用来控制audio/video文件或流播放的类。通过此类,可以方便的控制音频/视频文件的播放,暂停和停止等操作。
- Uri 统一资源标识符(Uniform Resource Identifier,或URI)是一个用于标识某一互联网资源名称的字符串。
- VideoView 自带的一种播放视频的组件。
- 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之音频视频的更多相关文章
- 【转】android如何浏览并选择图片 音频 视频
转自:http://www.cnblogs.com/top5/archive/2012/03/06/2381986.html 这几天 在学习并开发android系统的图片浏览 音频 视频 的浏览 ...
- 【视频】零基础学Android开发:蓝牙聊天室APP(四)
零基础学Android开发:蓝牙聊天室APP第四讲 4.1 ListView控件的使用 4.2 BaseAdapter具体解释 4.3 ListView分布与滚动事件 4.4 ListView事件监听 ...
- 【视频】零基础学Android开发:蓝牙聊天室APP(二)
零基础学Android开发:蓝牙聊天室APP第二讲 2.1 课程内容应用场景 2.2 Android UI设计 2.3 组件布局:LinearLayout和RelativeLayout 2.4 Tex ...
- android基础---->音频和视频的使用
Android 在播放音频和视频方面也是做了相当不错的支持,它提供了一套较为完整的API,使得开发者可以很轻松地编写出一个简易的音频或视频播放器.今天我们开始android中音频和视频使用的学习. 目 ...
- 【视频】零基础学Android开发:蓝牙聊天室APP(三)
零基础学Android开发:蓝牙聊天室APP第三讲 3.1 ImageView.ImageButton控件具体解释 3.2 GridView控件具体解释 3.3 SimpleAdapter适配器具体解 ...
- 【视频】零基础学Android开发:蓝牙聊天室APP(一)
零基础学Android开发:蓝牙聊天室APP第一讲 1. Android介绍与环境搭建:史上最高效Android入门学习 1.1 Google的大小战略 1.2 物联网与云计算 1.3 智能XX设备 ...
- 学Android开发 这19个开发工具助你顺风顺水
学Android开发 这19个开发工具助你顺风顺水 要想快速开发一个Android应用,通常会用到很多工具,巧妙利用这些工具,能让我们的开发工作事半功倍,节省大量时间,下面大连Android开发培训小 ...
- android平台短视频技术之 视频编辑的经验分享.
android平台短视频技术之 视频编辑的经验分享. 提示一: 各位看官,这里分享的是视频编辑,即剪切/拼接/分离/合并/涂鸦/标记/叠加/滤镜等对视频的编辑操作.不是流媒体网络播放等功能,请注意. ...
- Android开发 获取视频中的信息(例如预览图或视频时长) MediaMetadataRetriever媒体元数据检索器
前言 在Android里获取视频的信息主要依靠MediaMetadataRetriever实现 获取最佳视频预览图 所谓的最佳就是MediaMetadataRetriever自己计算的 /** * 获 ...
随机推荐
- CCF-CSP题解 201604-4 游戏
bfs #include <bits/stdc++.h> const int maxn = 100; using namespace std; int n, m, t; bool hasD ...
- ajax结合sweetalert实现删除按钮动态效果
目录 一.ajax结合sweetalert实现删除按钮动态效果 二.bulk_create批量插入数据 1. 一条一条插入 2. 批量插入 三.自定义分页器 一.ajax结合sweetalert实现删 ...
- JPA中实现双向一对多的关联关系
场景 JPA入门简介与搭建HelloWorld(附代码下载): https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/103473937 ...
- 百度大脑EdgeBoard计算卡基于Resnet50/Mobile-SSD模型的性能评测
ResNet模型 前言在上一次的测试中,我们从头开始训练了一个三个卷积层串联一个全连接层的输出,作为猫狗分类的预测的模型,这次我们自己训练一个ResNet模型,并在以下三个环境中进行性能的对比 AIS ...
- ORA-27140: attach to post/wait facility failed
Errors in file /home/u01/app/oracle/diag/rdbms/hnybdb21/hnybdb211/trace/hnybdb211_j000_143099.trc:OR ...
- acwing 861. 二分图的最大匹配 模板
地址 https://www.acwing.com/problem/content/description/863/ 给定一个二分图,其中左半部包含n1n1个点(编号1~n1n1),右半部包含n2n ...
- Linux’s init system & systemd
一.init system 1.计算机是如何启动的 以早期 Fedora 系统为例. 1.开机 2.BIOS 和 GRUB(引导加载程序) 3.Linux 内核启动后,init 进程 是在 Fedor ...
- 破解另一家网站的反爬机制 & HMAC 算法
零.写在前面 本文涉及的反爬技术,仅供个人技术学习,禁止并做到: 干扰被访问网站的正常运行 抓取受到法律保护的特定类型的数据或信息 搜集到的数据禁止传播.交给第三方使用.或者牟利 如有可能,在爬到数据 ...
- .NET Core 3.0 Preview 6中对ASP.NET Core和Blazor的更新
我们都知道在6月12日的时候微软发布了.NET Core 3.0的第6个预览版.针对.NET Core 3.0的发布我们国内的微软MVP-汪宇杰还发布的官翻版的博文进行了详细的介绍.具体的可以关注&q ...
- WPF数据可视化-趋势图
环境: 系统: Window 7以上: 工具:VS2013及以上. 研发语言及工程: C# WPF 应用程序 效果: 简介: 不需要调用第三方Dll, 仅仅在WPF中使用贝塞尔曲线,不到500 ...