Android中IM的语音处理简介及初步实现

本文介绍了Android即时通讯(IM)应用中的语音处理功能,包括语音功能的基本流程、编解码原因、主要API的使用,以及数据传输的两种方式:文件模式和字节流模式。同时,提到了权限管理和相应的录音播放工具类。
摘要由CSDN通过智能技术生成

IM

即为Instant Message,
消息内容不大,传输快速
即时到达,实时通知

IM中语音功能简介

控制消息大小,语音时长在一分钟以内。
数据压缩,减小传输数据量
长连接接受通知,声音文件单独下载

语音功能流程

发送方:
开启录音
获取数据 
编码保存

接收方
解码
接受数据
播放

需要编解码的原因:

声音原始数据非常大,不压缩传输量几乎无法接受

主要API

声音采集:
MediaRecorder:直接录制成文件并且保存起来
AudioRecord:直接把声音实时的字节数据返还给我们
声音播放:
Mediplayer:基于文件的播放
AudioTrack:提供基于字节数据播放

数据传输:

基于文件:HTTP文件上传下载
基于字节流:TCP/WebScoket

Demo
权限

    <uses-permission android:name="android.permission.RECORD_AUDIO"/>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

使用文件模式录音和播放

public class RecordAudioByFileActivity extends AppCompatActivity {
   

    private static final String TAG = RecordAudioByFileActivity.class.getSimpleName();

    @BindView(R.id.tvLog)
    TextView mTvLog;
    @BindView(R.id.tvPressToSay)
    Button mTvPressToSay;
    @BindView(R.id.btnPlayAudio)
    Button mBtnPlayAudio;

    private ExecutorService mExecutorService;
    private MediaRecorder mMediaRecorder;
    private File mAudioFile;

    private long mBeginRecordInMillis, mEndRecordInMillis;

    // 播放状态
    private volatile boolean mIsplaying;
    private MediaPlayer mMediaPlayer;

    public void setIsplaying(boolean isplaying) {
        //设置当前播放状态
        mIsplaying = isplaying;
        //改变UI
        mBtnPlayAudio.setText(
                mIsplaying ? R.string.record_audio_stop_playing : R.string.record_audio_playing);

        if (mIsplaying) {

            if (mAudioFile != null) {
                mExecutorService.submit(new Runnable() {
                    @Override
                    public void run() {
                        doPlayAudio(mAudioFile);
                    }
                });
            } else {
                Toast.makeText(RecordAudioByFileActivity.this, "请先录音...",
                        Toast.LENGTH_SHORT).show();
            }


        }
    }


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_record_audio_by_file);
        ButterKnife.bind(this);

        // 录音JNI函数不具备线程安全性,所以要用单线程
        mExecutorService = Executors.newSingleThreadExecutor();

        initUIControlerEventHandlers();
    }

    @Override
    protected void onDestroy() {
        //activity销毁后,停止后台任务,避免内存泄漏
        mExecutorService.shutdownNow();
        releaseRecorder();
        stopPlay();
        super.onDestroy();
    }


    @OnClick(R.id.btnPlayAudio)
    void playAudioHandler() {
        setIsplaying(!mIsplaying);
    }

    //按下说话,释放发送,所以不要使用onClciker
    private void initUIControlerEventHandlers() {
        mTvPressToSay.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                switch (event.getAction()) {
                    case MotionEvent.ACTION_DOWN:
                        startRecordAudio();
                        break;

                    case MotionEvent.ACTION_UP:
                    case MotionEvent.ACTION_CANCEL:
                        stopRecordAudio();
                        break;

                    default:
                        break;

                }

                return true;
            }
        });
    }

    /**
     * 开始录音
     */
    private void startRecordAudio() {
        //改变UI状态,正在说话
        mTvPressToSay.setText(R.string.record_audio_speaking);
        //提交后台任务,执行录音
        mExecutorService.submit(new Runnable() {
            @Override
            public void run() {
                //释放之前的录音的recorder
                releaseRecorder();
                //执行录音逻辑,如果失败提示用户
                if (!doStartRecordAudio()) {
                    recordFail();
                }
            }
        });

    }

    /**
     * 停止录音
     */
    private void stopRecordAudio() {
        //改变UI状态,按
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值