android 手机一边录音一边播放 仿yy的试听功能

2023-10-31 19:18

本文主要是介绍android 手机一边录音一边播放 仿yy的试听功能,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一 android中AudioRecord采集音频的参数说明

在android中采集音频的api是android.media.AudioRecord类

其中构造器的几个参数就是标准的声音采集参数

以下是参数的含义解释

public AudioRecord (int audioSource, int sampleRateInHz, int channelConfig, int audioFormat, int bufferSizeInBytes)

Since: API Level 3

Class constructor.

Parameters

audioSource

the recording source. See MediaRecorder.AudioSource for recording source definitions.

音频源:指的是从哪里采集音频。这里我们当然是从麦克风采集音频,所以此参数的值为MIC

sampleRateInHz

the sample rate expressed in Hertz. Examples of rates are (but not limited to) 44100, 22050 and 11025.

采样率:音频的采样频率,每秒钟能够采样的次数,采样率越高,音质越高。给出的实例是44100、22050、11025但不限于这几个参数。例如要采集低质量的音频就可以使用4000、8000等低采样率。

channelConfig

describes the configuration of the audio channels. See CHANNEL_IN_MONO and CHANNEL_IN_STEREO

声道设置:android支持双声道立体声和单声道。MONO单声道,STEREO立体声

audioFormat

the format in which the audio data is represented. See ENCODING_PCM_16BIT and ENCODING_PCM_8BIT

编码制式和采样大小:采集来的数据当然使用PCM编码(脉冲代码调制编码,即PCM编码。PCM通过抽样、量化、编码三个步骤将连续变化的模拟信号转换为数字编码。) android支持的采样大小16bit 或者8bit。当然采样大小越大,那么信息量越多,音质也越高,现在主流的采样大小都是16bit,在低质量的语音传输的时候8bit足够了。

bufferSizeInBytes

the total size (in bytes) of the buffer where audio data is written to during the recording. New audio data can be read from this buffer in smaller chunks than this size. SeegetMinBufferSize(int, int, int) to determine the minimum required buffer size for the successful creation of an AudioRecord instance. Using values smaller than getMinBufferSize() will result in an initialization failure.

采集数据需要的缓冲区的大小,如果不知道最小需要的大小可以在getMinBufferSize()查看。

二 代码

package com.example.superb.yy4;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;

import java.io.IOException;
import java.io.PipedInputStream;
import java.io.PipedOutputStream;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

import org.w3c.dom.Text;

public class MainActivity extends Activity {
PipedInputStream in;
boolean isRrcord;
mAudio mm ;
mAudioPlayer m;

TextView T1,T2;
Button btn;
@Override
protected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);btn=findViewById(R.id.search_close_btn);T1=findViewById(R.id.dddd);isRrcord = false;}
public void btnclick(View v){if (isRrcord){isRrcord = false;mm.stopRecord();m.stopPlay();btn.setText("开始");T1.setText("点击开始");}else{isRrcord = true;startRecord();btn.setText("停止");T1.setText("点击停止");}
}private void startRecord(){in = new PipedInputStream();new Thread(new Runnable() {@Overridepublic void run() {try {mm = new mAudio(MainActivity.this, in);mm.StartAudioData();} catch (IOException e) {e.printStackTrace();}}}).start();new Thread(new Runnable() {@Overridepublic void run() {byte[] buffer = new byte[1024];PipedOutputStream pout = new PipedOutputStream();m = new mAudioPlayer();try {m.setOutputStream(pout);new Thread(new Runnable() {@Overridepublic void run() {// TODO Auto-generated method stubm.startPlayAudio();}}).start();} catch (IOException e1) {e1.printStackTrace();}int size = 0 ;try {while (true){while (in.available()>0){size = in.read(buffer);pout.write(buffer, 0, size);}}} catch (IOException e) {e.printStackTrace();}}}).start();
}

}

package com.example.superb.yy4;

import java.io.IOException;
import java.io.PipedInputStream;
import java.io.PipedOutputStream;

import android.content.Context;
import android.media.AudioFormat;
import android.media.AudioRecord;
import android.media.MediaRecorder;

/*

  • To getaudio or play audio

  • */
    public class mAudio {
    private AudioRecord audioRecord;
    private Context context;
    private boolean isRecording = false ;
    private PipedOutputStream outstream ;//利用管道传输数据
    public mAudio(Context context , PipedInputStream instream) throws IOException {
    this.context = context;
    //初始化管道流 用于向外传输数据
    outstream = new PipedOutputStream();
    outstream.connect(instream);
    }
    public void StartAudioData(){//得到录音数据
    int frequency = 11025;

     //frequency采样率:音频的采样频率,每秒钟能够采样的次数,采样率越高,音质越高。// 给出的实例是44100、22050、11025但不限于这几个参数。// 例如要采集低质量的音频就可以使用4000、8000等低采样率。@SuppressWarnings("deprecation")int channelConfiguration = AudioFormat.CHANNEL_CONFIGURATION_STEREO;//立体声录制通道int audioEncoding = AudioFormat.ENCODING_PCM_16BIT;//编码制式和采样大小:采集来的数据当然使用PCM编码(脉冲代码调制编码,// 即PCM编码。PCM通过抽样、量化、编码三个步骤将连续变化的模拟信号转换为数字编码。) android支持的采样大小16bit 或者8bit。// 当然采样大小越大,那么信息量越多,音质也越高,// 现在主流的采样大小都是16bit,在低质量的语音传输的时候8bit足够了。//int buffersize = AudioRecord.getMinBufferSize(frequency, channelConfiguration, audioEncoding);
    

    //采集数据需要的缓冲区的大小,如果不知道最小需要的大小可以在getMinBufferSize()查看。
    audioRecord = new AudioRecord(MediaRecorder.AudioSource.MIC,
    frequency, channelConfiguration, audioEncoding, buffersize);
    //音频源:指的是从哪里采集音频。这里我们当然是从麦克风采集音频,所以此参数的值为MIC

     //frequency采样率:音频的采样频率,每秒钟能够采样的次数,采样率越高,音质越高。// 给出的实例是44100、22050、11025但不限于这几个参数。// 例如要采集低质量的音频就可以使用4000、8000等低采样率。byte[]buffer  = new byte[buffersize];audioRecord.startRecording();//开始录音isRecording = true;int bufferReadSize = 1024;while (isRecording){audioRecord.read(buffer, 0, bufferReadSize);try {outstream.write(buffer, 0, bufferReadSize);} catch (IOException e) {e.printStackTrace();}}
    

    }
    public void stopRecord(){//停止录音
    isRecording = false;
    audioRecord.stop();
    try {
    outstream.close();
    } catch (IOException e) {
    e.printStackTrace();
    }
    }

}

package com.example.superb.yy4;

import java.io.IOException;
import java.io.PipedInputStream;
import java.io.PipedOutputStream;

import android.media.AudioFormat;
import android.media.AudioManager;
import android.media.AudioTrack;

public class mAudioPlayer {
private PipedInputStream instream;
private boolean isPlaying ;
private AudioTrack audioplayer;
private byte[] buffer;
public mAudioPlayer() {
isPlaying = false;
instream = null;
//初始化播音类
@SuppressWarnings(“deprecation”)
int bufsize = AudioTrack.getMinBufferSize(11025, AudioFormat.CHANNEL_CONFIGURATION_STEREO,
AudioFormat.ENCODING_PCM_16BIT);
audioplayer = new AudioTrack(AudioManager.STREAM_MUSIC, 11025, AudioFormat.CHANNEL_CONFIGURATION_STEREO,
AudioFormat.ENCODING_PCM_16BIT, bufsize,AudioTrack.MODE_STREAM);
}
//设置管道流,用于接受音频数据
public void setOutputStream(PipedOutputStream out) throws IOException{
instream = new PipedInputStream(out);

}
public void startPlayAudio(){ //调用之前先调用setOutputStream 函数isPlaying = true;audioplayer.play();//开始接受数据流播放buffer = new byte[1024];while (instream!=null&&isPlaying){try {while (instream.available()>0){int size = instream.read(buffer);audioplayer.write(buffer, 0, size);//不断播放数据}} catch (IOException e) {e.printStackTrace();}}
}
public void stopPlay(){//停止播放isPlaying = false ;try {instream.close();} catch (IOException e) {e.printStackTrace();}audioplayer.stop();
}

}
参考:
https://www.cnblogs.com/nanguabing/archive/2012/12/16/2820732.html
http://www.cnblogs.com/mythou/p/3242000.html

下载demo

这篇关于android 手机一边录音一边播放 仿yy的试听功能的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/317542

相关文章

Android kotlin中 Channel 和 Flow 的区别和选择使用场景分析

《Androidkotlin中Channel和Flow的区别和选择使用场景分析》Kotlin协程中,Flow是冷数据流,按需触发,适合响应式数据处理;Channel是热数据流,持续发送,支持... 目录一、基本概念界定FlowChannel二、核心特性对比数据生产触发条件生产与消费的关系背压处理机制生命周期

Android ClassLoader加载机制详解

《AndroidClassLoader加载机制详解》Android的ClassLoader负责加载.dex文件,基于双亲委派模型,支持热修复和插件化,需注意类冲突、内存泄漏和兼容性问题,本文给大家介... 目录一、ClassLoader概述1.1 类加载的基本概念1.2 android与Java Class

Qt使用QSqlDatabase连接MySQL实现增删改查功能

《Qt使用QSqlDatabase连接MySQL实现增删改查功能》这篇文章主要为大家详细介绍了Qt如何使用QSqlDatabase连接MySQL实现增删改查功能,文中的示例代码讲解详细,感兴趣的小伙伴... 目录一、创建数据表二、连接mysql数据库三、封装成一个完整的轻量级 ORM 风格类3.1 表结构

mysql表操作与查询功能详解

《mysql表操作与查询功能详解》本文系统讲解MySQL表操作与查询,涵盖创建、修改、复制表语法,基本查询结构及WHERE、GROUPBY等子句,本文结合实例代码给大家介绍的非常详细,感兴趣的朋友跟随... 目录01.表的操作1.1表操作概览1.2创建表1.3修改表1.4复制表02.基本查询操作2.1 SE

Golang如何用gorm实现分页的功能

《Golang如何用gorm实现分页的功能》:本文主要介绍Golang如何用gorm实现分页的功能方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录背景go库下载初始化数据【1】建表【2】插入数据【3】查看数据4、代码示例【1】gorm结构体定义【2】分页结构体

Java Web实现类似Excel表格锁定功能实战教程

《JavaWeb实现类似Excel表格锁定功能实战教程》本文将详细介绍通过创建特定div元素并利用CSS布局和JavaScript事件监听来实现类似Excel的锁定行和列效果的方法,感兴趣的朋友跟随... 目录1. 模拟Excel表格锁定功能2. 创建3个div元素实现表格锁定2.1 div元素布局设计2.

Python如何将OpenCV摄像头视频流通过浏览器播放

《Python如何将OpenCV摄像头视频流通过浏览器播放》:本文主要介绍Python如何将OpenCV摄像头视频流通过浏览器播放的问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完... 目录方法1:使用Flask + MJPEG流实现代码使用方法优点缺点方法2:使用WebSocket传输视

Android DataBinding 与 MVVM使用详解

《AndroidDataBinding与MVVM使用详解》本文介绍AndroidDataBinding库,其通过绑定UI组件与数据源实现自动更新,支持双向绑定和逻辑运算,减少模板代码,结合MV... 目录一、DataBinding 核心概念二、配置与基础使用1. 启用 DataBinding 2. 基础布局

Android ViewBinding使用流程

《AndroidViewBinding使用流程》AndroidViewBinding是Jetpack组件,替代findViewById,提供类型安全、空安全和编译时检查,代码简洁且性能优化,相比Da... 目录一、核心概念二、ViewBinding优点三、使用流程1. 启用 ViewBinding (模块级

HTML5实现的移动端购物车自动结算功能示例代码

《HTML5实现的移动端购物车自动结算功能示例代码》本文介绍HTML5实现移动端购物车自动结算,通过WebStorage、事件监听、DOM操作等技术,确保实时更新与数据同步,优化性能及无障碍性,提升用... 目录1. 移动端购物车自动结算概述2. 数据存储与状态保存机制2.1 浏览器端的数据存储方式2.1.