android 与后台实时视频,Android实时监控项目第四篇:后台线程发送预览帧视频数据...

还记得上篇提到的setPreviewCallback(Camera.PreviewCallback cb)函数吗?我们在开始预览帧视频之前,调用的它,这里要注意其内部的Camera.PreviewCallback类型的参数,我们需要写一个类继承Camera.PreviewCallback的类,在该类中覆写public void onPreviewFrame(byte[] data, Camera camera)方法,这里的data参数保存的即是预览帧是视频数据,一旦程序调用Camera.PreviewCallback接口,便会自动调用发方法,因此当我们在开始预览帧视频之前调用setPreviewCallback(Camera.PreviewCallback cb)函数时,便会回调该方法,理论上来说我们在这个方法中写发送帧视频的代码就行了,但实际上我们并不能这么做,因为发送视频数据是一个很耗时的操作,为了防止UI线程阻塞,我们需要另外开启一个线程,在该线程中实现视频的发送操作。

这里我们采用AsyncTask后台线程,因此我们需要再写一个类,继承AsyncTask抽象类,并覆写其中的protected Void doInBackground(Void... params)方法,在该方法中编写发送视频数据的程序即可,这里要注意形参的含义,因为的项目中不需要用到这三个参数,因此全部传入Void.

//该方法运行在后台线程中,主要负责执行耗时的后台计算传输等工作,

//实际的后台操作被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)方法时,便会自动回调该方法,从而执行其内部代码。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值