Android如何实现边采集边上传

最近看了Sipdroid和ZXing两个开源代码,对于如何在Andrpid平台上实现边采集边上传的功能有了新的见解,同时也决定重新弄一下以前做的广州亚运排传的项目.

先给大家说下软件的功能吧.

拿出android手机然后采集实时的图片数据,并对这些采集的图片数据进行H264编码,然后根据协议上传到公司的服务器上。

那么现在大家分析下,如果要实现这些功能,有哪些技术瓶颈:

1.Camera参数设置,设置不正确,无法看到视频,而且最主要的是有的时候你用的设置在公司的测试机上运行正常在其他手机上就看不到视频了。

2.如何获取采集的实时图片数据

3.摄像头打开后大家发现没图片是倒置的,原因何在,如何解决倒置的问题呢?

4.H264压缩编码

5.H264编码后的图片显示为灰白色的,为什么呢?

请看我下面的代码,我将为大家详细的解释上面的情况出现的理由和解决方案:

  1. package com.camera.CameraPreview;  
  2.   
  3. import java.io.IOException;  
  4.   
  5. import android.app.Activity;  
  6. import android.content.pm.ActivityInfo;  
  7. import android.hardware.Camera;  
  8. import android.hardware.Camera.PreviewCallback;  
  9. import android.os.Bundle;  
  10. import android.view.SurfaceHolder;  
  11. import android.view.Window;  
  12. import android.view.SurfaceHolder.Callback;  
  13. import android.view.SurfaceView;  
  14.   
  15. public class PreviewActivity extends Activity implements Callback, PreviewCallback {  
  16.   
  17.   
  18. private SurfaceView mSurface ;  
  19.   
  20. private SurfaceHolder mHolder;  
  21.   
  22.   
  23. /** Called when the activity is first created. */  
  24. @Override  
  25. public void onCreate(Bundle savedInstanceState) {  
  26. super.onCreate(savedInstanceState);  
  27.   
  28. requestWindowFeature(Window.FEATURE_NO_TITLE);   
  29. //and set the preview to landscape mode.   
  30. setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);   
  31.   
  32. setContentView(R.layout.main);  
  33.   
  34. mSurface = (SurfaceView)this.findViewById(R.id.SurfacePrewView);  
  35. mHolder = mSurface.getHolder();  
  36. mHolder.addCallback(this);  
  37.   
  38. mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);//该代码放在addCallback前还是addCallback后对代码Camera有没有影响   
  39. }  
  40.   
  41.   
  42. @Override  
  43. public void surfaceChanged(SurfaceHolder holder, int format, int width,  
  44. int height) {  
  45. Camera.Parameters parame = mCamera.getParameters();  
  46. parame.setPreviewSize(320,480);  
  47.   
  48. mCamera.startPreview();  
  49. }  
  50.   
  51.   
  52.   
  53. private Camera mCamera ;  
  54.   
  55. @Override  
  56. public void surfaceCreated(SurfaceHolder holder) {  
  57. if(mCamera!=null)  
  58. {  
  59. mCamera.release();  
  60. mCamera = null ;  
  61. }  
  62. //<uses-permission android:name="android.permission.CAMERA" />   
  63. //必须添加此权限,否则DDMS便会提示你:can not connect to Camera service   
  64. mCamera = Camera.open();  
  65.   
  66. try {  
  67. mCamera.setPreviewDisplay(mHolder);//此代码必须添加视频才会显示出来   
  68. mCamera.setPreviewCallback(this);  
  69.   
  70. catch (IOException e) {  
  71. e.printStackTrace();  
  72. }  
  73. }  
  74.   
  75.   
  76. @Override  
  77. public void surfaceDestroyed(SurfaceHolder holder) {  
  78. if(mCamera != null)  
  79. {  
  80. mCamera.release();  
  81. mCamera = null ;  
  82. }  
  83. }  
  84.   
  85.   
  86. @Override  
  87. public void onPreviewFrame(byte[] data, Camera camera) {  
  88. // TODO Auto-generated method stub   
  89.   
  90. //get the prew frame here,the data of default is YUV420_SP   
  91. //you should change YUV420_SP to YUV420_P   
  92.   
  93. }  
  94.   
  95.   
  96.   
  97.   
  98. }  

1. 为了确保在所有的平台上你都能够看到画面,SurfaceCreated() SurfaceChanged() SurfaceDestory()请一定要按照上面的写法写:
SurfaceCreated中注意
mCamera.setPreviewDisplay(mHolder);//此代码必须添加视频才会显示出来
   mCamera.setPreviewCallback(this);// 设置预览帧的接口,就是通过这个接口,我们来获得预览帧的数据的

2.图像是倒的如何解决?
//and set the preview to landscape mode.
        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
在SetContentView之前调用此代码,理由大家自己看API文档,解释的麻烦.

3.public void onPreviewFrame(byte[] data, Camera camera)

该接口为获取视频预览帧的接口,传递进来的data,默认是YUV420SP的,H264编码的源默认是YUV420的,将他们转换一下再编码图像就正常了;

转换函数:

  1. private byte[] changeYUV420SP2P(byte[]data,int length){  
  2. int width = 176;  
  3. int height = 144;  
  4. byte[] str = new byte[length];  
  5. System.arraycopy(data, 0, str, 0,width*height);  
  6.   
  7. int strIndex = width*height;  
  8.   
  9. for(int i = width*height+1; i < length ;i+=2)  
  10. {  
  11. str[strIndex++] = data[i];  
  12. }  
  13.   
  14.   
  15. for(int i = width*height;i<length;i+=2)  
  16. {  
  17. str[strIndex++] = data[i];  
  18. }  
  19. return str;  
  20. }  

4.编解码库
关于Android的编解码库因为涉及到公司的版权问题,请大家原谅我无法给出库了,不过这些都是从X264中提取出来的,是在Windows主机上搭建了一个linux的虚拟机,然后在linux虚拟机下编写的NDK开源库,X264这块因为最近一直在弄Sipdroid的代码,暂时还无法腾出精力来管理


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值