Android实时监控项目第四篇:后台线程发送预览帧视频数据
来源:互联网 发布:超高速usb3.0端口 编辑:程序博客网 时间:2024/05/14 15:34
还记得上篇提到的setPreviewCallback(Camera.PreviewCallback cb)函数吗?我们在开始预览帧视频之前,调用的它,这里要注意其内部的Camera.PreviewCallback类型的参数,我们需要写一个类继承Camera.PreviewCallback的类,在该类中覆写public void onPreviewFrame(byte[] data, Camera camera)方法,这里的data参数保存的即是预览帧是视频数据,一旦程序调用Camera.PreviewCallback接口,便会自动调用发方法,因此当我们在开始预览帧视频之前调用setPreviewCallback(Camera.PreviewCallback cb)函数时,便会回调该方法,理论上来说我们在这个方法中写发送帧视频的代码就行了,但实际上我们并不能这么做,因为发送视频数据是一个很耗时的操作,为了防止UI线程阻塞,我们需要另外开启一个线程,在该线程中实现视频的发送操作。
这里我们采用AsyncTask<Void, Void, Void>后台线程,因此我们需要再写一个类,继承AsyncTask<Void, Void, Void>抽象类,并覆写其中的protected Void doInBackground(Void... params)方法,在该方法中编写发送视频数据的程序即可,这里要注意形参的含义,因为的项目中不需要用到这三个参数,因此全部传入Void,关于AsyncTask的详细使用,可以参见这两篇博客:http://blog.csdn.net/ns_code/article/details/12889455和http://blog.csdn.net/liuhe688/article/details/6532519,我在该方法中写的代码如下:
- //该方法运行在后台线程中,主要负责执行耗时的后台计算传输等工作,
- //实际的后台操作被UI Thread调用时,该方法被回调
- @Override
- protected Void doInBackground(Void... params) {
- //cam = (CameraActivity)context;
- Size size = cam.getCamera().getParameters().getPreviewSize();
- int wide = size.width;
- int high = size.height;
- YuvImage image = new YuvImage(data, ImageFormat.NV21, wide, high, null);
- //因为要实时处理视频流,因此用内存操作流比较合适
- ByteArrayOutputStream os = new ByteArrayOutputStream(data.length);
- if(!image.compressToJpeg(new Rect(0, 0, wide, high), 100, os)){
- return null;
- }
- send(os);
- return null;
- }
这里倒数第三行的send(os)记为发送视频的操作,当然,如果你是做其他的操作,而不是传输视频数据,你也可以将其改为其他的函数,比如做街景检测、人脸车牌识别等,而其他代码基本不用修改,发送视频的send方法基本就是按照TCP协议编写,在JAVA中是用Socket类编写客户端的代码:
- //发送视频流到PC端,这里传递过来的参数os中保存的是视频输出流数据
- private void send(ByteArrayOutputStream os) {
- //定义用来保存从输入流中读取的视频流数据的byte数组
- byte[] buffer = new byte[1024];
- try {
- Socket client = new Socket(ipName,30000);
- OutputStream outSocket = client.getOutputStream();
- //实例化内存输入流,将视频流数据写入到内存中
- ByteArrayInputStream inputFromOs = new ByteArrayInputStream(os.toByteArray());
- //不断从内存中读取数据到buffer中,不断再从buffer中将视频数据发送到outSocket流中
- int amount;
- while((amount =inputFromOs.read(buffer) ) != -1)
- outSocket.write(buffer, 0, amount);
- //这里需要刷新用到缓冲区的输出流
- os.flush();
- inputFromOs.close();
- os.close();
- outSocket.close();
- } catch (UnknownHostException e) {
- e.printStackTrace();
- System.out.println("无法找到要连接的服务器");
- } catch (IOException e) {
- e.printStackTrace();
- System.out.println("IO错误");
- }
- }
最后,什么时候调用protected Void doInBackground(Void... params)方法呢?看了上面那两篇博客,应该也会明白了,当调用execute(Params... params)方法时,便会自动回调该方法,从而执行其内部代码。
至此,整个项目的Android客户端代码已经编写完毕,下篇将讲述PC端(亦即服务端)代码的实现
- Android实时监控项目第四篇:后台线程发送预览帧视频数据
- Android实时监控项目第四篇:后台线程发送预览帧视频数据
- Android实时监控项目第三篇:通过摄像头实时预览帧视频
- Android实时监控项目第三篇:通过摄像头实时预览帧视频
- Android手机实时视频监控
- Android手机实时视频监控
- Android手机实时视频监控
- Android手机实时视频监控
- Android中实时视频监控方案设计思路
- Android中实时视频监控方案设计思路
- Android中实时视频监控方案设计思路
- Android视频不预览”,获取视频数据
- Android实时监控项目第二篇:登陆界面的设计
- Android实时监控项目第二篇:登陆界面的设计
- Android端通过Usb建立Socket通讯(实时发送视频数据)
- Android摄像头开发:实时摄像头视频预览帧的编码问题(二)
- Android摄像头开发:实时摄像头视频预览帧的编码问题
- Android摄像头开发:实时摄像头视频预览帧的编码问题(二)
- UITableView 默认选择某行的方法
- Linux下建立SSHFS共享
- 单例程序
- 中国移动:物联网项目实战开发企业级应用(ssp框架应用、EXTJS4.2、GoogleMap、JPA)
- jQuery 入门教程(9):终止动画
- Android实时监控项目第四篇:后台线程发送预览帧视频数据
- for循环的简单应用
- Linux 内核的排队自旋锁(FIFO Ticket Spinlock)
- 超强备用手机换衫记——NOKIA 6120c 换壳教程
- Windows Server 2012 VDI 标准部署之创建虚拟机集合(续)
- jQuery 入门教程(10): 回调函数
- 面向对象思考过程
- Perfmon - Windows 自带系统监测工具
- 《将博客搬至CSDN》