Android下音视频对讲演示程序

必读说明

简介

  本软件根据《道德经》为核心思想而设计,实现了两个设备之间进行音视频对讲,一般可用于楼宇对讲、智能门铃对讲、企业员工对讲、智能对讲机、以及类似于微信QQ音视频对讲的其他场景。本软件支持以下增强处理:
  * 支持IPv4和IPv6的TCP和UDP协议传输,UDP协议支持可靠传输。
  * 支持实时半双工(一键通)和实时全双工的音频或视频或音视频对讲。
  * 支持8000Hz、16000Hz、32000Hz、48000Hz的音频。
  * 支持声学回音消除,通过本人自己设计的音频输入输出帧同步方法、自适应设置回音延迟方法、三重声学回音消除器,声学回音可以消除到99%以上,还可以消除同一房间回音,且收敛时间很短,无论网络如何抖动都可以消除。
  * 支持噪音抑制,对常见的底噪音、嘈杂的街道音、风吹音、等都有抑制效果。
  * 支持语音活动检测,只有在人说话时才发送网络数据,无人说话时不产生网络数据,从而降低噪音、降低网络流量。
  * 支持自动增益控制,当人说话声音较小时会自动增大音量,当人说话声音较大时会自动减小音量。
  * 支持音频编解码,对音频数据的压缩率在1~20%之间,且支持动态比特率,从而大幅度降低网络流量,声音依然清晰,还支持数据包丢失隐藏,当网络丢包率高达30%时,仍然可以进行对讲。
  * 支持保存音频到文件和绘制音频波形到Surface,可以直观且方便的调试音频。
  * 支持视频软硬编解码,支持指定比特率,最低到10KB/s仍然可以进行视频对讲,还支持横竖屏切换。
  * 支持音视频自适应抖动缓冲,当网络存在丢包、乱序、延时等抖动情况时,通过自适应调节缓冲深度来应对这些抖动。
  * 支持自定义调节各种功能的参数来适应不同的设备,绝大部分情况下都不需要修改。
  * 支持保存音视频输入输出到文件。
  * 支持与Windows下音视频对讲演示程序进行音视频对讲。

  声学回音消除器效果对比:

名称 收敛时间 回音延迟不稳定 残余回音 远近端同时说话 同一房间对讲 运算量
Speex声学回音消除器 有语音活动1~3秒 0~3秒自适应调节 回音延迟稳定时没有
回音延迟不稳定时有很大
近端语音被消除20% 会产生一定回音 一般
WebRtc定点版声学回音消除器 0秒 延迟400ms以内0秒自适应调节
延后超过400ms将无法消除
回音延迟稳定时没有
回音延迟不稳定时偶尔有一丝丝,偶尔有很大
近端语音被完全消除 会产生较大回音 一般
WebRtc浮点版声学回音消除器 有语音活动1秒 0秒自适应调节 回音延迟稳定时没有
回音延迟不稳定时偶尔有一丝丝
近端语音被消除50% 会产生较小回音 较大
Speex声学回音消除器
+WebRtc定点版声学回音消除器
0秒 0~3秒自适应调节 回音延迟稳定时没有
回音延迟不稳定时有很大
近端语音被消除20% 会产生一定回音 一般
WebRtc定点版声学回音消除器
+WebRtc浮点版声学回音消除器
0秒 0秒自适应调节 回音延迟稳定时没有
回音延迟不稳定时偶尔有一丝丝
近端语音被消除50% 会产生较小回音 较大
Speex声学回音消除器
+WebRtc定点版声学回音消除器
+WebRtc浮点版声学回音消除器
0秒 0秒自适应调节 回音延迟稳定时没有
回音延迟不稳定时极低概率会有一丝丝
近端语音被消除50% 会产生很小回音 很大

  特别注意:以上是在不使用系统自带声学回音消除器的效果,且不同设备或不同环境或不同时间效果都会不同,所以需要自己亲自测试。

准备

  准备两台安装了Android 2.3及以上系统的设备(已适配到Android 13.0),其中一台设备作为客户端可以连接到另一台作为服务端的设备(可以用Ping工具测试,建议两台设备在同一局域网内),且两台设备都安装相同版本的本软件。

开始

  在一台设备上直接点击创建服务端,再在另一台设备上将IP地址改为服务端设备的IP地址,并点击连接服务端,即可开始对讲,在任意一端点击中断,即可中断对讲。

  设置按钮:提供了各项功能的参数设置,大部分情况下都不需要修改,如果发现不适合某些设备,则需要根据设备情况修改。
  保存设置按钮:将各项功能的参数保存到Stng.xml中,每次运行本软件时会自动读取设置。
  读取设置按钮:将Stng.xml中各项功能的参数读取到本软件中。
  删除设置按钮:将Stng.xml文件删除。
  重置设置按钮:将本软件的设置重置为默认。

  特别注意:如果把两台设备放在同一房间里测试,有可能会出现啸叫、声音不完整、等问题,这是因为现在的麦克风都很灵敏了,一点小小的声音都会被录进去,两台设备会相互录音,导致软件无法正确识别回音,所以建议放在不同的房间里测试。如果实在要测试这种情况,就在设置里,Speex预处理器的设置里,关闭“使用自动增益控制”后再测试。

移植

  如果需要在自己的软件中使用本软件的音视频功能,需要以下几个步骤:
  1、在AndroidManifest.xml文件中添加android.permission.RECORD_AUDIO、android.permission.MODIFY_AUDIO_SETTINGS、android.permission.CAMERA权限。
  2、将HeavenTao.XXXX包和jniLibs文件夹下各个平台的动态库复制到自己的软件中。
  3、继承HeavenTao.Media.MediaPocsThrd媒体处理线程类,实现UserInit、UserPocs、UserDstoy、UserMsg、UserReadAdoVdoInptFrm、UserWriteAdoOtptFrm、UserGetAdoOtptFrm、UserWriteVdoOtptFrm、UserGetVdoOtptFrm这九个回调成员函数。如果要在JNI层处理音视频帧,则可以将这些回调成员函数继承为native函数,然后在JNI层实现即可。
  4、new这个继承的类,然后调用类的相关设置成员函数,最后调用start()成员函数启动媒体处理线程即可。
  5、当需要媒体处理线程退出时,调用类的RqirExit()成员函数即可。

  如果用户有不需要的部分功能,则只需要删除该功能对应的库文件即可,还可以进一步删除对应的类文件,并修改HeavenTao.Media.MediaPocsThrd类文件即可。
  如果只移植部分功能,没有移植MediaPocsThrd媒体处理线程类,则效果可能不好,因为MediaPocsThrd类做了很多优化。

  普通免费功能包括:WebRtc定点版声学回音消除器、Speex预处理器的噪音抑制、WebRtc定点版噪音抑制器、WebRtc浮点版噪音抑制器、Speex预处理器、Speex编解码器、Wave文件读取器、Wave文件写入器、音频波形器、本端TCP协议服务端套接字、本端TCP协议客户端套接字、本端UDP协议套接字。

  高级收费功能包括:Speex声学回音消除器、WebRtc浮点版声学回音消除器、SpeexWebRtc三重声学回音消除器、RNNoise噪音抑制器、OpenH264编解码器、系统自带H264编解码器、自己设计的自适应抖动缓冲器、Avi文件写入器、本端高级UDP协议套接字。

  各个功能对应的文件如下:
  * Speex声学回音消除器:libFunc.so、libSpeexDsp.so、SpeexAec.java。
  * WebRtc定点版声学回音消除器:libFunc.so、libc++_shared.so、libWebRtc.so、WebRtcAecm.java。
  * WebRtc浮点版声学回音消除器:libFunc.so、libc++_shared.so、libWebRtc.so、WebRtcAec.java。
  * SpeexWebRtc三重声学回音消除器:libFunc.so、libSpeexDsp.so、libc++_shared.so、libWebRtc.so、SpeexWebRtcAec.java。
  * WebRtc定点版噪音抑制器:libFunc.so、libc++_shared.so、libWebRtc.so、WebRtcNsx.java。
  * WebRtc浮点版噪音抑制器:libFunc.so、libc++_shared.so、libWebRtc.so、WebRtcNs.java。
  * RNNoise噪音抑制器:libFunc.so、libc++_shared.so、libWebRtc.so、libRNNoise.so、RNNoise.java。
  * Speex预处理器:libFunc.so、libSpeexDsp.so、SpeexPrpocs.java。
  * Speex编解码器:libFunc.so、libSpeex.so、SpeexEncd.java、SpeexDecd.java。
  * 音频波形器:libFunc.so、libAdoWavfm.so、AdoWavfm.java。
  * OpenH264编解码器:libFunc.so、libOpenH264.so、OpenH264Encd.java、OpenH264Decd.java。
  * 系统自带H264编解码器:libFunc.so、libSystemH264.so、SystemH264Encd.java、SystemH264Decd.java。
  * 图片处理:libFunc.so、libLibYUV.so、LibYUV.java。
  * 音视频自适应抖动缓冲器:libFunc.so、libc++_shared.so、libAjb.so、AAjb.java、VAjb.java。
  * 本端TCP协议UDP协议套接字:libFunc.so、libSokt.so、TcpSrvrSokt.java、TcpClntSokt.java、UdpSokt.java、AudpSokt.java。
  * Wave文件Avi文件写入读取器:libFunc.so、libMediaFile.so、WaveFileReader.java、WaveFileWriter.java、AviFileWriter.java。

注意

  不要在64位操作系统下使用32位动态库,或在32位操作系统下使用64位动态库,否则会导致意想不到的问题。
  不要对HeavenTao.XXXX包进行代码混淆,否则会导致意想不到的问题。
  从老版本更新到新版本时,类文件和库文件全部都要更新,不能只更新类文件或库文件,否则会导致意想不到的问题。
  如果要使用8000Hz采样频率时,最好不要使用RNNoise噪音抑制器,因为它对8000Hz的声音抑制非常强烈。
  本软件不支持音乐,尤其是系统自带噪音抑制器和RNNoise噪音抑制器可能对音乐的抑制非常强烈。
  某些Android设备的软硬件环境可能存在问题,从而可能会导致声学回音消除失败,这种情况必须要先解决这些问题。
  某些Android设备的系统自带声学回音消除器、噪音抑制器和自动增益控制器在使用后可能会导致音频输入出现问题,这种情况可以先关闭后再试试。
  音频波形器占用CPU比较高,建议只在需要调试时临时打开。
  系统自带H264编解码器需要Android 5.0(API 21)及以上系统,且在某些Android设备上使用可能会花屏,这种情况只能使用OpenH264编解码器。
  保存音视频输入输出的AdoVdoInptOtpt.avi文件不能直接播放,需要使用FFmpeg命令转码后才能播放,建议用VLC播放器,转码命令为:ffmpeg -i AdoVdoInptOtpt.avi -filter_complex "[0:a:1][0:a:2]amix=inputs=2:duration=max[aout]" -map [aout] -map 0:v -acodec pcm_s16le -vcodec copy AdoVdoInptOtpt_Mix.avi -y。

其他

  本软件采用了Speex的1.2.1版本、SpeexDsp的1.2.1版本、WebRtc的2019年7月份版本、OpenH264的2.3.1版本为基础,并进行了大量优化。
  讨论QQ群:511046632 欢迎大家参与测试和讨论!
  本人QQ号:280604597 赤勇玄心行天道
  本人博客:http://www.cnblogs.com/gaoyaguo
  Windows版源代码:https://github.com/cyz7758520/Windows_audio_talkback_demo_program
           https://gitee.com/chen_yi_ze/Windows_audio_talkback_demo_program
           https://gitcode.net/cyz7758520/Windows_audio_talkback_demo_program
  Android版源代码:https://github.com/cyz7758520/Android_audio_talkback_demo_program
           https://gitee.com/chen_yi_ze/Android_audio_talkback_demo_program
           https://gitcode.net/cyz7758520/Android_audio_talkback_demo_program

版权

  Speex:https://gitlab.xiph.org/xiph/speex/-/blob/master/COPYING
  WebRtc:https://gitlab.com/webrtc-mirror/webrtc/-/blob/master/LICENSE
  RNNoise:https://gitlab.xiph.org/xiph/rnnoise/-/blob/master/COPYING
  OpenH264:https://github.com/cisco/openh264/blob/master/LICENSE
  LibYUV:https://github.com/lemenkov/libyuv/blob/master/LICENSE
  TinyXml2:https://github.com/leethomason/tinyxml2/blob/master/LICENSE.txt

感谢

  感谢 WELEN、善书、陈国福 对 Speex、WebRTC 的指点!

函数

九个回调函数


函数名称:UserInit
功能说明:用户定义的初始化函数,在本线程刚启动时回调一次。
参数说明:无。
返回说明:0:成功。
     非0:失败。


函数名称:UserPocs
功能说明:用户定义的处理函数,在本线程运行时每隔1毫秒就回调一次。
参数说明:无。
返回说明:0:成功。
     非0:失败。


函数名称:UserDstoy
功能说明:用户定义的销毁函数,在本线程退出时回调一次。
参数说明:无。
返回说明:无。


函数名称:UserMsg
功能说明:用户定义的消息函数,在接收到用户消息时回调一次。
参数说明:MsgArgPt:[输入],存放消息参数的动态参数的指针。如果没有消息参数,则本参数为null。
返回说明:无。


函数名称:UserReadAdoVdoInptFrm
功能说明:用户定义的读取音视频输入帧函数,在读取到一个音频输入帧或视频输入帧并处理完后回调一次。如果没有使用音频输入和视频输入,则本函数不会被回调。
参数说明:AdoInptPcmSrcFrmPt:[输入],存放音频输入Pcm格式原始帧的指针,就是未经过声学回音消除、噪音抑制、自动增益控制的音频帧。如果不使用音频输入,则本参数为null。
     AdoInptPcmRsltFrmPt:[输入],存放音频输入Pcm格式结果帧的指针,就是已经过声学回音消除、噪音抑制、自动增益控制的音频帧。如果不使用音频输入,则本参数为null。
     AdoInptPcmFrmLenUnit:[输入],存放音频输入Pcm格式帧的长度,单位为采样单元。如果不使用音频输入,则本参数无意义。
     AdoInptPcmRsltFrmVoiceActSts:[输入],存放音频输入Pcm格式结果帧的语音活动状态,为非0表示有语音活动,为0表示无语音活动。如果不使用音频输入,则本参数无意义。
     AdoInptEncdRsltFrmPt:[输入],存放音频输入已编码格式结果帧的指针。如果不使用音频输入,或音频输入编码器要使用PCM原始数据,则本参数为null。
     AdoInptEncdRsltFrmLenByt:[输入],存放音频输入已编码格式结果帧的长度,单位为字节。如果不使用音频输入,或音频输入编码器要使用PCM原始数据,则本参数无意义。
     AdoInptEncdRsltFrmIsNeedTrans:[输入],存放音频输入已编码格式结果帧是否需要传输,为非0表示需要传输,为0表示不需要传输。如果不使用音频输入,或音频输入编码器要使用PCM原始数据,则本参数无意义。
     VdoInptNv21SrcFrmPt:[输入],存放视频输入Nv21格式原始帧的指针。如果不使用视频输入,或本次没有读取到视频输入帧,则本参数为null。
     VdoInptNv21SrcFrmWidth:[输入],存放视频输入Nv21格式原始帧的宽度,单位为像素。如果不使用视频输入,或本次没有读取到视频输入帧,则本参数无意义。
     VdoInptNv21SrcFrmHeight:[输入],存放视频输入Nv21格式原始帧的高度,单位为像素。如果不使用视频输入,或本次没有读取到视频输入帧,则本参数无意义。
     VdoInptNv21SrcFrmLenByt:[输入],存放视频输入Nv21格式原始帧的长度,单位为字节。如果不使用视频输入,或本次没有读取到视频输入帧,则本参数无意义。
     VdoInptYu12RsltFrmPt:[输入],存放视频输入Yu12格式结果帧的指针。如果不使用视频输入,或本次没有读取到视频输入帧,则本参数为null。
     VdoInptYu12RsltFrmWidth:[输入],存放视频输入Yu12格式结果帧的宽度,单位为像素。如果不使用视频输入,或本次没有读取到视频输入帧,则本参数无意义。
     VdoInptYu12RsltFrmHeight:[输入],存放视频输入Yu12格式结果帧的高度,单位为像素。如果不使用视频输入,或本次没有读取到视频输入帧,则本参数无意义。
     VdoInptYu12RsltFrmLenByt:[输入],存放视频输入Yu12格式结果帧的长度,单位为字节。如果不使用视频输入,或本次没有读取到视频输入帧,则本参数无意义。
     VdoInptEncdRsltFrmPt:[输入],存放视频输入已编码格式结果帧的指针。如果不使用视频输入,或本次没有读取到视频输入帧,或视频输入编码器要使用Yu12原始数据,则本参数为为null。
     VdoInptEncdRsltFrmLenByt:[输入],存放视频输入已编码格式结果帧的长度,单位为字节。如果不使用视频输入,或本次没有读取到视频输入帧,或视频输入编码器要使用Yu12原始数据,则本参数无意义。
返回说明:0:成功。
     非0:失败。


函数名称:UserWriteAdoOtptFrm
功能说明:用户定义的写入音频输出帧函数,在需要写入一个音频输出帧时回调一次。如果没有使用音频输出,则本函数不会被回调。注意:本函数不是在媒体处理线程中执行的,而是在音频输出线程中执行的,所以本函数应尽量在一瞬间完成执行,否则会导致音频输入输出帧不同步,从而导致声学回音消除失败。
参数说明:AdoOtptStrmIdx:[输入],存放音频输出流索引。
     AdoOtptPcmSrcFrmPt:[输出],存放音频输出Pcm格式原始帧的指针。如果音频输出解码器不使用PCM原始数据,则本参数为null。
     AdoOtptPcmFrmLenUnit:[输入],存放音频输出Pcm格式帧的长度,单位为采样单元。如果音频输出解码器不使用PCM原始数据,则本参数无意义。
     AdoOtptEncdSrcFrmPt:[输出],存放音频输出已编码格式原始帧的指针。如果音频输出解码器要使用PCM原始数据,则本参数为null。
     AdoOtptEncdSrcFrmSzByt:[输入],存放音频输出已编码格式原始帧的大小,单位为字节。如果音频输出解码器要使用PCM原始数据,则本参数无意义。
     AdoOtptEncdSrcFrmLenBytPt:[输出],存放音频输出已编码格式原始帧的长度的指针,单位为字节。如果音频输出解码器要使用PCM原始数据,则本参数为null。
返回说明:无。


函数名称:UserGetAdoOtptFrm
功能说明:用户定义的获取音频输出帧函数,在解码完一个已编码音频输出帧时回调一次。如果没有使用音频输出,则本函数不会被回调。注意:本函数不是在媒体处理线程中执行的,而是在音频输出线程中执行的,所以本函数应尽量在一瞬间完成执行,否则会导致音频输入输出帧不同步,从而导致声学回音消除失败。
参数说明:AdoOtptStrmIdx:[输入],存放音频输出流索引。
     AdoOtptPcmSrcFrmPt:[输入],存放音频输出Pcm格式原始帧的指针。
     AdoOtptPcmFrmLenUnit:[输入],存放音频输出Pcm格式帧的长度,单位为采样单元。
     AdoOtptEncdSrcFrmPt:[输入],存放音频输出已编码格式原始帧的指针。如果音频输出解码器要使用PCM原始数据,则本参数为null。
     AdoOtptEncdSrcFrmLenByt:[输入],存放音频输出已编码格式原始帧的长度,单位为字节。如果音频输出解码器要使用PCM原始数据,则本参数无意义。
返回说明:无。


函数名称:UserWriteVdoOtptFrm
功能说明:用户定义的写入视频输出帧函数,在可以显示一个视频输出帧时回调一次。如果没有使用视频输出,则本函数不会被回调。注意:本函数不是在媒体处理线程中执行的,而是在视频输出线程中执行的,所以本函数应尽量在一瞬间完成执行,否则会导致音视频输出帧不同步。
参数说明:VdoOtptStrmIdx:[输入],存放视频输出流索引。
     VdoOtptYu12SrcFrmPt:[输出],存放视频输出Yu12格式原始帧的指针。如果视频输出解码器不使用Yu12原始数据,则本参数为null。
     VdoOtptYu12SrcFrmWidthPt:[输出],存放视频输出Yu12格式原始帧宽度的指针,单位为像素。如果视频输出解码器不使用Yu12原始数据,则本参数为null。
     VdoOtptYu12SrcFrmHeightPt:[输出],存放视频输出Yu12格式原始帧高度的指针,单位为像素。如果视频输出解码器不使用Yu12原始数据,则本参数为null。
     VdoOtptEncdSrcFrmPt:[输出],存放视频输出已编码格式原始帧的指针。如果视频输出解码器要使用Yu12原始数据,则本参数为null。
     VdoOtptEncdSrcFrmSzByt:[输入],存放视频输出已编码格式原始帧的大小,单位为字节。如果视频输出解码器要使用Yu12原始数据,则本参数无意义。
     VdoOtptEncdSrcFrmLenBytPt:[输出],输入时,存放视频输出已编码格式原始帧的长度的指针,单位为字节。如果视频输出解码器要使用Yu12原始数据,则本参数为null。
返回说明:无。


函数名称:UserGetVdoOtptFrm
功能说明:用户定义的获取视频输出帧函数,在解码完一个已编码视频输出帧时回调一次。如果没有使用视频输出,则本函数不会被回调。注意:本函数不是在媒体处理线程中执行的,而是在视频输出线程中执行的,所以本函数应尽量在一瞬间完成执行,否则会导致音视频输出帧不同步。
参数说明:VdoOtptStrmIdx:[输入],存放视频输出流索引。
     VdoOtptYu12SrcFrmPt:[输入],存放视频输出Yu12格式原始帧的指针。
     VdoOtptYu12SrcFrmWidth:[输入],存放视频输出Yu12格式原始帧的宽度,单位为像素。
     VdoOtptYu12SrcFrmHeight:[输入],存放视频输出Yu12格式原始帧的高度,单位为像素。
     VdoOtptEncdSrcFrmPt:[输入],存放视频输出已编码格式原始帧的指针。如果视频输出解码器要使用Yu12原始数据,则本参数为null。
     VdoOtptEncdSrcFrmLenByt:[输入],存放视频输出已编码格式原始帧的长度,单位为字节。如果视频输出解码器要使用Yu12原始数据,则本参数无意义。
返回说明:无。


 

Android下音视频对讲演示程序(声学回音消除、噪音抑制、语音活动检测、自动增益控制、自适应抖动缓冲)(2023年07月13日更新)的更多相关文章

  1. 通俗的解释下音视频同步里pcr作用

    PCR同步在非硬件精确时钟源的情况还是谨慎使用,gstreamer里面采用PCR同步,但是发现好多ffmpeg转的片儿,或者是CP方的片源,pcr打得很粗糙的,老是有跳帧等现象.音视频同步,有三种方法 ...

  2. Android WebRTC 音视频开发总结

    www.cnblogs.com/lingyunhu/p/3621057.html 前面介绍了WebRTCDemo的基本结构,本节主要介绍WebRTC音视频服务端的处理,,转载请说明出处(博客园RTC. ...

  3. Android开发 音视频开发需要了解的专业术语知识

    前言 在摸索一段时间的音视频开发后,越来越发现这个坑的深度真是特别的深. 除了了解Android自带的音视频处理API以外,还得了解一些视频与音频方面的知识.这篇博客就是主要讲解这方面的专业术语.内容 ...

  4. 如何做好 Android 端音视频测试?

    在用户眼中,优秀的音视频产品应该具有清晰.低延时.流畅.秒开.抗丢包.高音效等特征.为了满足用户以上要求,网易云信的工程师通过自建源站,在SDK端为了适应网络优化进行QoS优化,对视频编码器进行优化, ...

  5. 如何基于 ZEGO SDK 实现 Android 一对一音视频聊天应用

    疫情期间,很多线下活动转为线上举行,实时音视频的需求剧增,在视频会议,在线教育,电商购物等众多场景成了"生活新常态". 本文将教你如何通过即构ZEGO sdk在Android端搭建 ...

  6. Android WebRTC 音视频开发总结(四)-- webrtc传输模块

    在介绍WebRTC通讯之前我们先来看一个P2P视频聊天包括的主要过程,转载请说明出处(博客园RTC.Blacker): 音视频数据采集->编码->发送->接收->解码-> ...

  7. Android WebRTC 音视频开发总结(三)-- 信令服务和媒体服务

    前面介绍了WebRTCDemo的基本结构,本节主要介绍WebRTC音视频服务端的处理,,转载请说明出处(博客园RTC.Blacker). 通过前面的例子我们知道运行WebRTCDemo即可看到P2P的 ...

  8. Android WebRTC 音视频开发总结(一)

    本系列文章主要总结和分享WebRTC开发过程中的一些经验,转载请说明出处(博客园RTC.Blacker),更多交流与合作请看页面上方的子标题! 一.WebRTC是什么? 可能您还不知道WebRTC是什 ...

  9. 【转】Android WebRTC 音视频开发总结(一)

    http://www.cnblogs.com/lingyunhu/p/3578218.html 本系列文章主要总结和分享WebRTC开发过程中的一些经验,转载请说明出处(博客园RTC.Blacker) ...

  10. Android 开发 音视频从入门到提高 任务列表 转载

    <Android 音视频从入门到提高 —— 任务列表> 1. 在 Android 平台绘制一张图片,使用至少 3 种不同的 API,ImageView,SurfaceView,自定义 Vi ...

随机推荐

  1. WakaTime Readme Stats-开源项目翻译

    寻找不同语言和地区的翻译 #23 Readme中添加了功能标志的开发指标 眼前一亮的Readme统计数据 你是早起的还是夜间的? 你一天中什么时候工作效率最高? 你用什么语言编写代码? 让我们在你的个 ...

  2. SpringBoot 多环境切换

    日常开发中一般都会有三个不同的环境,分别是开发环境(dev),测试环境(test)和生产环境(prod),不同的环境各种配置都不相同,比如数据库配置,服务器端口等等. Spring Boot 多环境配 ...

  3. 【干货向】我想试试教会你如何修改Git提交信息

    Git是目前IT行业使用率最高的版本控制系统,相信大家在日常工作中也经常使用,每次Git提交都会包含提交信息,常用的包括说明.提交人和提交时间等,此篇文章主要向大家介绍下如何修改这些信息,这些命令在正 ...

  4. 包管理工具npm和Yarn的区别,我们该如何选择?

    好家伙,学习新工具    1.为什么我们需要包管理器? 关于npm我们已经知道了,这是我们项目的包管理器, 我们现在用的无比顺手的工具,都是在无数的竞争中杀出来的,他们淘汰了无数的产品   首先,倘若 ...

  5. 伸展树(Splay)详解

    引入 在一条链中,二叉查找树的时间复杂度就会退化成 \(O(n)\),这时我们就需要平衡树来解决这个问题. \(Splay\)(伸展树)是平衡树的一种,它的每一步插入.查找和删除的平摊时间都是 \(O ...

  6. redis 中的 list

    lpush K1 V1 V2 V3   左边加入list rpush k1 v1 v2 v3 右边加入list lpop k1 左边吐出一个值 rpop k1 右边吐出一个值 lrange k1 0 ...

  7. Vue错误:Cannot read properties of undefined (reading '$router')

    解决方案 这是由于this的指向有问题,我们只需要重新声明一下this就可以重新调用了

  8. oracle 11g手工建库步骤(初学者)

    要建立的数据库ORACLE_SID=test1sys和system的密码为oracle1.建立相应的目录mkdir /u01/app/oracle/oradata/test1mkdir /u01/ap ...

  9. 手写promise之分步解析

    promise是es6推出适用于异步请求的构造函数,帮助解决回调地狱的问题,以下内容将自定义实现promise,只包括基本使用,所以一些边界情况考虑没有在内. 如果对promise用法还不熟悉的朋友可 ...

  10. 《深入理解Java虚拟机》读书笔记:Class类文件的结构

    Class类文件的结构 Sun公司以及其他虚拟机提供商发布了许多可以运行在各种不同平台上的虚拟机,这些虚拟机都可以载入和执行同一种平台无关的的程序存储格式--字节码(ByteCode),从而实现了程序 ...