美文网首页
以TCP Socket方式实现安卓摄像头数据的传输

以TCP Socket方式实现安卓摄像头数据的传输

作者: SHUTUP | 来源:发表于2016-05-17 22:54 被阅读1044次

    前言

    上一篇文章中我们使用了浏览器的HTTP SERVER PUSH功能,效果还行吧,不过用户体验上要差一些,因此我在这篇文章中将介绍直接通过Socket发送图片数据,然后客户端解析数据后直接展示的功能。

    效果

    Screenshot_2016-05-17-22-52-26_com.shutup.socketc.png

    Demo地址

    SocketCamera

    原理

    其实我们上一篇文章中也是通过Socket进行数据的传输的,只是数据的解析是由浏览器完成的,我们这次改为我们自己进行解析和展示。一些技术的点还是一样的。
    主要技术点:

    1. 获取原始摄像头数据
    2. 编码成合适的格式
    3. socket发送出去

    说明

    我们这里的发送和接收仍然是在单独的线程中实现,通过handler和主线程进行交互。
    服务端的发送逻辑:先发送数据的长度,占4个字节,接着发送数据的字节数组。

    class ServerWriter extends Thread {    
    @Override   
    public void run() {        
    super.run();        
    try {            
    //listen on 8888            
    mServerSocket = new ServerSocket(8888);            
    mSocket = mServerSocket.accept();            
    mOutputStream = mSocket.getOutputStream();        
    } catch (IOException e) {            
    e.printStackTrace();        
    }        
    while (isRun) {            
    if (isOk) {                
    try {                   
     //first write the data length to the outputStream ,it need a int size 4                   
    mOutputStream.write(ByteBuffer.allocate(4).putInt(baos.size()).array());                    
    //then write the data to the outputStream                    
    mOutputStream.write(baos.toByteArray());                    
    mOutputStream.flush();                
    } catch (IOException e) {                    
    e.printStackTrace();                    
    //if have any exception,close the thread                    
    isRun = false;               
     }                
    isOk = false;            
    }        
    }    
    }
    }
    

    客户端的接收逻辑:先读取4个字节,解析出数据的长度,然后通过循环读出所有的数据,循环的逻辑是这样的,如果剩余的待读取字节小于了我们缓冲区的大小,那么直接读取对应的大小,否则继续按照缓冲区大小进行读取。

    while (isRun) {    
    byte[] sizeArray = new byte[4];   
    try {        
    mInputStream.read(sizeArray);    
    } catch (IOException e) {        
    e.printStackTrace();    
    }    
    int picLength = ByteBuffer.wrap(sizeArray).asIntBuffer().get();    
    if (picLength == 0){        
    isRun = false;    
    }    
    Log.d("ClientReader", "picLength:" + picLength);    
    byte[] b = new byte[picLength];    
    try {        
    int totalLen = 0;        
    int bufferSize = 4 * 1024;        
    //when the read totalLen is less than the picLength        
    while (totalLen < picLength) {            
    int len = 0;            
    //if the left data is less than bufferSize,read them all ,            
    //else read them by bufferSize            
    if (bufferSize >= picLength - totalLen) {                
    len = mInputStream.read(b, totalLen, picLength - totalLen);            
    } else {                
    len = mInputStream.read(b, totalLen, bufferSize);            
    }            
    totalLen += len;        
    }    
    } catch (IOException e) {        
    e.printStackTrace();    
    }    
    ByteArrayInputStream inputStream = new ByteArrayInputStream(b);   
    Bitmap bitmap = BitmapFactory.decodeStream(inputStream);    
    Message message = mHandler.obtainMessage();    
    message.what = 1;    
    if (bitmap != null) {        
    message.obj = bitmap;        
    mHandler.sendMessage(message);    
    }}
    

    相关文章

      网友评论

          本文标题:以TCP Socket方式实现安卓摄像头数据的传输

          本文链接:https://www.haomeiwen.com/subject/sqnirttx.html