如今移动直播如火如荼的一片大火。而直播技术也层出不穷,各类开源的,收费的直播SDK平台也很多。以上全部种种,虽然能够快速的实现直播功能,但对于本身技术的积累和学习并无什么好处。本例子经过不借助任何框架。纯手打代码的模式。全部代码皆可编辑查看方便本身学习和积累。服务器
手机直播的原理很简单。就是经过手机带有的Camera模块。获取到Camera的数据,而后经过网络,发送到服务器。服务器再经过广播,推送到其余客户端。主要涉及到采集数据,发送数据,广播数据,客户端接受数据,再显示数据。以下图所示,视频直播离不开视频采集,原始的视频数据太大了,须要进行视频处理,处理后再压缩,节省宝贵的宽带,最后进行推流,推出去。网络
以上,说的很简单。其实实际操做起来,有好多技术问题要处理。普通的手机若是打开数据录像,10s的数据就有100多兆。如何处理这样的数据就设计到编码问题。这是一个比较大的坑。另外,还有就是带宽问题了。不管你编码压缩的多好,用户量若是上去,其带宽使用是至关可观。不一样地域,不一样电信提供商的都要考虑。另外就是服务器并发推送的处理。10万个用户和500万的用户视频推送处理是个不小的挑战。而本文对于以上问题都不作讨论。仅仅是个局域网手机直播demo。架构
代码架构并发
先说下实现原理。经过调用Android Camera,经过onReviewListener进行数据的获取。框架
camera.setPreviewCallback(new Camera.PreviewCallback() { @Override public void onPreviewFrame(byte[] data, Camera camera) { //获取当前的屏幕预览的像素 长与高 int mWidth = camera.getParameters().getPreviewSize().width; int mHeight = camera.getParameters().getPreviewSize().height; Log.e(TAG, "mWidth >" + mWidth + " mHeight" + mHeight); Log.e(TAG, "data length >" + data.length); // int[] buf = imageUtilEngine.decodeYUV420SP(data, // mWidth, // mHeight); // 对要发送的数据进行封装 进行 TLV 格式的封装 TAG L length V 长度 // TAG 为: width 0xF0 0xFF, height 0xF1 0xFF, data 0xF2 // 0xFF // 为了方便查询 0xF0 0xFF 为 开始标志位 。+(width 4位)+(height 4位)+ // (data长度 4 位) + data //对获取的数据进行打包处理 int length = 2 + 4 + 4 + 4 + data.length; ByteBuffer bb = ByteBuffer.allocate(length); bb.put(new byte[] { (byte) 0xF0, (byte) 0xFF }); bb.put(Utils.intToBytes2(mWidth)); bb.put(Utils.intToBytes2(mHeight)); bb.put(Utils.intToBytes2(data.length)); bb.put(data); //执行发送命令操做 sendData(bb.array()); } });
以上是一种获取预览信息的方式。除了此种方式,还有经过MediaRecorder的方式。获取视频信息。ide
还有一种直接把SurfaceView引用传下去,使用NDK调用Camera,直接获取数据源信息。学习
此种方式效率最高。可是这是Android工程师要求熟练NDK操做。编码
考虑过没,那个预览得到的数据是什么数据?spa
这个是大名鼎鼎的YUV数据。你搜索下这种数据格式。它算是各类视频流获取的第一手数据。原生数据。.net
对于YUV数据如何在客户端显示出来呢?这就是另外一个问题了。理论上SurfaceView能够直接显示的。可是Java层并无提供
相关接口。你须要调用NDK层里实现。
没写完,待续
代码工程:
http://download.csdn.net/detail/a315823806/9699223