您的位置:首页 > 移动开发 > Android开发

android使用socket实现实时视频

2015-08-14 11:19 381 查看
该视频实现是基于TCP/IP协议的Socket(客户端)和ServerSocket(服务端)类,发送视频也就是不间断的发送图片。具体如下:

PC服务端:socketService类开启服务及监听,线程类TheadServer处理socket连接,并调用另外一个线程类ThreadClient发送图片到到另外一台手机上

视频发送端:MainVideoActivity为显示界面,子线程ClientThread处理图片并发送到服务器

视频接受端:MainActivity为显示界面,子线程RevImageThread为接受服务端发送过来的图片

PC端socketService类:


packagecom.socket;
importjava.io.IOException;
importjava.net.ServerSocket;
importjava.net.Socket;


publicclasssocketService{


/**
*@paramargs
*@throwsIOException
*/
publicstaticvoidmain(String[]args)throwsIOException{


ServerSocketss=newServerSocket(3000);
System.out.println("begin");

while(true){


newThread(newTheadServer(ss)).start();
}
}
}



TheadServer类:

packagecom.socket;

importjava.awt.Image;
importjava.awt.image.BufferedImage;
importjava.io.IOException;
importjava.io.InputStream;
importjava.io.InputStreamReader;
importjava.io.OutputStream;
importjava.net.ServerSocket;
importjava.net.Socket;

importjavax.imageio.ImageIO;

publicclassTheadServerimplementsRunnable{
privateSockets=null;
privateBufferedImagebufferedImage;
publicInputStreamins;
publicTheadServer(ServerSocketss)throwsIOException{
System.out.println("startthread");
this.s=ss.accept();
}

@Override
publicvoidrun(){
try{
ins=s.getInputStream();
bufferedImage=ImageIO.read(ins);
ins.close();
ThreadClienttc=newThreadClient(bufferedImage);
newThread(tc).start();

}catch(IOExceptione){
//TODOAuto-generatedcatchblock
e.printStackTrace();

}finally{
try{
if(!s.isClosed())
s.close();
}catch(IOExceptione){
//TODOAuto-generatedcatchblock
e.printStackTrace();
}
}
}
}


ThreadClient类:

packagecom.socket;

importjava.awt.Image;
importjava.awt.image.BufferedImage;
importjava.awt.image.RenderedImage;
importjava.io.ByteArrayOutputStream;
importjava.io.IOException;
importjava.io.ObjectOutputStream;
importjava.io.OutputStream;
importjava.io.Serializable;
importjava.net.InetSocketAddress;
importjava.net.Socket;

importjavax.imageio.ImageIO;

publicclassThreadClientimplementsRunnable,Serializable{
privateBufferedImagebufferedImage;
publicThreadClient(BufferedImageimage){
this.bufferedImage=image;

}

@Override
publicvoidrun(){
//TODOAuto-generatedmethodstub
try{
Sockets=newSocket();
//接受视频端IP和端口
s.connect(newInetSocketAddress("10.0.56.234",40000),2000);
if(s.isConnected()&&!s.isClosed()){
System.out.println("Client:"+s.getRemoteSocketAddress().toString());
OutputStreamoos=s.getOutputStream();
ImageIO.write(bufferedImage,"JPG",oos);
oos.write("\n".getBytes());
oos.flush();
oos.close();
s.close();
}

}catch(IOExceptione){
//TODOAuto-generatedcatchblock
e.printStackTrace();
}
}

}


视频发送端:

MainVideoActivity类

packagecom.example.realtimevideo;

importjava.io.ByteArrayOutputStream;

importcom.example.threadConnect.ClientThread;

importandroid.graphics.ImageFormat;
importandroid.graphics.Rect;
importandroid.graphics.YuvImage;
importandroid.hardware.Camera;
importandroid.hardware.Camera.PreviewCallback;
importandroid.hardware.Camera.Size;
importandroid.os.Bundle;
importandroid.os.Handler;
importandroid.os.Message;
importandroid.app.Activity;
importandroid.util.DisplayMetrics;
importandroid.util.Log;
importandroid.view.Menu;
importandroid.view.SurfaceHolder;
importandroid.view.View;
importandroid.view.View.OnClickListener;
importandroid.view.Window;
importandroid.view.WindowManager;
importandroid.view.SurfaceHolder.Callback;
importandroid.view.SurfaceView;
importandroid.widget.Button;

publicclassMainVideoActivityextendsActivity{
MyHandlerhandler;
ClientThreadclientThread;
ByteArrayOutputStreamoutstream;

Buttonstart;
Buttonstop;
SurfaceViewsurfaceView;
SurfaceHoldersfh;
Cameracamera;
booleanisPreview=false;//是否在浏览中
intscreenWidth=300,screenHeight=300;

@Override
protectedvoidonCreate(BundlesavedInstanceState){
super.onCreate(savedInstanceState);
//设置全屏
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.activity_main_video);

handler=newMyHandler();
clientThread=newClientThread(handler);
newThread(clientThread).start();

DisplayMetricsdm=newDisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(dm);
screenWidth=dm.widthPixels;//获取屏幕分辨率宽度
screenHeight=dm.heightPixels;

start=(Button)findViewById(R.id.start);
stop=(Button)findViewById(R.id.stop);
surfaceView=(SurfaceView)findViewById(R.id.surfaceView);
sfh=surfaceView.getHolder();
sfh.setFixedSize(screenWidth,screenHeight/4*3);

sfh.addCallback(newCallback(){

@Override
publicvoidsurfaceChanged(SurfaceHolderarg0,intarg1,intarg2,
intarg3){
//TODOAuto-generatedmethodstub

}

@Override
publicvoidsurfaceCreated(SurfaceHolderarg0){
//TODOAuto-generatedmethodstub
initCamera();
}

@Override
publicvoidsurfaceDestroyed(SurfaceHolderarg0){
if(camera!=null){
if(isPreview)
camera.stopPreview();
camera.release();
camera=null;
}

}

});

//开启连接服务
start.setOnClickListener(newOnClickListener(){

@Override
publicvoidonClick(Viewarg0){

start.setEnabled(false);
}

});

}

@Override
publicbooleanonCreateOptionsMenu(Menumenu){
//Inflatethemenu;thisaddsitemstotheactionbarifitispresent.
getMenuInflater().inflate(R.menu.main_video,menu);
returntrue;
}

@SuppressWarnings("deprecation")
privatevoidinitCamera(){
if(!isPreview){
camera=Camera.open();
ClientThread.size=camera.getParameters().getPreviewSize();
}
if(camera!=null&&!isPreview){
try{
camera.setPreviewDisplay(sfh);//通过SurfaceView显示取景画面
Camera.Parametersparameters=camera.getParameters();
parameters.setPreviewSize(screenWidth,screenHeight/4*3);
/*每秒从摄像头捕获5帧画面,*/
parameters.setPreviewFrameRate(5);
parameters.setPictureFormat(ImageFormat.NV21);//设置图片格式
parameters.setPictureSize(screenWidth,screenHeight/4*3);//设置照片的大小
camera.setDisplayOrientation(90);
camera.setPreviewCallback(newPreviewCallback(){

@Override
publicvoidonPreviewFrame(byte[]data,Camerac){
//TODOAuto-generatedmethodstub
Sizesize=camera.getParameters().getPreviewSize();
try{
//调用image.compressToJpeg()将YUV格式图像数据data转为jpg格式
YuvImageimage=newYuvImage(data,ImageFormat.NV21,size.width,size.height,null);
if(image!=null){
Messagemsg=clientThread.revHandler.obtainMessage();
msg.what=0x111;
msg.obj=image;
clientThread.revHandler.sendMessage(msg);

/*outstream=newByteArrayOutputStream();
image.compressToJpeg(newRect(0,0,size.width,size.height),80,outstream);
outstream.flush();
newThread(clientThread).start();*/
}
}catch(Exceptionex){
Log.e("Sys","Error:"+ex.getMessage());
}
}

});
camera.startPreview();//开始预览
camera.autoFocus(null);//自动对焦
}catch(Exceptione){
e.printStackTrace();
}
isPreview=true;
}
}

staticclassMyHandlerextendsHandler{
@Override
publicvoidhandleMessage(Messagemsg){
if(msg.what==0x222){
//返回信息显示代码
}
}
}
}


ClientThread类:

packagecom.example.threadConnect;

importjava.io.BufferedReader;
importjava.io.ByteArrayInputStream;
importjava.io.ByteArrayOutputStream;
importjava.io.IOException;
importjava.io.InputStreamReader;
importjava.io.OutputStream;
importjava.io.UnsupportedEncodingException;
importjava.net.Socket;
importjava.net.SocketTimeoutException;
importjava.net.UnknownHostException;

importandroid.graphics.Rect;
importandroid.graphics.YuvImage;
importandroid.hardware.Camera.Size;
importandroid.os.Handler;
importandroid.os.Looper;
importandroid.os.Message;
importandroid.util.Log;

publicclassClientThreadimplementsRunnable{
privatestaticSocketsocket;
privatestaticByteArrayOutputStreamoutputstream;
privatestaticbytebyteBuffer[]=newbyte[1024];
publicstaticSizesize;

//向UI线程发送消息
privateHandlerhandler;

//接受UI线程消息
publicMyHandlerrevHandler;

BufferedReaderbr=null;
staticOutputStreamos=null;

publicClientThread(Handlerhandler){
this.handler=handler;

}

@Override
publicvoidrun(){

Looper.prepare();
//接受UI发来的信息
revHandler=newMyHandler();
Looper.loop();

}

publicstaticclassMyHandlerextendsHandler{
@Override
publicvoidhandleMessage(Messagemsg){
if(msg.what==0x111){
try{
socket=newSocket("10.0.56.232",3000);
os=socket.getOutputStream();
YuvImageimage=(YuvImage)msg.obj;
if(socket.isOutputShutdown()){
socket.getKeepAlive();

}else{
os=socket.getOutputStream();
outputstream=newByteArrayOutputStream();
image.compressToJpeg(newRect(0,0,size.width,size.height),80,outputstream);
ByteArrayInputStreaminputstream=newByteArrayInputStream(outputstream.toByteArray());
intamount;
while((amount=inputstream.read(byteBuffer))!=-1){
os.write(byteBuffer,0,amount);
}
os.write("\n".getBytes());
outputstream.flush();
outputstream.close();
os.flush();
os.close();
socket.close();
}
}catch(UnsupportedEncodingExceptione){
//TODOAuto-generatedcatchblock
e.printStackTrace();
}catch(IOExceptione){
//TODOAuto-generatedcatchblock
e.printStackTrace();
}
}
}
}
}


布局:

<LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:orientation="vertical"
tools:context=".MainVideoActivity">

<SurfaceView
android:id="@+id/surfaceView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:scaleType="fitCenter"
/>
<Button
android:id="@+id/start"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/start"/>
<Button
android:id="@+id/stop"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/stop"/>
</LinearLayout>


视频接受端:

MainActivity:

packagecom.example.socketphone;

importandroid.os.Bundle;
importandroid.os.Handler;
importandroid.os.Looper;
importandroid.os.Message;
importandroid.app.Activity;
importandroid.graphics.Bitmap;
importandroid.graphics.BitmapFactory;
importandroid.util.Log;
importandroid.view.Menu;
importandroid.widget.ImageView;

importjava.io.ByteArrayOutputStream;
importjava.io.IOException;
importjava.io.InputStream;
importjava.io.ObjectInputStream;
importjava.net.Socket;
importjava.net.ServerSocket;

importcom.example.Thread.RevImageThread;

publicclassMainActivityextendsActivity{
RevImageThreadrevImageThread;
publicstaticImageViewimage;
privatestaticBitmapbitmap;
privatestaticfinalintCOMPLETED=0x111;
privateMyHandlerhandler;

protectedvoidonCreate(BundlesavedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
image=(ImageView)findViewById(R.id.imageView1);
handler=newMyHandler();
revImageThread=newRevImageThread(handler);
newThread(revImageThread).start();

}

staticclassMyHandlerextendsHandler{
@Override
publicvoidhandleMessage(Messagemsg){
if(msg.what==COMPLETED){
bitmap=(Bitmap)msg.obj;
image.setImageBitmap(bitmap);
super.handleMessage(msg);
}
}
}

publicbooleanonCreateOptionsMenu(Menumenu){
//Inflatethemenu;thisaddsitemstotheactionbarifitispresent.
getMenuInflater().inflate(R.menu.main,menu);
returntrue;
}
}


RevImageThread类:

packagecom.example.Thread;

importjava.io.ByteArrayOutputStream;
importjava.io.IOException;
importjava.io.InputStream;
importjava.net.ServerSocket;
importjava.net.Socket;

importandroid.graphics.Bitmap;
importandroid.graphics.BitmapFactory;
importandroid.os.Handler;
importandroid.os.Looper;
importandroid.os.Message;
importandroid.util.Log;

publicclassRevImageThreadimplementsRunnable{

publicSockets;
publicServerSocketss;

//向UI线程发送消息
privateHandlerhandler;

privateBitmapbitmap;
privatestaticfinalintCOMPLETED=0x111;

publicRevImageThread(Handlerhandler){
this.handler=handler;
}

publicvoidrun()
{
byte[]buffer=newbyte[1024];
intlen=0;

try{
ss=newServerSocket(40000);
}catch(IOExceptione2){
//TODOAuto-generatedcatchblock
e2.printStackTrace();
}

InputStreamins=null;
while(true){

try{
s=ss.accept();
Log.e("strat","ljq");
ins=s.getInputStream();

ByteArrayOutputStreamoutStream=newByteArrayOutputStream();
while((len=ins.read(buffer))!=-1){
outStream.write(buffer,0,len);
}
ins.close();bytedata[]=outStream.toByteArray();
bitmap=BitmapFactory.decodeByteArray(data,0,data.length);

Messagemsg=handler.obtainMessage();
msg.what=COMPLETED;
msg.obj=bitmap;
handler.sendMessage(msg);

outStream.flush();
outStream.close();
if(!s.isClosed()){
s.close();
}

}catch(IOExceptione){
//TODOAuto-generatedcatchblock
e.printStackTrace();
}
//Bitmapbitmap=BitmapFactory.decodeStream(ins);

}
}

}


布局:

<RelativeLayoutxmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context=".MainActivity">

<ImageView
android:id="@+id/imageView1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:src="@drawable/ic_launcher"/>

</RelativeLayout>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: