




已阅读5页,还剩16页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
基于 Socket 的 Android 手机视频实时传输 肖泽云 首先,简单介绍一下原理。主要是在手机客户端(Android)通过实现 Cam era.PreviewCallback 接口,在其 onPreviewFrame 重载函数里面获取摄像头当 前图像数据,然后通过 Socket 将图像数据和相关的用户名、命令等数据传输到 服务器程序中。服务器端(PC 端)采用 C#编写,通过监听相应的端口,在获取 数据后进行相应的命令解析和图像数据还原,然后将图像数据传递至 PictureB ox 控件中用于显示,这样就实现了手机摄像头的视频数据实时传输到服务器上 。如果需要将这些视频进行转发,通过服务器再将这些数据复制转发即可。效 果如下: 对于 Android 客户端上主要有几个地方需要注意,第一个就是 Socket 通信 。Socket 通信可以通过 Socket 类来实现,直接结合 PrintWriter 来写入命令 ,如下定义的一个专门用于发送命令的线程类,当要连接到服务器和与服务器 断开时,都需要发送命令通知服务器,此外在进行其他文字传输时也可以采用 该方法,具体代码如下: /*发送命令线程*/ classclass MySendCommondThread extendsextends Thread privateprivate String commond; publicpublic MySendCommondThread(String commond) mond=commond; publicpublic voidvoid run() /实例化Socket trytry Socket socket=newnew Socket(serverUrl,serverPort); PrintWriter out = newnew PrintWriter(socket.getOutputStream(); out.println(commond); out.flush(); catchcatch (UnknownHostException e) catchcatch (IOException e) 如果是采用 Socket 发送文件,则可以通过 OutputStream 将 ByteArrayInp utStream 数据流读入,而文件数据流则转换为 ByteArrayOutputStream。如果 需要在前面添加文字,同样也需要转换为 byte,然后写入 OutputStream。同样 也可以通过定义一个线程类发送文件,如下: /*发送文件线程*/ classclass MySendFileThread extendsextends Thread privateprivate String username; privateprivate String ipname; privateprivate intint port; privateprivate bytebyte byteBuffer = newnew bytebyte1024; privateprivate OutputStream outsocket; privateprivate ByteArrayOutputStream myoutputstream; publicpublic MySendFileThread(ByteArrayOutputStream myoutputstream,String username,String ipname,intint port) thisthis.myoutputstream = myoutputstream; thisthis.username=username; thisthis.ipname = ipname; thisthis.port=port; trytry myoutputstream.close(); catchcatch (IOException e) e.printStackTrace(); publicpublic voidvoid run() trytry /将图像数据通过Socket发送出去 Socket tempSocket = newnew Socket(ipname, port); outsocket = tempSocket.getOutputStream(); /写入头部数据信息 String msg=.URLEncoder.encode(“PHONEVIDEO|“+username+“|“,“utf-8“); bytebyte buffer= msg.getBytes(); outsocket.write(buffer); ByteArrayInputStream inputstream = newnew ByteArrayInputStream(myoutputstream.toByteArray(); intint amount; whilewhile (amount = inputstream.read(byteBuffer) != -1) outsocket.write(byteBuffer, 0, amount); myoutputstream.flush(); myoutputstream.close(); tempSocket.close(); catchcatch (IOException e) e.printStackTrace(); 而获取摄像头当前图像的关键在于 onPreviewFrame()重载函数里面,该函 数里面有两个参数,第一个参数为 byte,为摄像头当前图像数据,通过 YuvI mage 可以将该数据转换为图片文件,同时还可用对该图片进行压缩和裁剪,将 图片进行压缩转换后转换为 ByteArrayOutputStream 数据,即前面发送文件线 程类中所需的文件数据,然后采用线程发送文件,如下代码: Override publicpublic voidvoid onPreviewFrame(bytebyte data, Camera camera) / TODOTODO Auto-generated method stub /如果没有指令传输视频,就先不传 ifif(!startSendVideo) returnreturn; ifif(tempPreRate 编译程序,在模拟机上效果如下: 接下来就是服务器端接收手机传输的视频数据,这与一般 CS 架构中服务器 程序类似,主要是监听端口,然后解析数据。现新建一个 C#应用程序项目(项 目名称为“手机摄像头” ) ,首先定义一些全局变量,主要包括服务器地址、端 口以及相关监听对象等,如下: / / 服务器状态,如果为false表示服务器暂停,true表示服务器开启 / public bool ServerStatus = false; / / 服务器地址 / public string ServerAddress; / / 服务器端口 / public int ServerPort; / / 开启服务的线程 / private Thread processor; / / 用于TCP监听 / private TcpListener tcpListener; / / 与客户端连接的套接字接口 / private Socket clientSocket; / / 用于处理客户事件的线程 / private Thread clientThread; / / 手机客户端所有客户端的套接字接口 / private Hashtable PhoneClientSockets = new Hashtable(); / / 手机用户类数组 / public ArrayList PhoneUsersArray = new ArrayList(); / / 手机用户名数组 / public ArrayList PhoneUserNamesArray = new ArrayList(); / / 图像数据流 / private ArrayList StreamArray; 然后定义处理客户端传递数据的函数 ProcessClient(),主要对接收数据 进行命令解析。如果是手机连接的命令(“PHONECONNECT“) ,就在记录该套接字 对象,同时在列表中添加该对象;如果是断开连接的命令(“PHONEDISCONNECT“ ),就移除该对象;如果是手机视频命令(“PHONEVIDEO“) ,就分解其包含的图 像数据,如果存在该用户对应的视频窗口,就传递该图像数据到这个视频窗口 中。具体代码如下: #region 处理客户端传递数据及处理事情 / / 处理客户端传递数据及处理事情 / private void ProcessClient() Socket client = clientSocket; bool keepalive = true; while (keepalive) Thread.Sleep(50); Byte buffer = null; bool tag = false; try buffer = new Byte1024;/client.Available int count = client.Receive(buffer, SocketFlags.None);/接收客户端套接字数据 if (count 0)/接收到数据 tag = true; catch (Exception e) keepalive = false; if (client.Connected) client.Disconnect(true); client.Close(); if (!tag) if (client.Connected) client.Disconnect(true); client.Close(); keepalive = false; string clientCommand = “; try clientCommand = System.Text.Encoding.UTF8.GetString(buffer);/转换接收的数据,数据来源 于客户端发送的消息 if (clientCommand.Contains(“%7C“)/从Android客户 端传递部分数据 clientCommand = clientCommand.Replace(“%7C“, “|“);/替换UTF中字符%7C为| catch /分析客户端传递的命令来判断各种操作 string messages = clientCommand.Split(|); if (messages != null /第一个字符串为命令 if (tempStr = “PHONECONNECT“)/手机连接服务器 try string tempClientName = messages1.Trim(); PhoneClientSockets.Remove(messages1);/ 删除之前与该用户的连接 PhoneClientSockets.Add(messages1, client);/建立与该客户端的Socket连接 UserClass tempUser = new UserClass(); tempUser.UserName = tempClientName; tempUser.LoginTime = DateTime.Now; Socket tempSocket = (Socket)PhoneClientSocketstempClientName; tempUser.IPAddress = tempSocket.RemoteEndPoint.ToString(); int tempIndex = PhoneUserNamesArray.IndexOf(tempClientName); if (tempIndex = 0) PhoneUserNamesArraytempIndex = tempClientName; PhoneUsersArraytempIndex = tempUser; MemoryStream stream2 = (MemoryStream)StreamArraytempIndex; if (stream2 != null) stream2.Close(); stream2.Dispose(); else/新增加 PhoneUserNamesArray.Add(tempClientName); PhoneUsersArray.Add(tempUser); StreamArray.Add(null); RefreshPhoneUsers(); catch (Exception except) else if (tempStr = “PHONEDISCONNECT“)/某个客户 端退出了 try string tempClientName = messages1; RemovePhoneUser(tempClientName); int tempPhoneIndex = PhoneUserNamesArray.IndexOf(tempClientName); if (tempPhoneIndex = 0) PhoneUserNamesArray.RemoveAt(tempPhoneIndex); MemoryStream memStream = (MemoryStream)StreamArraytempPhoneIndex; if (memStream != null) memStream.Close(); memStream.Dispose(); StreamArray.RemoveAt(tempPhoneIndex); Socket tempSocket = (Socket)PhoneClientSocketstempClientName;/第1个为客户端的ID,找到该 套接字 if (tempSocket != null) tempSocket.Close(); PhoneClientSockets.Remove(tempClientName); keepalive = false; catch (Exception except) RefreshPhoneUsers(); else if (tempStr = “PHONEVIDEO“)/接收手机数据流 try string tempClientName = messages1; string tempForeStr = messages0 + “%7C“ + messages1 + “%7C“; int startCount = System.Text.Encoding.UTF8.GetByteCount(tempForeStr); try MemoryStream stream = new MemoryStream(); if (stream.CanWrite)
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 棉花丰收科技手册
- 河北省曲周县2025年上半年公开招聘村务工作者试题含答案分析
- 河北省河间市2025年上半年公开招聘辅警试题含答案分析
- 2025版石材行业绿色供应链体系建设合同
- 2025版工业厂房使用权租赁合同
- 2025版商铺入股及物业运营管理合同
- 2025电子科技大学与知名企业联合研发项目技术合同范本
- 2025电脑绣花机产品研发与技术转移合同
- 2025版水电暖工程设计与施工总承包合同范本
- 2025年度吊装设备操作人员培训与考核合同
- 成都第四十九中学数学新初一分班试卷含答案
- 《平方根》(第1课时)示范公开课教学设计【北师大版八年级数学上册】
- 《信息检索与处理(修订版)》课件下 第2单元第二课 分析信息-第3单元 综合探究实践活动
- 楼盘融资商业计划书
- 物业费催费技巧(干货版)
- 2023-2024学年江苏省南通市如皋市重点中学八年级(上)第二次月考数学试卷(含解析)
- 脑梗塞个案护理查房
- 2013年天津公务员考试职位表
- 矿山安全供电讲义
- 小学语文阅读理解答题万能公式全套
- 公司管理程序文件模板
评论
0/150
提交评论