android中录音断点播放,Android实现语音播放与录音功能
本文实例为大家分享了Android实现语音播放与录音的具体代码,供大家参考,具体内容如下
项目用到的技术点和亮点
语音录音 (单个和列表)
语音播放(单个和列表)
语音录音封装
语音播放器封装
语音列表顺序播放
语音列表单个播放 复用问题处理
因为安装原生录音不能录mp3格式文件 而mp3格式是安卓和ios公用的,所以我们需要的是能直接录取mp3文件或者录完的格式转成mp3格式
下面添加这个库 能直接录mp3文件,我觉得是最方便的
compile ‘com.czt.mp3recorder:library:1.0.3'
1. 语音录音封装
代码简单 自己看吧
package com.video.zlc.audioplayer;
import com.czt.mp3recorder.MP3Recorder;
import com.video.zlc.audioplayer.utils.LogUtil;
import java.io.File;
import java.io.IOException;
import java.util.UUID;
/**
* @author zlc
*/
public class AudioManage {
private MP3Recorder mRecorder;
private String mDir; // 文件夹的名称
private String mCurrentFilePath;
private static AudioManage mInstance;
private boolean isPrepared; // 标识MediaRecorder准备完毕
private AudioManage(String dir) {
mDir = dir;
LogUtil.e("AudioManage=",mDir);
}
/**
* 回调“准备完毕”
* @author zlc
*/
public interface AudioStateListenter {
void wellPrepared(); // prepared完毕
}
public AudioStateListenter mListenter;
public void setOnAudioStateListenter(AudioStateListenter audioStateListenter) {
mListenter = audioStateListenter;
}
/**
* 使用单例实现 AudioManage
* @param dir
* @return
*/
public static AudioManage getInstance(String dir) {
if (mInstance == null) {
synchronized (AudioManage.class) { // 同步
if (mInstance == null) {
mInstance = new AudioManage(dir);
}
}
}
return mInstance;
}
/**
* 准备录音
*/
public void prepareAudio() {
try {
isPrepared = false;
File dir = new File(mDir);
if (!dir.exists()) {
dir.mkdirs();
}
String fileName = GenerateFileName(); // 文件名字
File file = new File(dir, fileName); // 路径+文件名字
//MediaRecorder可以实现录音和录像。需要严格遵守API说明中的函数调用先后顺序.
mRecorder = new MP3Recorder(file);
mCurrentFilePath = file.getAbsolutePath();
// mMediaRecorder = new MediaRecorder();
// mCurrentFilePath = file.getAbsolutePath();
// mMediaRecorder.setOutputFile(file.getAbsolutePath()); // 设置输出文件
// mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC); // 设置MediaRecorder的音频源为麦克风
// mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.AMR_NB); // 设置音频的格式
// mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB); // 设置音频的编码为AMR_NB
// mMediaRecorder.prepare();
// mMediaRecorder.start();
mRecorder.start(); //开始录音
isPrepared = true; // 准备结束
if (mListenter != null) {
mListenter.wellPrepared();
}
} catch (Exception e) {
e.printStackTrace();
LogUtil.e("prepareAudio",e.getMessage());
}
}
/**
* 随机生成文件名称
* @return
*/
private String GenerateFileName() {
// TODO Auto-generated method stub
return UUID.randomUUID().toString() + ".mp3"; // 音频文件格式
}
/**
* 获得音量等级——通过mMediaRecorder获得振幅,然后换算成声音Level
* maxLevel最大为7;
* @return
*/
public int getVoiceLevel(int maxLevel) {
if (isPrepared) {
try {
mRecorder.getMaxVolume();
return maxLevel * mRecorder.getMaxVolume() / 32768 + 1;
} catch (Exception e) {
e.printStackTrace();
}
}
return 1;
}
/**
* 释放资源
*/
public void release() {
if(mRecorder != null) {
mRecorder.stop();
mRecorder = null;
}
}
/**
* 停止录音
*/
public void stop(){
if(mRecorder!=null && mRecorder.isRecording()){
mRecorder.stop();
}
}
/**
* 取消(释放资源+删除文件)
*/
public void delete() {
release();
if (mCurrentFilePath != null) {
File file = new File(mCurrentFilePath);
file.delete(); //删除录音文件
mCurrentFilePath = null;
}
}
public String getCurrentFilePath() {
return mCurrentFilePath;
}
public int getMaxVolume(){
return mRecorder.getMaxVolume();
}
public int getVolume(){
return mRecorder.getVolume();
}
}
2. 语音播放器封装
package com.video.zlc.audioplayer.utils;
import android.content.Context;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.net.Uri;
/**
*
* @author zlc
*
*/
public class MediaManager {
private static MediaPlayer mMediaPlayer; //播放录音文件
private static boolean isPause = false;
static {
if(mMediaPlayer==null){
mMediaPlayer=new MediaPlayer();
mMediaPlayer.setOnErrorListener( new MediaPlayer.OnErrorListener() {
@Override
public boolean onError(MediaPlayer mp, int what, int extra) {
mMediaPlayer.reset();
return false;
}
});
}
}
/**
* 播放音频
* @param filePath
* @param onCompletionListenter
*/
public static void playSound(Context context,String filePath, MediaPlayer.OnCompletionListener onCompletionListenter){
if(mMediaPlayer==null){
mMediaPlayer = new MediaPlayer();
mMediaPlayer.setOnErrorListener( new MediaPlayer.OnErrorListener() {
@Override
public boolean onError(MediaPlayer mp, int what, int extra) {
mMediaPlayer.reset();
return false;
}
});
}else{
mMediaPlayer.reset();
}
try {
//详见“MediaPlayer”调用过程图
mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mMediaPlayer.setOnCompletionListener(onCompletionListenter);
mMediaPlayer.setDataSource(filePath);
mMediaPlayer.prepare();
mMediaPlayer.start();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
LogUtil.e("语音error==",e.getMessage());
}
}
/**
* 暂停
*/
public synchronized static void pause(){
if(mMediaPlayer!=null && mMediaPlayer.isPlaying()){
mMediaPlayer.pause();
isPause=true;
}
}
//停止
public synchronized static void stop(){
if(mMediaPlayer!=null && mMediaPlayer.isPlaying()){
mMediaPlayer.stop();
isPause=false;
}
}
/**
* resume继续
*/
public synchronized static void resume(){
if(mMediaPlayer!=null && isPause){
mMediaPlayer.start();
isPause=false;
}
}
public static boolean isPause(){
return isPause;
}
public static void setPause(boolean isPause) {
MediaManager.isPause = isPause;
}
/**
* release释放资源
*/
public static void release(){
if(mMediaPlayer!=null){
isPause = false;
mMediaPlayer.stop();
mMediaPlayer.release();
mMediaPlayer = null;
}
}
public synchronized static void reset(){
if(mMediaPlayer!=null) {
mMediaPlayer.reset();
isPause = false;
}
}
/**
* 判断是否在播放视频
* @return
*/
public synchronized static boolean isPlaying(){
return mMediaPlayer != null && mMediaPlayer.isPlaying();
}
}
3. 语音列表顺序播放
private int lastPos = -1;
//播放语音
private void playVoice(final int position, String from) {
LogUtil.e("playVoice position",position+"");
if(position >= records.size()) {
LogUtil.e("playVoice","全部播放完了");
stopAnimation();
MediaManager.reset();
return;
}
String voicePath = records.get(position).getPath();
LogUtil.e("playVoice",voicePath);
if(TextUtils.isEmpty(voicePath) || !voicePath.contains(".mp3")){
Toast.makeText(this,"语音文件不合法",Toast.LENGTH_LONG).show();
return;
}
if(lastPos != position && "itemClick".equals(from)){
stopAnimation();
MediaManager.reset();
}
lastPos = position;
//获取listview某一个条目的图片控件
int pos = position - id_list_voice.getFirstVisiblePosition();
View view = id_list_voice.getChildAt(pos);
id_iv_voice = (ImageView) view.findViewById(R.id.id_iv_voice);
LogUtil.e("playVoice position",pos+"");
if(MediaManager.isPlaying()){
MediaManager.pause();
stopAnimation();
}else if(MediaManager.isPause()){
startAnimation();
MediaManager.resume();
}else{
startAnimation();
MediaManager.playSound(this,voicePath, new MediaPlayer.OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mediaPlayer) {
//播放完停止动画 重置MediaManager
stopAnimation();
MediaManager.reset();
playVoice(position + 1, "loop");
}
});
}
}
4. 语音列表单个播放 复用问题处理
播放逻辑基本同上
private int lastPosition = -1;
private void playVoice(FendaListInfo.ObjsEntity obj, int position) {
String videoPath = obj.path;
if(TextUtils.isEmpty(videoPath) || !videoPath.contains(".mp3")){
Toast.makeText(this,"语音文件不合法",Toast.LENGTH_LONG).show();
return;
}
if(position != lastPosition){ //点击不同条目先停止动画 重置音频资源
stopAnimation();
MediaManager.reset();
}
if(mAdapter!=null)
mAdapter.selectItem(position, lastPosition);
lastPosition = position;
id_iv_voice.setBackgroundResource(R.drawable.animation_voice);
animationDrawable = (AnimationDrawable) id_iv_voice.getBackground();
if(MediaManager.isPlaying()){
stopAnimation();
MediaManager.pause();
}else if(MediaManager.isPause()){
startAnimation();
MediaManager.resume();
}else{
startAnimation();
MediaManager.playSound(this,videoPath, new MediaPlayer.OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mp) {
LogUtil.e("onCompletion","播放完成");
stopAnimation();
MediaManager.stop();
}
});
}
}
//核心方法
//点击了某一个条目 这个条目isSelect=true 上一个条目isSelect需要改为false 防止滑动过程中 帧动画复用问题
public void selectItem(int position, int lastPosition) {
LogUtil.e("selectItem"," ;lastPosition="+lastPosition+" ;position="+position);
if(lastPosition >= 0 && lastPosition < mDatas.size() && lastPosition != position){
FendaListInfo.ObjsEntity bean = mDatas.get(lastPosition);
bean.isSelect = false;
mDatas.set(lastPosition, bean);
notifyDataSetChanged();
}
if(position < mDatas.size() && position != lastPosition){
FendaListInfo.ObjsEntity bean = mDatas.get(position);
bean.isSelect = true;
mDatas.set(position,bean);
}
}
/**
* 适配器图片播放的动画处理
*/
private void setVoiceAnimation(ImageView iv_voice, FendaListInfo.ObjsEntity obj) {
//处理动画复用问题
AnimationDrawable animationDrawable;
if(obj.isSelect){
iv_voice.setBackgroundResource(R.drawable.animation_voice);
animationDrawable = (AnimationDrawable) iv_voice.getBackground();
if(MediaManager.isPlaying() && animationDrawable!=null){
animationDrawable.start();
}else{
iv_voice.setBackgroundResource(R.drawable.voice_listen);
animationDrawable.stop();
}
}else{
iv_voice.setBackgroundResource(R.drawable.voice_listen);
}
}
5.下载地址
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。
android中录音断点播放,Android实现语音播放与录音功能相关推荐
- android中录音断点播放,Android实现暂停--继续录音(AudioRecord)
Android提供了两个API用于录音的实现:MediaRecorder 和 AudioRecord,各有优劣. 1.MediaRecorder 已经集成了录音.编码.压缩等,支持少量的录音音频格式, ...
- Android中http断点下载,Android HttpURLConnection断点下载(单线程)
HttpCilent 跟 HttpURLConnection 是安卓原生的用来实现http请求的类: Android 6.0之后取消了HttpClient,不支持跟新 ,今天小编使用的是HttpURL ...
- Android中录音的使用
今天我们介绍一下Android中录音的应用.我们在开发中经常有需要录音的场景,比如语音记录,聊天发送语音.这些情况下我们就要进行录音操作.那么今天我就给大家介绍一下在Android中如何进行录音. 1 ...
- android语音动画,Android逐帧动画的简单使用-语音播放效果的实现
逐帧动画(Frame-By-Frame Animation)原理很简单,即快速切换不同的图片,形成动画效果.Android中逐帧动画的实现方式也很简单,下面以语音播放效果为例说明. 1. 首先准备图片 ...
- android 喇叭帧动画,CSS动画效果——语音播放小喇叭
写业务代码经常会碰到要自己实现一些设计交给的小动画,今天我们就来看下小喇叭那种类似倒过来的wifi图标一样的效果: 语音播放效果 对于这个有几种实现方案:一种是直接把图标.png文件放在下面,然后再在 ...
- android 语音播放工具,Android简易的仿微信聊天的语音播放控件
说到Android音频播放,可谓108式,方案众多,这里有一篇总结Android几种播放音频的方式的文章,传送门.本文旨在熟悉MediaPlayer的使用,遂此控件封装采用MediaPlayer实现. ...
- android中edittext设置密码格式,Android 自定义EditText(带清理、密码可见、不可见)...
实际开发中经常会遇到输入框,各种不同的需求,在一般情况下,清除内容,以及密码可见与不可见基本很常见,那么不废话直接上代码! 在res\values\attrs.xml中 .java import an ...
- android wear 录音,首款Android Wear录音应用上架
一位名为 BinomV 的开发者悄然带来最新 Android Wear 平台的新应用:Wear Audio Recorder.该应用程序的最基本功能便是让智能手机支持录音功能,目前已经上架谷歌官方的 ...
- android中怎么网络判断,Android中判断网络是否连接实例详解
Android中判断网络是否连接实例详解 在android中,如何监测网络的状态呢,这个有的时候也是十分重要的,方法如下: public class ConnectionDetector { priv ...
最新文章
- Lucene组件概述
- 8.深度学习练习:Gradient Checking
- java mediainfo.dll_MediaInfo库的简单使用
- windows 安装 pip工具
- springboot 讯飞语音_讯飞智能语音鼠标实际体验感受
- 使用react-native做一个简单的应用-01项目介绍
- P2272 [ZJOI2007]最大半连通子图
- dispatch js实现_js实现对象自定义事件,触发,on监听事件的方式
- 双系统装完只能u盘启动_安装双系统后没有双系统启动菜单怎么办?双系统启动菜单修复教程...
- led大屏按实际尺寸设计画面_led显示屏尺寸大小要怎么算
- css画企鹅,知识点
- 【camera】手机相机系统
- ADGUARD——去除广告利器
- 华清远见-重庆中心-HTML、CSS技术总结
- 2019年互联网公司月饼哪家强?阿里、百度、网易等14家中秋月饼盘点
- 看完何同学的这期B站视频,我做了个决定...
- 除法器的实现(恢复余数、不恢复余数、级数展开、Newton-Raphson)
- 统一文档服务器,统一标准化文档oraclei服务器安装基础手册.doc
- ARM架构—— Cortex-M3与Cortex-M4特点概述
- 图论算法 有图有代码 万字总结 向前辈致敬
热门文章
- 特斯拉自动驾驶中的 OccupancyNetworks NeRFs
- U盘用转接头插入电脑后,读取不出来还没有提示音
- 51Nod 1453(CF553-A) - 抽彩球(Kyoya and Colored Balls) - 解题报告
- 使用git新建分支并上传
- 好看的壁纸,如今只需discord你也可以拥有
- 分布式电商项目(1)---vue初始化项目
- 【Android App】实战项目之仿微信的私信和群聊App(附源码和演示视频 超详细必看)
- PD快充 - fusb302驱动调试笔记
- Bagehot,Banyan,Chaguan……《经济学人》的这些单词有何深意?
- Map接口以及Collections工具类