一起学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自己计算的 /** * 获 ...
随机推荐
- wc命令统计目录下所有文件行数
想统计一下最近一个项目的代码行数,一个一个文件统计显然不是程序员的思维,wc命令可以统计一个文本的行数,结合find命令可以实现我的需求(注意符号):
- 65-如何部署 Calico 网络?
Calico 是一个纯三层的虚拟网络方案,Calico 为每个容器分配一个 IP,每个 host 都是 router,把不同 host 的容器连接起来.与 VxLAN 不同的是,Calico 不对数据 ...
- 防止sql注入的最好方式
避免 SQL injection 攻击的传统方法之一是,把它作为一个输入合法性检查的问题来处理,只接受列在白名单中的字符,或者识别并避免那些列在黑名单中的恶意数据.白名单方法是一种非常有效方法,它可以 ...
- NLP标记集资料
title: 标记集 tags: grammar_cjkRuby: true --- LTP分词标注集 标记 含义 举例 B 词首 __中__国 I 词中 哈__工__大 E 词尾 科__学__ S ...
- idea自用快捷键(非常实用)
最近看了下idea的快捷键,不禁感慨idea真是太强大了,这里记录一下我常用的快捷键 Ctrl+F:在当前文件中查找 Ctrl+R:替换字符串 Alt + shift + 鼠标点击 多处同时编辑 ...
- Cocos Creator | 炮弹发射效果模拟
一.预览效果 二.设置物理世界属性: 1.打开物理系统: cc.director.getPhysicsManager().enabled = true; 2. 配置重力加速度: cc.direct ...
- python3 TensorFlow训练数据集准备 下载一些百度图片 入门级爬虫示例
从百度图片下载一些图片当做训练集,好久没写爬虫,生疏了.没有任何反爬,随便抓. 网页: 动态加载,往下划会出现更多的图片,一次大概30个.先找到保存每一张图片的json,其对应的url: 打开调试,清 ...
- Navicat远程连接MySQL8,必知防坑策略
项目上线是每一个开发工程师面临收获前面抓紧时间开发的成果,但有时我们上线项目首先需要做一些相关的业务测试.通过Xshell远程连接后使用命令行的方式连接操作Mysql这个没什么太大的你问题.但每次通过 ...
- maven 解决jar包冲突及简单使用
maven 解决jar包冲突 1.jar包冲突原因 maven中使用坐标导入jar包时会把与之相关的依赖jar包导入(导入spring-context的jar时就会把spring的整个主体导入) ,而 ...
- iOS-----------安装fir-cli错误
1.在终端执行 gem install fir-cli 一直提示错误: You don't have write permissions for the /Library/Ruby/Gems/ ...