一、具体流程:
1.通过客户端socket请求,服务端接受到请求后,获取socket的输出流对象outs。
2.服务端通过Camera的setPreviewCallback方法回调采集摄像头视频数据,将一张张图片数据数据压缩,发送到客户端,因为是图片,需要在图片开头加个标记,然后指定数据长度发送。
3.客户端接收数据,根据数据开头标记,以及数据的长度,接收数据,按一张张图片的形式,采用handle更新imageview。
思路很简单,主要代码:
服务端代码:
<div>public class MainActivity extends Activity {TextView tv;SurfaceView surfv;SurfaceHolder surfaceHolder;int screenWidth=300, screenHeight=300;public Handler mHandler = new Handler(){public void handleMessage(android.os.Message msg) {switch (msg.what) {case CamConstant.INIT_CAMERA:/*if(CamConstant.hadInit){return;}</div><div>    Camera camera = CameraUtil.initCamera(surfaceHolder);if( null != camera){CamConstant.hadInit = true;}*/break;case CamConstant.RECYCLE_CAMERA:CameraUtil.recycleCamera();CamConstant.hadInit = false;break;default://tv.setText((CharSequence) msg.obj);tv.append((CharSequence) msg.obj+"\n");break;}};};@Overrideprotected void onCreate(Bundle savedInstanceState) {setContentView(R.layout.activity_main);super.onCreate(savedInstanceState);MainApplication.mHandler = this.mHandler;tv = (TextView) findViewById(R.id.textView);surfv = (SurfaceView) findViewById(R.id.surview);DisplayMetrics dm = new DisplayMetrics();getWindowManager().getDefaultDisplay().getMetrics(dm);screenWidth = dm.widthPixels;// 获取屏幕分辨率宽度screenHeight = dm.heightPixels;surfaceHolder = surfv.getHolder();surfaceHolder.setFixedSize(screenWidth, screenHeight/4*2);surfaceHolder.addCallback(new Callback() {@Overridepublic void surfaceDestroyed(SurfaceHolder holder) {// TODO Auto-generated method stub}@Overridepublic void surfaceCreated(SurfaceHolder holder) {// TODO Auto-generated method stubCameraUtil.initCamera(surfaceHolder);}@Overridepublic void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {// TODO Auto-generated method stub}});//tv.setMovementMethod(ScrollingMovementMethod.getInstance());startService();};public void startService(){Intent intent = new Intent(MainActivity.this, CamThreadService.class);startService(intent);}@Overrideprotected void onDestroy() {// TODO Auto-generated method stubCameraUtil.recycleCamera();CamConstant.hadInit = false;if(ServiceUtil.isServiceRunning(this, "CamService")){stopService(new Intent(this, CamService.class));}super.onDestroy();}}</div>


public class CamThreadService extends Service {Socket mClintSocket;ServerSocket serverSocket;@Overridepublic IBinder onBind(Intent intent) {return null;}@Overridepublic void onCreate() {L.e("启动11111");// TODO Auto-generated method stubnew Thread(new Runnable() {@Overridepublic void run() {// TODO Auto-generated method stubtry {L.e("accept000");sendMSG("accept1111"); serverSocket = new ServerSocket(CamConstant.Camera_Port);while(true){L.e("accept0001111");L.e("accept11111");sendMSG("accept222");mClintSocket = serverSocket.accept();L.e("accept22222");L.e("accept3333");new Thread(){public void run() {if(mClintSocket != null){sendMSG("accept3333");//初始化//MainApplication.mHandler.sendEmptyMessage(CamConstant.INIT_CAMERA);L.e("accept4444");boolean flag = true;while(flag){if(CameraUtil.mCamera != null){try {CameraUtil.mCamera.setPreviewCallback(new StreamIt(mClintSocket));} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}flag = false;mClintSocket = null;}}}};}.start();}} catch (IOException e) {// TODO Auto-generated catch blockL.e("之行报错 停止");e.printStackTrace();}}}).start();super.onCreate();}/*** 视频流数据相关回调*/private class StreamIt implements PreviewCallback {private OutputStream out;private InputStream in;private int  times = 0;public  StreamIt(Socket s) throws IOException {// TODO Auto-generated constructor stubthis.out = s.getOutputStream();this.in = s.getInputStream();sendMSG("压缩后的数据11");int[] textures = new int[1];L.e("压缩后的数据1");}@Overridepublic void onPreviewFrame(byte[] data, Camera camera) { // TODO Auto-generated method stubSize size = camera.getParameters().getPreviewSize();try {L.e("压缩后的数据1.5");if(times == 0){YuvImage image = new YuvImage(data, ImageFormat.NV21, size.width, size.height, null);if(image != null){//这是源数据ByteArrayOutputStream outputStream = new ByteArrayOutputStream();image.compressToJpeg(new Rect(0, 0, size.width, size.height), 100, outputStream);byte[] srcData = outputStream.toByteArray();int len = srcData.length;Bitmap src = BitmapFactory.decodeByteArray(srcData, 0, len);//压缩后的数据byte[] outdata = transImage(src, 640, 480);L.e("压缩后的数据2");sendMSG("压缩后的数据22");int datalen = outdata.length;out.write((byte) 0xA0);out.write(intTOBytes(datalen));out.write(outdata, 0, datalen);if(!src.isRecycled()){src.recycle();}}}} catch (Exception e) {// TODO: handle exceptione.printStackTrace();}}/*** 数据转换,将bitmap转换为byte*/private byte[] transImage(Bitmap bitmap, int width, int height){try{int bitmapWidth = bitmap.getWidth();int bitmapHeight = bitmap.getHeight();//缩放图片的尺寸float scaleWidth = (float) width/bitmapWidth;float scaleHeight = (float) height/bitmapHeight;Matrix matrix = new Matrix();matrix.postScale(scaleWidth, scaleHeight);//产生缩放后的Bitmap对象Bitmap resizeBitemp = Bitmap.createBitmap(bitmap, 0, 0, bitmapWidth, bitmapHeight, matrix, false);ByteArrayOutputStream outputStream = new ByteArrayOutputStream();resizeBitemp.compress(CompressFormat.JPEG, 85, outputStream);byte[] byteArray = outputStream.toByteArray();outputStream.close();if(!bitmap.isRecycled()){bitmap.recycle();}if(!resizeBitemp.isRecycled()){resizeBitemp.recycle();}return byteArray;}catch(Exception ex){ex.printStackTrace();MainApplication.mHandler.sendEmptyMessage(CamConstant.RECYCLE_CAMERA);}return null;}/*** 将int 数值转换为4个字节*/private byte[] intTOBytes(int value){Log.e("cam",value+"d");byte[] src = new byte[4];src[3] = (byte) ((value >> 24) & 0xFF);src[2] = (byte)((value >> 16) & 0xFF);src[1] = (byte)((value >> 8) & 0xFF);src[0] = (byte)(value & 0xFF);return src;}}@Overridepublic void onDestroy() {// TODO Auto-generated method stubtry {if(mClintSocket !=null){mClintSocket.close();}} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}MainApplication.mHandler.sendEmptyMessage(CamConstant.RECYCLE_CAMERA);super.onDestroy();}public void sendMSG(String text){Message msg = new Message();msg.what = 908;msg.obj = text;MainApplication.mHandler.sendMessage(msg);}
}
</pre>
客户端代码:

public class MainActivity extends Activity {RevImageThread revImageThread;public static ImageView image;private static TextView textView1;private static Bitmap bitmap;private static final int COMPLETED = 0x111;private MyHandler handler;protected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);image=(ImageView)findViewById(R.id.imageView1);textView1 = (TextView) findViewById(R.id.textView1);textView1.setMovementMethod(ScrollingMovementMethod.getInstance());handler = new MyHandler();revImageThread = new RevImageThread(handler);new Thread(revImageThread).start();}static class MyHandler extends Handler{@Overridepublic void handleMessage(Message msg){if(msg.obj != null){textView1.append(msg.obj.toString()+"\n");}if (msg.what == COMPLETED) {bitmap = (Bitmap)msg.obj;image.setImageBitmap(bitmap); super.handleMessage(msg);}  }}public boolean onCreateOptionsMenu(Menu menu) {// Inflate the menu; this adds items to the action bar if it is present.getMenuInflater().inflate(R.menu.main, menu);return true;}
}

public class RevImageThread implements Runnable {public Socket s;public ServerSocket ss;//向UI线程发送消息private Handler handler;private Bitmap bitmap;private static final int COMPLETED = 0x111;public RevImageThread(Handler handler){this.handler = handler;}public void run(){    try {ss = new ServerSocket(ScoketIPandPort.SOCKTPORT);} catch (IOException e2) {// TODO Auto-generated catch blocke2.printStackTrace();}while(true){try {s = ss.accept();Log.e("strat","ljq");new Thread(){public void run() {try {byte [] buffer = new byte[1024];InputStream ins = null;ins = s.getInputStream();Log.v("socket", "socketcc1111");if(s != null){Log.v("socket", "socketcc2222");while(true){int len = 0;int i = 0;int j = 0;boolean flag = true;/*while(flag){i += ins.read();Log.e("socket", ":"+i + " : " + j++);}*/if(ins.read() == 0xA0){byte[] src = new byte[4];len = ins.read(src);Log.v("sck", "src3:"+src[3]);Log.v("sck", "src2:"+src[2]);Log.v("sck", "src1:"+src[1]);Log.v("sck", "src0:"+src[0]);Log.v("sck", "src:"+src);Log.v("socket", "socketcc55551:"+len);Log.v("socket", "socketcc55552:"+src);len = bytesToInt(src, 0);Log.v("socket", "socketcc55553:"+src);Log.v("socket", "socketcc55554:"+len);//len = 4000000;byte[] srcData = new byte[len];sendMSG(len+":len");int readc = 0;ins.read(srcData, readc, len);Log.v("socket", "srcData0:"+srcData[0]);sendMSG("srcData0:"+srcData[0]);Log.v("socket", "srcData0:"+srcData[1]);Log.v("socket", "srcData0:"+srcData[2]);Log.v("socket", "srcData0:"+srcData[3]);Log.v("socket", "srcData0:"+srcData[4]);Log.v("socket", "srcData0:"+srcData[5]);Log.v("socket", "srcData0:"+srcData[6]);Log.v("socket", "srcData0:"+srcData[7]);Log.v("socket", "srcData0:"+srcData[len-1]);sendMSG(srcData[len-1]+"L");bitmap = BitmapFactory.decodeByteArray(srcData, 0, len);Message msg =handler.obtainMessage();msg.what = COMPLETED;msg.obj = bitmap;handler.removeMessages(COMPLETED);handler.sendMessage(msg);}//Message msg = new Message();/* 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); */}}  } catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();sendMSG(e.toString()+"bao cuo " +e.getMessage());}};}.start();} catch (IOException e1) {// TODO Auto-generated catch blocke1.printStackTrace();}/* if(!s.isClosed()){s.close();}*///Bitmap bitmap = BitmapFactory.decodeStream(ins);}}public int bytesToInt(byte[] src, int offset){int value;value = (int)((src[offset] & 0xFF))| ((src[offset+1] & 0xFF)<<8)| ((src[offset+2] & 0xFF)<<16)| ((src[offset+3] & 0xFF)<<24);return value;}public int bytesToInt2(byte[] src, int offset){int value;value = (int)((src[offset] & 0xFF<<24)| ((src[offset+1] & 0xFF)<<16)| ((src[offset+2] & 0xFF)<<8)| (src[offset+3] & 0xFF));return value;}/*  public static int bytesToInt2(byte[] src, int offset) {  int value;    value = (int) ( ((src[offset] & 0xFF)<<24)  |((src[offset+1] & 0xFF)<<16)  |((src[offset+2] & 0xFF)<<8)  |(src[offset+3] & 0xFF));  return value;  } */public  void sendMSG(String text){Message msg = new Message();msg.what = 908;msg.obj = text;handler.sendMessage(msg);}
}

该代码也只做参考作用,代码中有漏洞,需要理解代码之后才能解决


DEMO源码

摄像头MediaCodec 编解码

MediaCodec编解码手机投屏功能的实现

android 手机采集摄像头视频 socket 视频传输 实时传播相关推荐

  1. Android 手机采集摄像头视频 socket 视频传输实时传播

    这里搜集了两种实现Android 手机采集摄像头视频 socket 视频传输实时传播的方法,两种都可以使用. 第一种如下: 1.通过客户端socket请求,服务端接受到请求后,获取socket的输出流 ...

  2. android 手机支持什么格式的视频格式,手机高清小普及:手机支持那些视频格式?...

    背景 虽然在2010年众多的手机厂商都推出了他们的高清手机,可是由于手机的硬件以及操作系统的限制,因此并不是所有的高清格式都能够在目前市面上那些支持高清播放的手机中播放.那么如果大家想要在手机上欣赏高 ...

  3. android蓝牙 相机,如何使用摄像头构建蓝牙控制的汽车,以及如何将Android手机用作摄像头...

    了解如何使用摄像头构建蓝牙控制的汽车,以及如何将Android手机用作摄像头. 硬件组件: · Arduino UNO×1个 · 双H桥电机驱动器L298×1个 · HC-05蓝牙模块×1个 · 9V ...

  4. android 蓝牙传输图片吗,如何使用蓝牙将Android手机中的照片和视频副本发送到树莓派...

    步骤1:将Raspberry Pi放入蓝牙设备 完成以下步骤我以前的版本将Raspberry Pi转换为可指导完成此步骤的Bluetooth设备. 步骤2:使Raspberry Pi设备成为Bluet ...

  5. 在Ubuntu虚拟机使用ffmpeg采集摄像头的yuv视频数据

    在Ubuntu虚拟机使用ffmpeg采集摄像头的yuv数据 使用命令从视频提取出yuv数据 提取yuv视频数据 单独提取视频的y分量或u.v分量 通过摄像头获取yuv数据 使用命令从视频提取出yuv数 ...

  6. 基于FFMPEG采集摄像头图像编码MP4视频+时间水印

    1.硬件平台 操作系统:Ubuntu18.04 ffmpeg版本:ffmpeg4.2.5 摄像头:电脑自带或USB免驱摄像头 水印处理:avfilter 图像渲染:SDL库   摄像头图像采集+MP4 ...

  7. android手机采集,Android手机直播之采集技术分析

    近两年来直播行业越来越火,图玩智能科技为企业提供直播平台二次开发服务以及各类app的开发,欢迎随时咨询www.toivan.com. 作为Android手机直播的研发,本着技术分享的精神,现在写一系列 ...

  8. android音频采集时延,有关音视频采样率帧率以及 Duration 的那些事

    ---------------------------------------------------------------------------------------------------- ...

  9. android实时传输视频Socket

    android实时传输视频Socket https://download.csdn.net/download/u012560682/7780979?spm=1001.2101.3001.5697 An ...

最新文章

  1. xen 虚拟机挂了,宿主机假死的问题追终,全思路
  2. python装饰器副作用_对Python 装饰器的理解心得
  3. springboot工程的热部署
  4. Netty的ChannelFuture和ChannelPromise
  5. phpcms v9 打开网站特别慢 增加数据库缓存方法
  6. Helm 3 完整教程(十八):Helm 流控制结构(2)with 语句
  7. Ruby on Rails 目录结构
  8. Ubuntu 上安装 Node.js
  9. maya前台渲染_maya前台渲染MEL
  10. 深入浅出SCSI子系统(八)SCSI错误恢复
  11. Android的第一行代码
  12. 微信发红包功能的测试用例
  13. Hadoop专业解决方案-第5章 开发可靠的MapReduce应用
  14. Kylin使用Spark构建Cube
  15. netbeans11安装教程_Netbeans使用教程
  16. 苹果4S恢复模式 一直正在等待iphone解决办法
  17. AutoLeaders控制组——51单片机学习笔记(LED点阵屏、DS1302时钟芯片)
  18. 用Interl 5100AGN 无线网卡破解无线网络WEP密码
  19. Python实战项目2——自动获取酷狗音乐工具
  20. 克里斯蒂安贝尔_马特达蒙和克里斯蒂安贝尔 出演福特vs法拉利的传记片

热门文章

  1. 英语中的动词(基础篇)
  2. 云存储——搜狐网络U盘
  3. php 求总页数,WordPress单篇文章分页,获取总页数代码
  4. 微信“小绿书” PK 小红书,胜率有多大?
  5. 2021年8月12日-------Java从基础到项目教程,Java全栈学习路线,帮你省去培训机构的2万块钱。
  6. 表情捕捉的指标/图像的无参考质量评价
  7. 微信小程序-点击按钮,图片重新加载
  8. 理解LSTM网络(翻译)
  9. Java的基本概念(3) 判断和循环
  10. 云计算要用5G技术,那5G是什么?