基于Socket的Android手机视频实时传输Word格式文档下载.docx
《基于Socket的Android手机视频实时传输Word格式文档下载.docx》由会员分享,可在线阅读,更多相关《基于Socket的Android手机视频实时传输Word格式文档下载.docx(27页珍藏版)》请在冰豆网上搜索。
同样也可以通过定义一个线程类发送文件,如下:
/**发送文件线程*/
classMySendFileThreadextendsThread{
privateStringusername;
privateStringipname;
privateintport;
privatebytebyteBuffer[]=newbyte[1024];
privateOutputStreamoutsocket;
privateByteArrayOutputStreammyoutputstream;
publicMySendFileThread(ByteArrayOutputStreammyoutputstream,Stringusername,Stringipname,intport){
this.myoutputstream=myoutputstream;
this.username=username;
this.ipname=ipname;
this.port=port;
myoutputstream.close();
e.printStackTrace();
}
publicvoidrun(){
try{
//将图像数据通过Socket发送出去
SockettempSocket=newSocket(ipname,port);
outsocket=tempSocket.getOutputStream();
//写入头部数据信息
Stringmsg=.URLEncoder.encode("
PHONEVIDEO|"
+username+"
|"
"
utf-8"
);
byte[]buffer=msg.getBytes();
outsocket.write(buffer);
ByteArrayInputStreaminputstream=newByteArrayInputStream(myoutputstream.toByteArray());
intamount;
while((amount=inputstream.read(byteBuffer))!
=-1){
outsocket.write(byteBuffer,0,amount);
myoutputstream.flush();
myoutputstream.close();
tempSocket.close();
}catch(IOExceptione){
e.printStackTrace();
而获取摄像头当前图像的关键在于onPreviewFrame()重载函数里面,该函数里面有两个参数,第一个参数为byte[],为摄像头当前图像数据,通过YuvImage可以将该数据转换为图片文件,同时还可用对该图片进行压缩和裁剪,将图片进行压缩转换后转换为ByteArrayOutputStream数据,即前面发送文件线程类中所需的文件数据,然后采用线程发送文件,如下代码:
@Override
publicvoidonPreviewFrame(byte[]data,Cameracamera){
//TODOAuto-generatedmethodstub
//如果没有指令传输视频,就先不传
if(!
startSendVideo)
return;
if(tempPreRate<
VideoPreRate){
tempPreRate++;
tempPreRate=0;
try{
if(data!
=null)
{
YuvImageimage=newYuvImage(data,VideoFormatIndex,VideoWidth,VideoHeight,null);
if(image!
ByteArrayOutputStreamoutstream=newByteArrayOutputStream();
//在此设置图片的尺寸和质量
pressToJpeg(newRect(0,0,(int)(VideoWidthRatio*VideoWidth),
(int)(VideoHeightRatio*VideoHeight)),VideoQuality,outstream);
outstream.flush();
//启用线程将图像数据发送出去
Threadth=newMySendFileThread(outstream,pUsername,serverUrl,serverPort);
th.start();
}catch(IOExceptione){
e.printStackTrace();
值得注意的是,在调试中YuvImage可能找不到,在模拟机上无法执行该过程,但是编译后在真机中可以通过。
此外,以上传输文字字符都是采用UTF编码,在服务器端接收时进行解析时需要采用对应的编码进行解析,否则可能会出现错误解析。
Android客户端中关键的部分主要就这些,新建一个Android项目(项目名称为SocketCamera),在main布局中添加一个SurfaceView和两个按钮,如下图所示:
然后在SocketCameraActivity.java中添加代码,具体如下:
packagecom.xzy;
importjava.io.ByteArrayInputStream;
importjava.io.ByteArrayOutputStream;
importjava.io.IOException;
importjava.io.OutputStream;
importjava.io.PrintWriter;
import.Socket;
import.UnknownHostException;
importandroid.app.Activity;
importandroid.app.AlertDialog;
importandroid.content.DialogInterface;
importandroid.content.Intent;
importandroid.content.SharedPreferences;
importandroid.graphics.Rect;
importandroid.graphics.YuvImage;
importandroid.hardware.Camera;
importandroid.hardware.Camera.Size;
importandroid.os.Bundle;
importandroid.preference.PreferenceManager;
importandroid.view.Menu;
importandroid.view.MenuItem;
importandroid.view.SurfaceHolder;
importandroid.view.SurfaceView;
importandroid.view.View;
importandroid.view.WindowManager;
importandroid.view.View.OnClickListener;
importandroid.widget.Button;
publicclassSocketCameraActivityextendsActivityimplementsSurfaceHolder.Callback,
Camera.PreviewCallback{
privateSurfaceViewmSurfaceview=null;
//SurfaceView对象:
(视图组件)视频显示
privateSurfaceHoldermSurfaceHolder=null;
//SurfaceHolder对象:
(抽象接口)SurfaceView支持类
privateCameramCamera=null;
//Camera对象,相机预览
/**服务器地址*/
privateStringpUsername="
XZY"
;
privateStringserverUrl="
192.168.1.100"
/**服务器端口*/
privateintserverPort=8888;
/**视频刷新间隔*/
privateintVideoPreRate=1;
/**当前视频序号*/
privateinttempPreRate=0;
/**视频质量*/
privateintVideoQuality=85;
/**发送视频宽度比例*/
privatefloatVideoWidthRatio=1;
/**发送视频高度比例*/
privatefloatVideoHeightRatio=1;
/**发送视频宽度*/
privateintVideoWidth=320;
/**发送视频高度*/
privateintVideoHeight=240;
/**视频格式索引*/
privateintVideoFormatIndex=0;
/**是否发送视频*/
privatebooleanstartSendVideo=false;
/**是否连接主机*/
privatebooleanconnectedServer=false;
privateButtonmyBtn01,myBtn02;
/**Calledwhentheactivityisfirstcreated.*/
publicvoidonCreate(BundlesavedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.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);
//开始连接主机按钮
myBtn01.setOnClickListener(newOnClickListener(){
publicvoidonClick(Viewv){
//Common.SetGPSConnected(LoginActivity.this,false);
if(connectedServer){//停止连接主机,同时断开传输
startSendVideo=false;
connectedServer=false;
myBtn02.setEnabled(false);
myBtn01.setText("
开始连接"
myBtn02.setText("
开始传输"
//断开连接
Threadth=newMySendCommondThread("
PHONEDISCONNECT|"
+pUsername+"
th.start();
}
else//连接主机
{
//启用线程发送命令PHONECONNECT
PHONECONNECT|"
connectedServer=true;
myBtn02.setEnabled(true);
停止连接"
}});
myBtn02.setEnabled(false);
myBtn02.setOnClickListener(newOnClickListener(){
if(startSendVideo)//停止传输视频
else{//开始传输视频
startSendVideo=true;
停止传输"
publicvoidonStart()//重新启动的时候
{
mSurfaceHolder=mSurfaceview.getHolder();
//绑定SurfaceView,取得SurfaceHolder对象
mSurfaceHolder.addCallback(this);
//SurfaceHolder加入回调接口
mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
//设置显示器类型,setType必须设置
//读取配置文件
SharedPreferencespreParas=PreferenceManager.getDefaultSharedPreferences(SocketCameraActivity.this);
pUsername=preParas.getString("
Username"
"
serverUrl=preParas.getString("
ServerUrl"
192.168.0.100"
StringtempStr=preParas.getString("
ServerPort"
8888"
serverPort=Integer.parseInt(tempStr);
tempStr=preParas.getString("
VideoPreRate"
1"
VideoPreRate=Integer.parseInt(tempStr);
VideoQuality"
85"
VideoQuality=Integer.parseInt(tempStr);
VideoWidthRatio"
100"
VideoWidthRatio=Integer.parseInt(tempStr);
VideoHeightRatio"
VideoHeightRatio=Integer.parseInt(tempStr);
VideoWidthRatio=VideoWidthRatio/100f;
VideoHeightRatio=VideoHeightRatio/100f;
super.onStart();
protectedvoidonResume(){
super.onResume();
InitCamera();
/**初始化摄像头*/
privatevoidInitCamera(){
try{
mCamera=Camera.open();
}catch(Exceptione){
protectedvoidonPause(){
super.onPause();
if(mCamera!
=null){
mCamera.setPreviewCallback(null);
//!
!
这个必须在前,不然退出出错
mCamera.stopPreview();
mCamera.release();
mCamera=null;
}
}catch(Exceptione){
publicvoidsurfaceChanged(SurfaceHolderarg0,intarg1,intarg2,intarg3){
if(mCamera==null){
return;
mCamera.setPreviewCallback(this);
mCamera.setDisplayOrientation(90);
//设置横行录制
//获取摄像头参数
Camera.Parametersparameters=mCamera.getParameters();
Sizesize=parameters.getPreviewSize();
VideoWidth=size.width;
VideoHeight=size.height;
VideoFormatIndex=parameters.getPreviewFormat();
mCamera.startPreview();
publicvoidsurfaceCreated(SurfaceHolderholder){
mCamera.setPreviewDisplay(mSurfaceHolder);
publicvoidsurfaceDestroyed(SurfaceHolderholder){
if(null!
=mCamera){
mCamera.setPreviewCallback(null);
retur