ImageVerifierCode 换一换
格式:DOCX , 页数:27 ,大小:413.44KB ,
资源ID:8363528      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/8363528.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(基于Socket的Android手机视频实时传输.docx)为本站会员(b****5)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

基于Socket的Android手机视频实时传输.docx

1、基于Socket的Android手机视频实时传输基于Socket的Android手机视频实时传输基于Socket的Android手机视频实时传输肖泽云首先,简单介绍一下原理。主要是在手机客户端(Android)通过实现Camera.PreviewCallback接口,在其onPreviewFrame重载函数里面获取摄像头当前图像数据,然后通过Socket将图像数据和相关的用户名、命令等数据传输到服务器程序中。服务器端(PC端)采用C#编写,通过监听相应的端口,在获取数据后进行相应的命令解析和图像数据还原,然后将图像数据传递至PictureBox控件中用于显示,这样就实现了手机摄像头的视频数据实

2、时传输到服务器上。如果需要将这些视频进行转发,通过服务器再将这些数据复制转发即可。效果如下:对于Android客户端上主要有几个地方需要注意,第一个就是Socket通信。Socket通信可以通过Socket类来实现,直接结合PrintWriter来写入命令,如下定义的一个专门用于发送命令的线程类,当要连接到服务器和与服务器断开时,都需要发送命令通知服务器,此外在进行其他文字传输时也可以采用该方法,具体代码如下: /*发送命令线程*/ class MySendCommondThread extends Thread private String commond; public MySendCom

3、mondThread(String commond) mond=commond; public void run() /实例化Socket try Socket socket=new Socket(serverUrl,serverPort); PrintWriter out = new PrintWriter(socket.getOutputStream(); out.println(commond); out.flush(); catch (UnknownHostException e) catch (IOException e) 如果是采用Socket发送文件,则可以通过OutputStr

4、eam将ByteArrayInputStream数据流读入,而文件数据流则转换为ByteArrayOutputStream。如果需要在前面添加文字,同样也需要转换为byte,然后写入OutputStream。同样也可以通过定义一个线程类发送文件,如下: /*发送文件线程*/ class MySendFileThread extends Thread private String username; private String ipname; private int port; private byte byteBuffer = new byte1024; private OutputStre

5、am outsocket; private ByteArrayOutputStream myoutputstream; public MySendFileThread(ByteArrayOutputStream myoutputstream,String username,String ipname,int port) this.myoutputstream = myoutputstream; this.username=username; this.ipname = ipname; this.port=port; try myoutputstream.close(); catch (IOEx

6、ception e) e.printStackTrace(); public void run() try /将图像数据通过Socket发送出去 Socket tempSocket = new Socket(ipname, port); outsocket = tempSocket.getOutputStream(); /写入头部数据信息 String msg=.URLEncoder.encode(PHONEVIDEO|+username+|,utf-8); byte buffer= msg.getBytes(); outsocket.write(buffer); ByteArrayInput

7、Stream inputstream = new ByteArrayInputStream(myoutputstream.toByteArray(); int amount; while (amount = inputstream.read(byteBuffer) != -1) outsocket.write(byteBuffer, 0, amount); myoutputstream.flush(); myoutputstream.close(); tempSocket.close(); catch (IOException e) e.printStackTrace(); 而获取摄像头当前图

8、像的关键在于onPreviewFrame()重载函数里面,该函数里面有两个参数,第一个参数为byte,为摄像头当前图像数据,通过YuvImage可以将该数据转换为图片文件,同时还可用对该图片进行压缩和裁剪,将图片进行压缩转换后转换为 ByteArrayOutputStream数据,即前面发送文件线程类中所需的文件数据,然后采用线程发送文件,如下代码: Override public void onPreviewFrame(byte data, Camera camera) / TODO Auto-generated method stub /如果没有指令传输视频,就先不传 if(!startS

9、endVideo) return; if(tempPreRateVideoPreRate) tempPreRate+; return; tempPreRate=0; try if(data!=null) YuvImage image = new YuvImage(data,VideoFormatIndex, VideoWidth, VideoHeight,null); if(image!=null) ByteArrayOutputStream outstream = new ByteArrayOutputStream(); /在此设置图片的尺寸和质量 pressToJpeg(new Rect(

10、0, 0, (int)(VideoWidthRatio*VideoWidth), (int)(VideoHeightRatio*VideoHeight), VideoQuality, outstream); outstream.flush(); /启用线程将图像数据发送出去 Thread th = new MySendFileThread(outstream,pUsername,serverUrl,serverPort); th.start(); catch (IOException e) e.printStackTrace(); 值得注意的是,在调试中YuvImage可能找不到,在模拟机上无

11、法执行该过程,但是编译后在真机中可以通过。此外,以上传输文字字符都是采用UTF编码,在服务器端接收时进行解析时需要采用对应的编码进行解析,否则可能会出现错误解析。Android客户端中关键的部分主要就这些,新建一个Android项目(项目名称为SocketCamera),在main布局中添加一个SurfaceView和两个按钮,如下图所示:然后在SocketCameraActivity.java中添加代码,具体如下:package com.xzy;import java.io.ByteArrayInputStream;import java.io.ByteArrayOutputStream;i

12、mport java.io.IOException;import java.io.OutputStream;import java.io.PrintWriter;import .Socket;import .UnknownHostException;import android.app.Activity;import android.app.AlertDialog;import android.content.DialogInterface;import android.content.Intent;import android.content.SharedPreferences;import

13、 android.graphics.Rect;import android.graphics.YuvImage;import android.hardware.Camera;import android.hardware.Camera.Size;import android.os.Bundle;import android.preference.PreferenceManager;import android.view.Menu;import android.view.MenuItem;import android.view.SurfaceHolder;import android.view.

14、SurfaceView;import android.view.View;import android.view.WindowManager;import android.view.View.OnClickListener;import android.widget.Button;public class SocketCameraActivity extends Activity implements SurfaceHolder.Callback,Camera.PreviewCallback private SurfaceView mSurfaceview = null; / SurfaceV

15、iew对象:(视图组件)视频显示 private SurfaceHolder mSurfaceHolder = null; / SurfaceHolder对象:(抽象接口)SurfaceView支持类 private Camera mCamera = null; / Camera对象,相机预览 /*服务器地址*/ private String pUsername=XZY; /*服务器地址*/ private String serverUrl=192.168.1.100; /*服务器端口*/ private int serverPort=8888; /*视频刷新间隔*/ private int

16、VideoPreRate=1; /*当前视频序号*/ private int tempPreRate=0; /*视频质量*/ private int VideoQuality=85; /*发送视频宽度比例*/ private float VideoWidthRatio=1; /*发送视频高度比例*/ private float VideoHeightRatio=1; /*发送视频宽度*/ private int VideoWidth=320; /*发送视频高度*/ private int VideoHeight=240; /*视频格式索引*/ private int VideoFormatIn

17、dex=0; /*是否发送视频*/ private boolean startSendVideo=false; /*是否连接主机*/ private boolean connectedServer=false; private Button myBtn01, myBtn02; /* Called when the activity is first created. */ Override public void onCreate(Bundle savedInstanceState) super.onCreate(savedInstanceState); setContentView(R.la

18、yout.main); /禁止屏幕休眠 getWindow().setFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON, WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); mSurfaceview = (SurfaceView) findViewById(R.id.camera_preview); myBtn01=(Button)findViewById(R.id.button1); myBtn02=(Button)findViewById(R.id.button2); /开始连接主机按钮

19、myBtn01.setOnClickListener(new OnClickListener() public void onClick(View v) /Common.SetGPSConnected(LoginActivity.this, false); if(connectedServer)/停止连接主机,同时断开传输 startSendVideo=false; connectedServer=false; myBtn02.setEnabled(false); myBtn01.setText(开始连接); myBtn02.setText(开始传输); /断开连接 Thread th = n

20、ew MySendCommondThread(PHONEDISCONNECT|+pUsername+|); th.start(); else/连接主机 /启用线程发送命令PHONECONNECT Thread th = new MySendCommondThread(PHONECONNECT|+pUsername+|); th.start(); connectedServer=true; myBtn02.setEnabled(true); myBtn01.setText(停止连接); ); myBtn02.setEnabled(false); myBtn02.setOnClickListene

21、r(new OnClickListener() public void onClick(View v) if(startSendVideo)/停止传输视频 startSendVideo=false; myBtn02.setText(开始传输); else / 开始传输视频 startSendVideo=true; myBtn02.setText(停止传输); ); Override public void onStart()/重新启动的时候 mSurfaceHolder = mSurfaceview.getHolder(); / 绑定SurfaceView,取得SurfaceHolder对象

22、mSurfaceHolder.addCallback(this); / SurfaceHolder加入回调接口 mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);/ 设置显示器类型,setType必须设置 /读取配置文件 SharedPreferences preParas = PreferenceManager.getDefaultSharedPreferences(SocketCameraActivity.this); pUsername=preParas.getString(Username, XZY); se

23、rverUrl=preParas.getString(ServerUrl, 192.168.0.100); String tempStr=preParas.getString(ServerPort, 8888); serverPort=Integer.parseInt(tempStr); tempStr=preParas.getString(VideoPreRate, 1); VideoPreRate=Integer.parseInt(tempStr); tempStr=preParas.getString(VideoQuality, 85); VideoQuality=Integer.par

24、seInt(tempStr); tempStr=preParas.getString(VideoWidthRatio, 100); VideoWidthRatio=Integer.parseInt(tempStr); tempStr=preParas.getString(VideoHeightRatio, 100); VideoHeightRatio=Integer.parseInt(tempStr); VideoWidthRatio=VideoWidthRatio/100f; VideoHeightRatio=VideoHeightRatio/100f; super.onStart(); O

25、verride protected void onResume() super.onResume(); InitCamera(); /*初始化摄像头*/ private void InitCamera() try mCamera = Camera.open(); catch (Exception e) e.printStackTrace(); Override protected void onPause() super.onPause(); try if (mCamera != null) mCamera.setPreviewCallback(null); / !这个必须在前,不然退出出错

26、mCamera.stopPreview(); mCamera.release(); mCamera = null; catch (Exception e) e.printStackTrace(); Override public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) / TODO Auto-generated method stub if (mCamera = null) return; mCamera.stopPreview(); mCamera.setPreviewCallback(thi

27、s); mCamera.setDisplayOrientation(90); /设置横行录制 /获取摄像头参数 Camera.Parameters parameters = mCamera.getParameters(); Size size = parameters.getPreviewSize(); VideoWidth=size.width; VideoHeight=size.height; VideoFormatIndex=parameters.getPreviewFormat(); mCamera.startPreview(); Override public void surfac

28、eCreated(SurfaceHolder holder) / TODO Auto-generated method stub try if (mCamera != null) mCamera.setPreviewDisplay(mSurfaceHolder); mCamera.startPreview(); catch (IOException e) e.printStackTrace(); Override public void surfaceDestroyed(SurfaceHolder holder) / TODO Auto-generated method stub if (nu

29、ll != mCamera) mCamera.setPreviewCallback(null); / !这个必须在前,不然退出出错 mCamera.stopPreview(); mCamera.release(); mCamera = null; Override public void onPreviewFrame(byte data, Camera camera) / TODO Auto-generated method stub /如果没有指令传输视频,就先不传 if(!startSendVideo) return; if(tempPreRateVideoPreRate) tempPreRate+; retur

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1