Android采集音视频上传服务器
本文相关代码位于:https://codechina.csdn.net/mirrors/greenjim301/titan?utm_source=csdn_github_accelerator
虽然一直做音视频相关的开发,但一直没有接触过Android开发,因为一些机缘巧合的事,就决定做Android上的音视频采集。
起初没有接触过Android开发,就找网上教程看看,然后在github上找了个音视频采集相关的Demo,在这个Demo上逐渐按照自己的理解去改。因为要用到Android硬编,所以定位在Android 5.0版本以上。
音视频采集和编码基本上都是参考Webrtc相关部分的代码。视频采集用的Camera2,视频编码用的MediaCodec,编码为H264。视频采集送编码前还涉及到YUV的旋转,获取旋转角度方法参考Webrtc相关代码,旋转通过集成的Libyuv实现。音频采集用的AudioRecord,这是要说明的是Webrtc代码中把软实现的噪声抑制和去回声排除掉了,因为这个开销比较大。我在用的时候并没有排除,因为我想有总比没有好。音频编码我采用的AAC,Webrtc上都是窄带音频编码,没有AAC编码,所以就照着视频编码的代码写了AAC编码。
之后的部分都是用C++实现的,NDK编译,通过JNI由Java层调用。将编码后的音视频流打包成RTP包,RTP打包主要参考FFmpeg的代码。再通过私有协议上传到服务器,服务器是我自己实现的,私有协议格式是我自己定的。除了音视频RTP包传输,我还做了一个登录请求,消息体用的Json,Json解析同集成的JsonCpp实现。网络传输部分主要依赖我自己封装的一个跨平台网络中间件k_util,这个中间件可以在Windows、Linux和Android平台上使用。如果再把kqueue封装一下,还可以在IOS平台上使用。
开发中主要遇到三个难点。一是多线程,初次用Java开发,我平时都是用C++的,感觉Java在弱化线程的概念,但线程又是实实在在存在的,所以经常遇到跨线程访问失效的问题,最后还是通过加锁解决。二是屏幕旋转的问题,最开始屏幕旋转会把View销毁再重新创建,这显然不可取的。后来参考网上的方法屏幕旋转不销毁View了,但编码后的视频方向老不对,参考Webrtc相关代码解决。三是Native层回调Java。登录返回结果的解析在Native层完成,需要将结果通知到主线程更新UI。参考网上方法实现了Native回调Java方法,再通过Handler通知到主线程更新UI。
代码在我的中兴blade A3手机上测试通过,Android版本7.0。
对应服务器的代码在这里:https://codechina.csdn.net/mirrors/greenjim301/kronos?utm_source=csdn_github_accelerator