Android如何实现边采集边上传--Camera类实现(后续发表MediaRecorder实现)

news/2025/2/26 21:56:00

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

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

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

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

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

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

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

4.H264压缩编码

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

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

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


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. int strIndex = width*height;
  7. for(int i = width*height+1; i < length ;i+=2)
  8. {
  9. str[strIndex++] = data[i];
  10. }
  11. for(int i = width*height;i<length;i+=2)
  12. {
  13. str[strIndex++] = data[i];
  14. }
  15. return str;
  16. }
复制代码



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

我的话费充值店-各种面额

电信100元仅售98.60 
联通100仅售99.00
移动100仅售99.30


http://www.niftyadmin.cn/n/4667608.html

相关文章

一文读懂分红险、万能险和投连险

一、分设账户的区别 分红险不设单独的投资账户&#xff0c;分红险的保障和分红账户是混合的。 万能险设有保障账户和一个单独的投资账户。 投连险也是保障账户和投资账户分离&#xff0c;并设置有几个不同投资账户&#xff0c;可能享有较高回报的同时也需承担一定的风险&#x…

这些混账的开源库在煞笔Windows系统上的编译方法

这些混账的开源库在煞笔Windows系统上的编译方法 母语不就是用来吐槽的么&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;说母语我不骂人难道还用英语么&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&…

WindowManager massge和handler

在一个可移动浮动按钮的demo源码学习中&#xff0c;有一些WindowManager的使用&#xff0c;在此做下总结。 1.翻译过来就是窗口管理&#xff0c;是和应用框架层的窗口管理器交互的接口&#xff0c;通过 mWindowManager (WindowManager) mContext.getSystemService(Context.WIN…

推荐一个好站点,音视频学习

http://www.shouyanwang.org/forum.php 我的话费充值店-各种面额 电信100元仅售98.60 联通100仅售99.00移动100仅售99.30

在Centos 6.6环境使用系统自带的internal-sftp搭建SFTP服务器。

转&#xff1a;http://blog.csdn.net/xinxin19881112/article/details/46831311 打开命令终端窗口&#xff0c;按以下步骤操作。 0、查看openssh的版本 [plain] view plaincopy ssh -V 使用ssh -V 命令来查看openssh的版本&#xff0c;版本必须大于4.8p1&#xff0c;低于的这…

jni 获得java窗口句柄

我们知道C的每个窗体都对应着一个句柄HWND&#xff0c;通过这个句柄我们可以对这个窗口以及它的资源进行各种操作&#xff0c;比如让它前端显示等。那么操作系统给Java编写的窗体&#xff08;Frame或者JFrame的对象或者子类对象&#xff09;有没有分配这个唯一的HWND呢。需要使…

Jquery时间快捷控件(Jtime)配置v1.0

1、脚本代码行 /*** title 时间工具类* note 本类一律违规验证返回false* author {boonyachengdugmail.com}* date 2013-07-01* formatter "2013-07-01 00:00:00" , "2013-07-01"* version LBS2.0 * param plugin Jtime v1.1*/ (function(){window.TimeO…

关于Visual C++ 的CLR、ATL、MFC对比

MFC、ATL和CLR是VC2005内置的3大库&#xff0c;涵盖了windows的各种开发方法和开发应用。当然关于C开发的库不止这3个&#xff0c;不过这3个是微软推荐。从编程所处层次而言&#xff0c;WIN32为最底层,其次是MFC.然后是CLR. WIN32 winAPI MFC MFC类库 CLR .net库 1. WIN32常规就…