实现的功能就是两个手机在一个局域网内可以互相观看对方的摄像头图像,当然如果都是连接公网那么就能远程互看了,,,,和视频聊天差不多,,不过没有声音,,,,,,,,

源码是在网上找的(具体地址忘了,如有侵犯请告知),亲测能用,,其实一开始想直接用到自己现在做的东西上 ,不过直接加到自己现在的软件上,调试了一下发现,,我想多了,老天总是不让自己那么轻易的.......................

因为自己手头上只有一个手机,所以就自己发给自己了,本想像写其它文章似得详细叙述一番,看了一下表,,感觉还是算了吧,,昨天把程序加到自己的软件上然后修改,测试一直熬到了1点,然后下午上班的时候头疼,困,然后就睡了1个小时.............年轻人不要老熬夜,,对身体不好,

上面的是自己的摄像头预览的,

下面的是通过TCP传输过来的

源码如下

package com.example.realtimevideo;

import java.io.ByteArrayOutputStream;

import com.example.threadConnect.ClientThread;
import com.example.threadConnect.RevImageThread; import android.graphics.Bitmap;
import android.graphics.ImageFormat;
import android.graphics.YuvImage;
import android.hardware.Camera;
import android.hardware.Camera.PreviewCallback;
import android.hardware.Camera.Size;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.app.Activity;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.Menu;
import android.view.SurfaceHolder;
import android.view.Window;
import android.view.WindowManager;
import android.view.SurfaceHolder.Callback;
import android.view.SurfaceView;
import android.widget.ImageView;
import android.widget.RelativeLayout; public class MainVideoActivity extends Activity{
RevImageThread revImageThread;
public static ImageView image;
private static Bitmap bitmap;
private static final int COMPLETED = 0x222; MyHandler handler;
ClientThread clientThread;
ByteArrayOutputStream outstream; SurfaceView surfaceView;
SurfaceHolder sfh;
Camera camera;
boolean isPreview = false; //是否在浏览中
static int screenWidth=300;
static int screenHeight=300; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// 设置全屏
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.activity_main_video);
surfaceView = (SurfaceView)findViewById(R.id.surfaceView);
image=(ImageView)findViewById(R.id.imageView1); handler = new MyHandler();
clientThread = new ClientThread();
new Thread(clientThread).start(); revImageThread = new RevImageThread(handler);
new Thread(revImageThread).start(); DisplayMetrics dm = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(dm);
screenWidth = dm.widthPixels;// 获取屏幕分辨率宽度
screenHeight = dm.heightPixels; image.setLayoutParams(new RelativeLayout.LayoutParams(screenWidth,screenHeight));
//image.setMaxHeight(screenHeight);
//image.setMaxWidth(screenWidth); image.setMaxHeight(screenHeight/2);
sfh = surfaceView.getHolder();
sfh.setFixedSize(screenWidth, screenHeight/2); sfh.addCallback(new Callback(){ @Override
public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2,
int arg3) {
// TODO Auto-generated method stub } @Override
public void surfaceCreated(SurfaceHolder arg0) {
// TODO Auto-generated method stub
initCamera();
} @Override
public void surfaceDestroyed(SurfaceHolder arg0) {
if (camera != null) {
if (isPreview) camera.stopPreview();
camera.release();
camera = null;
} } }); } @Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main_video, menu);
return true;
} @SuppressWarnings("deprecation")
private void initCamera() {
if (!isPreview) {
int k = 0;
if((k=FindBackCamera())!=-1){
camera = Camera.open(k);
}else{
camera = Camera.open();
}
ClientThread.size = camera.getParameters().getPreviewSize();
}
if (camera != null && !isPreview) {
try{
camera.setPreviewDisplay(sfh); // 通过SurfaceView显示取景画面
Camera.Parameters parameters = 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(new PreviewCallback(){
@Override
public void onPreviewFrame(byte[] data, Camera c) {
// TODO Auto-generated method stub
Size size = camera.getParameters().getPreviewSize();
try{
//调用image.compressToJpeg()将YUV格式图像数据data转为jpg格式
YuvImage image = new YuvImage(data, ImageFormat.NV21, size.width, size.height, null);
if(image!=null){
Message msg = clientThread.revHandler.obtainMessage();
msg.what=0x111;
msg.obj=image;
clientThread.revHandler.sendMessage(msg);
}
}catch(Exception ex){
Log.e("Sys","Error:"+ex.getMessage());
}
} });
camera.startPreview(); // 开始预览
camera.autoFocus(null); // 自动对焦
} catch (Exception e) {
e.printStackTrace();
}
isPreview = true;
}
} static class MyHandler extends Handler{
@Override
public void handleMessage(Message msg){
if (msg.what == COMPLETED) {
bitmap = (Bitmap)msg.obj; //image.setPivotX(image.getWidth()/2);
//image.setPivotX(image.getHeight()/2); //image.setImageBitmap(bitmap);
image.setLayoutParams(new RelativeLayout.LayoutParams(screenWidth,screenHeight));
image.setImageBitmap(bitmap);
image.setRotation(90);
super.handleMessage(msg);
}
}
} //调用前置摄像头
private int FindFrontCamera(){
int cameraCount = 0;
Camera.CameraInfo cameraInfo = new Camera.CameraInfo();
cameraCount = Camera.getNumberOfCameras(); // get cameras number for ( int camIdx = 0; camIdx < cameraCount;camIdx++ ) {
Camera.getCameraInfo( camIdx, cameraInfo ); // get camerainfo
if ( cameraInfo.facing ==Camera.CameraInfo.CAMERA_FACING_FRONT ) {
// 代表摄像头的方位,目前有定义值两个分别为CAMERA_FACING_FRONT前置和CAMERA_FACING_BACK后置
return camIdx;
}
}
return -1;
} //调用后置摄像头
private int FindBackCamera(){
int cameraCount = 0;
Camera.CameraInfo cameraInfo = new Camera.CameraInfo();
cameraCount = Camera.getNumberOfCameras(); // get cameras number for ( int camIdx = 0; camIdx < cameraCount;camIdx++ ) {
Camera.getCameraInfo( camIdx, cameraInfo ); // get camerainfo
if ( cameraInfo.facing ==Camera.CameraInfo.CAMERA_FACING_BACK ) {
// 代表摄像头的方位,目前有定义值两个分别为CAMERA_FACING_FRONT前置和CAMERA_FACING_BACK后置
return camIdx;
}
}
return -1;
}
}

package com.example.threadConnect;

import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.Socket; import android.graphics.Rect;
import android.graphics.YuvImage;
import android.hardware.Camera.Size;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.util.Log; public class ClientThread implements Runnable {
private static Socket socket ;
private static ByteArrayOutputStream outputstream;
private static byte byteBuffer[] = new byte[1024];
public static Size size; //接受UI线程消息
public MyHandler revHandler; BufferedReader br= null;
static OutputStream os = null; @Override
public void run() {
Looper.prepare();
//接受UI发来的信息
revHandler = new MyHandler();
Looper.loop();
} public static class MyHandler extends Handler{
@Override
public void handleMessage(Message msg){
if(msg.what==0x111){
try {
socket = new Socket("192.168.3.10",8081);
os = socket.getOutputStream();
YuvImage image = (YuvImage) msg.obj;
if(socket.isOutputShutdown()){
Log.e("output is down","ljq");
}else{
os = socket.getOutputStream();
outputstream = new ByteArrayOutputStream();
image.compressToJpeg(new Rect(0, 0, size.width, size.height), 80, outputstream);
ByteArrayInputStream inputstream = new ByteArrayInputStream(outputstream.toByteArray());
int amount;
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 (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}

package com.example.threadConnect;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket; import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Handler;
import android.os.Message; public class RevImageThread implements Runnable { public Socket s;
public ServerSocket ss; //向UI线程发送消息
private Handler handler; private Bitmap bitmap;
private static final int COMPLETED = 0x222; public RevImageThread(Handler handler){
this.handler = handler;
} public void run()
{
byte [] buffer = new byte[1024];
int len = 0; try {
ss = new ServerSocket(8080);
} catch (IOException e2) {
// TODO Auto-generated catch block
e2.printStackTrace();
} InputStream ins = null;
while(true){ try {
s = ss.accept();
ins = s.getInputStream(); ByteArrayOutputStream outStream = new ByteArrayOutputStream();
while( (len=ins.read(buffer)) != -1){
outStream.write(buffer, 0, len);
}
ins.close(); byte data[] = outStream.toByteArray();
bitmap = BitmapFactory.decodeByteArray(data, 0, data.length); Message msg =handler.obtainMessage();
msg.what = COMPLETED;
msg.obj = bitmap;
handler.sendMessage(msg); outStream.flush();
outStream.close();
if(!s.isClosed()){
s.close();
} } catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//Bitmap bitmap = BitmapFactory.decodeStream(ins); }
} }

布局

<RelativeLayout xmlns: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="fill_parent"
android:layout_height="fill_parent"
android:scaleType="fitCenter"
/>
<ImageView
android:id="@+id/imageView1"
android:layout_width="fill_parent"
android:layout_height="fill_parent" android:src="@drawable/ic_launcher"/>
</RelativeLayout>

权限

对了关于如何使用

这个程序把发送图像和接收图像做在了一块了

其实只有知道TCP通信应该就会用,,不对源程序没提供地址输入框,,,,,,,后期自己加上了,不过现在感觉需要修改,因为源程序是不停的申请不停的释放,,,,,,

未完,,待续,,改好了就把自己完善的代码奉上, 加详细解释,一步一步的写出来..................

Android之网络摄像头的更多相关文章

  1. Android IOS WebRTC 音视频开发总结(八十五)-- 使用WebRTC广播网络摄像头视频(下)

    本文主要介绍WebRTC (我们翻译和整理的,译者:weizhenwei,校验:blacker),最早发表在[编风网] 支持原创,转载必须注明出处,欢迎关注我的微信公众号blacker(微信ID:bl ...

  2. Android IOS WebRTC 音视频开发总结(八十三)-- 使用WebRTC广播网络摄像头视频(上)

    本文主要介绍WebRTC (我们翻译和整理的,译者:weizhenwei,校验:blacker),最早发表在[编风网] 支持原创,转载必须注明出处,欢迎关注我的微信公众号blacker(微信ID:bl ...

  3. 抓住“新代码”的影子 —— 基于GoAhead系列网络摄像头多个漏洞分析

    PDF 版本下载:抓住“新代码”的影子 —— 基于GoAhead系列网络摄像头多个漏洞分析 Author:知道创宇404实验室 Date:2017/03/19 一.漏洞背景 GoAhead作为世界上最 ...

  4. Android okHttp网络请求之Json解析

    前言: 前面两篇文章介绍了基于okHttp的post.get请求,以及文件的上传下载,今天主要介绍一下如何和Json解析一起使用?如何才能提高开发效率? okHttp相关文章地址: Android o ...

  5. Android okHttp网络请求之Get/Post请求

    前言: 之前项目中一直使用的Xutils开源框架,从xutils 2.1.5版本使用到最近的xutils 3.0,使用起来也是蛮方便的,只不过最近想着完善一下app中使用的开源框架,由于Xutils里 ...

  6. Android okHttp网络请求之文件上传下载

    前言: 前面介绍了基于okHttp的get.post基本使用(http://www.cnblogs.com/whoislcj/p/5526431.html),今天来实现一下基于okHttp的文件上传. ...

  7. Android okHttp网络请求之缓存控制Cache-Control

    前言: 前面的学习基本上已经可以完成开发需求了,但是在项目中有时会遇到对请求做个缓存,当没网络的时候优先加载本地缓存,基于这个需求我们来学习一直okHttp的Cache-Control. okHttp ...

  8. Android okHttp网络请求之Retrofit+Okhttp+RxJava组合

    前言: 通过上面的学习,我们不难发现单纯使用okHttp来作为网络库还是多多少少有那么一点点不太方便,而且还需自己来管理接口,对于接口的使用的是哪种请求方式也不能一目了然,出于这个目的接下来学习一下R ...

  9. Android检测网络是否正常代码!

    在Android开发中,如果该应用程序需要连接网络请求,那么最好我们先做一个检测网络是否在线的判断,否则程序容易出现卡死或FC等Bug,应该判断如果手机离线则弹出提示让用户检查网络,如果正常则继续执行 ...

随机推荐

  1. JavaScript高级编程———JSON

    JavaScript高级编程———JSON < script > /*JSON的语法可以表达一下三种类型的值 简单值:使用与javas相同的语法,可以在JSON中表达字符串.数值.布尔值和 ...

  2. JavaSE——序列化和反序列化

    序列化: 序列化对应写的操作.(读与写都是站在应用的角度上) 序列化就是一种用来处理对象流的机制,所谓对象流也就是将对象的内容进行流化.可以对流化后的对象进行读写操作,也可将流化后的对象传输于网络之间 ...

  3. Windows Win7建立wifi热点,手机共享WIFI上网

    Win7建立wifi热点,手机共享wifi上网 by:授客 QQ:1033553122 1.以管理员身份运行命令提示符:快捷键win+R→输入cmd→回车 2.启用并设定虚拟WiFi网卡:运行命令:n ...

  4. Linux 配置iso系统盘为本地yum源

    Linux配置iso系统盘为本地yum源 by:授客 QQ:1033553122   1.目的 安装软件时,经常会遇到包或类库的依赖性问题,为此,我们可以通过yum命令安装软件,尽量避免出现繁琐的软件 ...

  5. JAVA:函数的定义、使用

      本文内容: 什么是函数 函数的定义格式 函数的重载(overload): 函数的调用使用注意 关于形式参数的使用 首发时间:2017-06-23 修改时间:2018-03-21:修改了布局,修改了 ...

  6. 白盒测试实践-DAY1

    时间:2017.12.11 地点:软件学院 成员:张玉.周静.张双双 会议内容:讨论题目要求,分配任务 针对第一阶段的任务进行部署,共同学习白盒测试方法,根据自己选择的系统--餐厅网站,针对其中的管理 ...

  7. Python图像识别(聚类)

    # -*- coding: utf-8 -*- """ Created on Fri Sep 21 15:37:26 2018 @author: zhen "& ...

  8. .NET、ADO.NET、ASP.NET名称解析及.NET平台架构组成

    转https://blog.csdn.net/xiaouncle/article/details/53265256 名词解释 1.Winform:Windows应用程序.桌面应用程序.C/S应用程序  ...

  9. MySQl新特性 GTID

    GTID简介 概念 全局事务标识符(GTID)是创建的唯一标识符,并与在源(主)服务器上提交的每个事务相关联.此标识符不但是唯一的,而且在给定复制设置中的所有服务器上都是唯一的.所有交易和所有GTID ...

  10. MySQL crash-safe replication(3): MySQL的Crash Safe和Binlog的关系

    2016-12-23 17:29 宋利兵 作者:宋利兵 来源:MySQL代码研究(mysqlcode) 0.导读 本文重点介绍了InnoDB的crash safe和binlog之间的关系,以及2阶段提 ...