zoukankan      html  css  js  c++  java
  • Android平台语音交友软件源码开发,语音通话的实现

    在Android平台上开发语音交友软件源码,最重要的就是语音通话的实现,一般语音通话大概流程如下:语音采集,编解码,网络传输以及语音播放。如果算上UI交互的话,就是五个模块了。

    整体流程大概是:A发送语音请求给B,A声音通过MIC被采集成PCM原始数据,然后经过编码压缩,再通过网络将编码后的音频数据传输出去;B端通过网络收到数据后进行解码处理,然后调用播放模块,进行音频数据的播放。

    1、语音采集模块
    Android平台语音交友软件源码开发,在语音通话中是通过AudioRecord接口来实现PCM数据的采集,这一步比较容易的。但需要注意的是AudioRecord接口的使用方法。构造AudioRecord 实例需要参数 public AudioRecord (int audioSource, intsampleRateInHz, int channelConfig, int audioFormat, int bufferSizeInBytes)

    比如录音代码如下:

        static final int frequency = 8000;   
        static final int channelConfiguration = AudioFormat.CHANNEL_CONFIGURATION_MONO;     
        static final int audioEncoding = AudioFormat.ENCODING_PCM_16BIT;    
        int recBufSize,playBufSize; 
        AudioRecord audioRecord;    
     
         recBufSize =  AudioRecord.getMinBufferSize(frequency,     
                  channelConfiguration, audioEncoding);      
         audioRecord = new AudioRecord(MediaRecorder.AudioSource.MIC, frequency,     
          AudioFormat.CHANNEL_CONFIGURATION_MONO, AudioFormat.ENCODING_PCM_16BIT, recBufSize);

    2、语音播放

    当语音交友软件源码中语音数据采集好了之后,接着可以实现语音播放模块。Android上实现PCM数据的播放也很简单,直接使用AudioTrack这个接口就行了。同样需要注意该接口的使用方法。AudioTrack的构造方式跟AudioRecord是对应的

        static final int frequency = 8000;   
        static final int channelConfiguration = AudioFormat.CHANNEL_CONFIGURATION_MONO;     
        static final int audioEncoding = AudioFormat.ENCODING_PCM_16BIT;    
        int recBufSize,playBufSize; 
        AudioTrack  audioPlayer ;
     
      playBufSize =  AudioTrack.getMinBufferSize(frequency,     
                 channelConfiguration, audioEncoding);        
      audioPlayer = new AudioTrack(AudioManager.STREAM_MUSIC,frequency,AudioFormat.CHANNEL_OUT_MONO,
      AudioFormat.ENCODING_PCM_16BIT,playBufSize,
                   AudioTrack.MODE_STREAM) ;

    3、语音编解码

    采集到的PCM数据是原始的语音数据,如果我们直接进行网络传输,那是不可取的。因此,要进行打包编码。
    在语音交友软件源码开发中,编码我们需要第三方的库,把speex源码下载下来,写好JNI接口,在NDK环境编译一下,即可在java环境调用。
    例如下面一个接口函数

     jint 
     Java_com_audiocodec_talkdemo_AudioCodec_InitAudioEncodec( JNIEnv* env,
                                                     jobject thiz,jint sampling_rate,jint audioLevel)
      {
      if(nInitAudioCodecEncodeFlag == 1 || audioLevel < 3 || audioLevel > 8 )
      return 0 ;
     
    int  frame_size ;
     
    if(sampling_rate == 8000)
    {
    audio_Leval = 0 ;          
      capAudioLength = 160     ; 
      capAudioBitrate = 8000  ; 
    }else if(sampling_rate == 16000)
    {
         audio_Leval = 1 ;  
         capAudioLength = 320     ;  
         capAudioBitrate = 16000  ;  
    }else if(sampling_rate == 32000)
    {
         audio_Leval = 2 ; 
         capAudioLength = 640     ;  
         capAudioBitrate = 32000  ;  
       }else
        return 0 ; 
     
    tmp_Level = audioLevel ; //设置等级 15kbit/s
    speex_mode = speex_lib_get_mode(audio_Leval) ; 
     
     
    enc_state = speex_encoder_init(speex_mode);
    speex_encoder_ctl(enc_state,SPEEX_SET_QUALITY,&tmp_Level);
     
    int tmp = 30 ;//丢包补偿
    int nRet = speex_encoder_ctl(enc_state, SPEEX_SET_PLC_TUNING, &tmp);
    nRet = speex_encoder_ctl(enc_state, SPEEX_GET_PLC_TUNING, &tmp);
     
    speex_bits_init(&bits); 
     
       nInitAudioCodecEncodeFlag = 1 ;
     
       return 1 ;
     }
     
    //编码音频数据
    /*
    参数
        jbyteArray  szAudio   等待编码的音频数据
        jbyteArray  szOut     编码后的音频数据
    返回值
        成功返回 编码后长度
        失败返回 0 
    */
     
    jint Java_com_audiocodec_talkdemo_AudioCodec_AudioEncode( JNIEnv* env,
                                jobject thiz,jbyteArray szAudio,jbyteArray szOut)
    {
    if(nInitAudioCodecEncodeFlag == 0)
      return 0 ;
     
      jbyte* szAudioBuffer =  (jbyte *)(*env)->GetByteArrayElements(env,szAudio, 0);
      jbyte* szOutBuffer   =  (jbyte *)(*env)->GetByteArrayElements(env,szOut, 0);
     
    //清空bits ,以便编码
      speex_bits_reset(&bits);
     
        //进行编码
      int nRet = speex_encode_int(enc_state,(spx_int16_t*)szAudioBuffer, &bits);
     
      //把编码后的bits 结构,拷贝到cbits_enc的数据可以从网络发送出去,长度为nByte_enc
      int nByte_enc = speex_bits_write(&bits, szOutBuffer, 200);
     
      (*env)->ReleaseByteArrayElements(env,szAudio,szAudioBuffer,0) ;
      (*env)->ReleaseByteArrayElements(env,szOut,szOutBuffer,0) ;
     
      return nByte_enc ;
    }                                                 
     
    /*
    函数功能 初始化编码器
    参数
        无参数
    返回值
        成功返回 1
        失败返回 0 
    */
    jint 
    Java_com_audiocodec_talkdemo_AudioCodec_ExitAudioEncodec( JNIEnv* env,
                                                     jobject thiz)
    {
    if(nInitAudioCodecEncodeFlag == 1)
    {
    nInitAudioCodecEncodeFlag = 0 ;
     
    //销毁资源
    speex_bits_destroy(&bits); 
    speex_encoder_destroy(enc_state);
    enc_state = NULL ;
    }else
    return 0 ;
    }

    4 网络发送、接收

       //定义
    DatagramSocket udpSocket  ;  
     
    //生成
          try {
    udpSocket = new  DatagramSocket(6789);
      } catch (SocketException e1) {
       e1.printStackTrace();
     }
     
     //发送
       try {
    udpSocket.send(sendPacket) ;
     } catch (IOException e) {
    e.printStackTrace();
     }
     
      //接收
      udpSocket.receive(udpPackage); 
     
      //关闭
      udpSocket.close() ;

    以上就是“Android平台语音交友软件源码开发,语音通话的实现”的全部内容了,希望对大家有帮助。

    本文转载自网络,转载仅为分享干货知识,如有侵权欢迎联系云豹科技进行删除处理

    原文链接:https://blog.csdn.net/qq_15807167/article/details/67637024?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522162493198616780269844055%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fall.%2522%257D&request_id=162493198616780269844055&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~first_rank_v2~rank_v29-2-67637024.pc_search_result_before_js&utm_term=%E8%AF%AD%E9%9F%B3%E9%80%9A%E8%AF%9D%E7%9A%84%E5%9B%9E%E5%A3%B0&spm=1018.2226.3001.4187

  • 相关阅读:
    手机端调用摄像头拍照
    判断浏览器是否支持css3属性或单位
    浏览器页面加载解析渲染机制(一)
    css默认值汇总
    分享几个高效编写JS 的心得
    说几个JS优化技巧吧
    yahoo的30条优化规则
    Jquery的$命名冲突
    C语言时间头文件
    C语言随机数的生成
  • 原文地址:https://www.cnblogs.com/yunbao/p/14950727.html
Copyright © 2011-2022 走看看