android视频和音频采集及预览
2016-09-29 14:49
323 查看
android视频和音频采集及预览
本文说明android采集方面的方法,预览用previcw,视频采集用Camera类,音频采集用AudioRecord,如果需要ios采集在我的博客中看上一篇,ffmpeg的windows和linux采集用的dshow,vfw,linux4video,在适合的时候写篇博客。
本文所需代码如下:
package com.android.lvs.lvs_android_device_camera_module;
/**
* Created by zhuweigang on 2016/7/1.
*/
//包含传出的结构体info类
import com.android.lvs.lvsandroidinfo.LvsAndroidInfo;
import android.graphics.ImageFormat;
import android.os.Bundle;
import android.hardware.Camera;
import android.os.Bundle;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import android.annotation.TargetApi;
import android.app.Activity;
import android.content.pm.PackageManager;
import android.hardware.Camera;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
import java.nio.charset.Charset;
import java.util.HashMap;
import java.util.List;
import java.util.Date;
import java.nio.CharBuffer;
import java.nio.ByteBuffer;
import java.io.IOException;
import java.util.concurrent.locks.Lock;
public class LvsAndroidDeviceCameraCollection
{
//成员
private static final String TAG = "lvs_Camera";
public int m_num_device = 0;
public LvsAndroidInfo m_Module_Info = null; //如果多个摄像头得到当前使用的info
int m_streamid_accumulation = 0; //streamid累加,用于区分streamid,当音视频streamid相同时
Lock m_thread_video_callback_lock; //用于视频采集的锁,防止回调取出数据和处理冲突
File file_video = null; //测试采集到的视频数据是否正确
FileOutputStream fos_video = null; //测试采集到的视频数据是否正确
//android 后面的摄像头
public final Camera.PreviewCallback mPreviewCallbacx_CAMERA_FACING_BACK = new Camera.PreviewCallback()
{
@Override
public void onPreviewFrame(byte[] arg0, Camera ncamera)
{
Camera.Parameters parameters = ncamera.getParameters();
if (m_Module_Info != null)
{
//线程锁
m_thread_video_callback_lock.lock();
//回调这一帧的时间戳
long timenow = System.currentTimeMillis();
m_Module_Info.setBuf(arg0);
//for(int p=0;p<arg0.length;p++){
// m_Module_Info.Buf[p]= (char)arg0[p];
//}
m_Module_Info.ActualLen = arg0.length;
m_Module_Info.pts = timenow;
m_Module_Info.dts = timenow;
//释放线程锁
m_thread_video_callback_lock.unlock();
}
}
};
//android 前面的摄像头
public final Camera.PreviewCallback mPreviewCallbacx_CAMERA_FACING_FRONT = new Camera.PreviewCallback()
{
@Override
public void onPreviewFrame(byte[] arg0, Camera ncamera)
{
Camera.Parameters parameters = ncamera.getParameters();
if (m_Module_Info != null)
{
//线程锁
m_thread_video_callback_lock.lock();
//回调这一帧的时间戳
long timenow = System.currentTimeMillis();
m_Module_Info.setBuf(arg0);
//for(int p=0;p<arg0.length;p++){
// m_Module_Info.Buf[p]= arg0[p];
//}
m_Module_Info.ActualLen = arg0.length;
m_Module_Info.pts = timenow;
m_Module_Info.dts = timenow;
//释放线程锁
m_thread_video_callback_lock.unlock();
//测试采集到的视频数据是否正确
/*
if (file_video == null )
{
file_video = new File(Environment.getExternalStorageDirectory() + File.separator + "lvs_test_camera.yuv");
try
{
fos_video = new FileOutputStream(file_video);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
//写到文件中
try {
fos_video.write(m_Module_Info.Buf, 0, (int) m_Module_Info.ActualLen);
} catch (IOException e) {
e.printStackTrace();
}
*/
}
}
};
//函数
public int init_param(HashMap<Integer,LvsAndroidInfo> list_Module_Info,
HashMap<Integer,Camera> list_Camera,
int streamid_accumulation,Lock thread_video_callback_lock)
{
int ret = 0;
m_thread_video_callback_lock = thread_video_callback_lock;
m_streamid_accumulation = streamid_accumulation;
m_num_device = Camera.getNumberOfCameras();
for (int i = 0 ; i< m_num_device;i++)
{
LvsAndroidInfo Module_Info = new LvsAndroidInfo();
Camera camera = null;
Module_Info.stream_id = i + streamid_accumulation;
Module_Info.Is_ToNext_Module = 1;
Module_Info.device_type = 0; //摄像头
Module_Info.CodecType = 0x1; //视频
Module_Info.pts = 0;
Module_Info.dts = 0;
Module_Info.timebase_num = 1;
Module_Info.timebase_den = 1000; //毫秒转换为妙用
camera = open_camera(Module_Info,i);
if (camera == null)
{
return -1;
}
Module_Info.BufLen = Module_Info.Width *Module_Info.Height*3;
Module_Info.Buf = new byte[Module_Info.Width *Module_Info.Height*3];
Module_Info.ActualLen = 0;
//关闭摄像头 在read/write的时候重新打开
if (camera != null)
{
camera.setPreviewCallback(null); //这里如果不设置会出现崩溃的问题
camera.release();
camera = null;
}
//填写到list中
list_Module_Info.put(i + m_streamid_accumulation,Module_Info);
list_Camera.put(i + m_streamid_accumulation,camera);
}
return 1;
}
public void uninit(HashMap<Integer,LvsAndroidInfo> list_Module_Info,
HashMap<Integer,Camera> list_Camera,Lock thread_video_callback_lock)
{
m_Module_Info = null;
for (int i = 0 ; i< m_num_device;i++)
{
LvsAndroidInfo Module_Info = list_Module_Info.get(i + m_streamid_accumulation);
Camera camera = list_Camera.get(i + m_streamid_accumulation);
if (camera != null)
{
//停止输出数据
camera.stopPreview();
camera.setPreviewCallback(null); //这里如果不设置会出现崩溃的问题
//关闭摄像头
camera.release();
camera = null;
}
if (Module_Info != null)
{
if (Module_Info.Buf != null)
{
Module_Info.Buf = null;
}
Module_Info = null;
}
}
list_Module_Info.clear();
list_Module_Info = null;
list_Camera.clear();
list_Camera = null;
m_thread_video_callback_lock = thread_video_callback_lock;
}
public int CameraRead(HashMap<Integer,LvsAndroidInfo> list_Module_Info,
HashMap<Integer,Camera> list_Camera)
{
int ret = 0;
for (int i = 0 ; i< m_num_device;i++)
{
LvsAndroidInfo Module_Info = list_Module_Info.get(i + m_streamid_accumulation);
Camera camera = list_Camera.get(i + m_streamid_accumulation);
//如果需要采集
if(Module_Info.Is_ToNext_Module == 1)
{
if (camera == null)
{
camera = open_camera(Module_Info,i);
if (camera == null)
{
return -1;
}
//设置回调函数
Camera.CameraInfo cameraInfo = new Camera.CameraInfo();
Camera.getCameraInfo(i,cameraInfo);
if (cameraInfo.facing == cameraInfo.CAMERA_FACING_BACK)
{
camera.setPreviewCallback(mPreviewCallbacx_CAMERA_FACING_BACK);
}
else if(cameraInfo.facing == cameraInfo.CAMERA_FACING_FRONT)
{
camera.setPreviewCallback(mPreviewCallbacx_CAMERA_FACING_FRONT);
}
else
{
return -1;
}
list_Camera.put(i + m_streamid_accumulation,camera);
//得到当前使用的module info
m_Module_Info = Module_Info;
//输出数据在预览类里面做
}
}
}
return 1;
}
public int CameraWrite(HashMap<Integer,LvsAndroidInfo> list_Module_Info,
HashMap<Integer,Camera> list_Camera)
{
int ret = 0;
for (int i = 0 ; i< m_num_device;i++)
{
LvsAndroidInfo Module_Info = list_Module_Info.get(i + m_streamid_accumulation);
Camera camera = list_Camera.get(i + m_streamid_accumulation);
//如果需要采集
if(Module_Info.Is_ToNext_Module == 1)
{
if (camera == null)
{
camera = open_camera(Module_Info,i);
if (camera == null)
{
return -1;
}
//设置回调函数
Camera.CameraInfo cameraInfo = new Camera.CameraInfo();
Camera.getCameraInfo(i,cameraInfo);
if (cameraInfo.facing == cameraInfo.CAMERA_FACING_BACK)
{
camera.setPreviewCallback(mPreviewCallbacx_CAMERA_FACING_BACK);
}
else if(cameraInfo.facing == cameraInfo.CAMERA_FACING_FRONT)
{
camera.setPreviewCallback(mPreviewCallbacx_CAMERA_FACING_FRONT);
}
else
{
return -1;
}
list_Camera.put(i + m_streamid_accumulation,camera);
//得到当前使用的module info
m_Module_Info = Module_Info;
//输出数据在预览类里面做
}
}
}
return 1;
}
//打开摄像头
private Camera open_camera(LvsAndroidInfo Module_Info,int cameraId)
{
int k = 0;
int m = 0;
//打开摄像头
Camera camera = null;
camera = Camera.open(cameraId);
//重试三次
for(int retry = 0;retry < 3 ;retry ++)
{
if (camera == null)
{
return null;
}
}
//参考SDK中的API,获取摄像头的参数:
Camera.Parameters parameters = camera.getParameters();// 摄像头参数集
//获取摄像头支持的各种格式
List<Integer> supportedPictureFormats = parameters.getSupportedPictureFormats();;
//获取预览的各种视频格式
List<Integer> supportedPreviewFormats = parameters.getSupportedPreviewFormats();
//获取摄像头支持的各种分辨率
List<Camera.Size> supportedPictureSizes = parameters.getSupportedPictureSizes();
//获取预览的各种分辨率
List<Camera.Size> supportedPreviewSizes = parameters.getSupportedPreviewSizes();
//获取预览摄像头支持的帧率
List<int[]> SupportedPreviewFpsRange = parameters.getSupportedPreviewFpsRange();
// 设置预浏格式,注意要在预览支持的范围内选择
//parameters.setPreviewFormat(ImageFormat.NV21);
// 设置预浏尺寸,注意要在预览支持的范围内选择
//parameters.setPreviewSize(640, 480);
//设置参数
// 设置视频格式 picture是拍照,Preview是视频
parameters.setPreviewFormat(ImageFormat.NV21); //貌似nv21所有手机都支持
Module_Info.Stream_PixFormat = 24;
// 设置照片分辨率,注意要在摄像头支持的范围内选择
Camera.Size camerasize;
for (k = 0; k < supportedPictureSizes.size() ; k++)
{
camerasize = supportedPictureSizes.get(k);
if (camerasize.width == 640 && camerasize.height == 480) //采集默认640 * 480
{
parameters.setPictureSize(640,480);
parameters.setPreviewSize(640,480);
Module_Info.Width = 640;
Module_Info.Height = 480;
break;
}
}
//如果未找到,取出第一个和最后一个用小的
if (k == supportedPictureSizes.size() )
{
//取出第一个
Camera.Size camerasize_first = supportedPictureSizes.get(0);
//取出最后一个
Camera.Size camerasize_end = supportedPictureSizes.get(supportedPictureFormats.size() - 1);
if (camerasize_first.width >= camerasize_end.width)
{
parameters.setPictureSize(camerasize_end.width,camerasize_end.height);
Module_Info.Width = camerasize_end.width;
Module_Info.Height = camerasize_end.height;
}
else
{
parameters.setPictureSize(camerasize_first.width,camerasize_first.height);
Module_Info.Width = camerasize_first.width;
Module_Info.Height = camerasize_first.height;
}
}
// 设置照片帧率,注意要在摄像头支持的范围内选择,如果不支持25fps 直接用默认
List<int[]> PreviewFpsRang = parameters.getSupportedPreviewFpsRange();
int[] FpsRang;
for (m = 0; m< PreviewFpsRang.size();m++)
{
FpsRang = PreviewFpsRang.get(m);
int FpsRangfirst = FpsRang[0];
int FpsRangend = FpsRang[FpsRang.length -1];
if ((FpsRangfirst < 25000 && FpsRangend >= 25000) ||
(FpsRangfirst >= 25000 && FpsRangend < 25000))
{
parameters.setPreviewFpsRange(25000,FpsRangend);
break;
}
else
{
continue;
}
}
//parameters.setRotation(0);
// 设置摄像头参数
camera.setParameters(parameters); //旋转90度,貌似没用
//camera.setDisplayOrientation(0); //旋转90度,貌似没用
return camera;
}
}
如有错误请指正:
本文说明android采集方面的方法,预览用previcw,视频采集用Camera类,音频采集用AudioRecord,如果需要ios采集在我的博客中看上一篇,ffmpeg的windows和linux采集用的dshow,vfw,linux4video,在适合的时候写篇博客。
本文所需代码如下:
package com.android.lvs.lvs_android_device_camera_module; /** * Created by zhuweigang on 2016/6/30. */ //包含传出的结构体info类 import com.android.lvs.lvsandroidinfo.LvsAndroidInfo; import android.graphics.ImageFormat; import android.hardware.Camera; import java.io.IOException; import android.view.SurfaceHolder; import android.view.SurfaceView; import java.util.HashMap; import android.content.Context; import android.util.AttributeSet; public class LvsAndroidDeviceCameraPreview extends SurfaceView implements SurfaceHolder.Callback { private static final String TAG = "lvs_Camera"; public SurfaceHolder mSurfaceHolder = null; public Camera mcamera = null; public LvsAndroidDeviceCameraPreview(Context context) { super(context); } public LvsAndroidDeviceCameraPreview(Context context, AttributeSet attrs) { super(context, attrs); mSurfaceHolder = getHolder(); mSurfaceHolder.addCallback(this); mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); } @Override public void surfaceCreated(SurfaceHolder surfaceHolder) { mSurfaceHolder = surfaceHolder; if (mcamera != null) { //摄像头旋转90度 mcamera.setDisplayOrientation(90); //设置渲染Holder try { if (mSurfaceHolder != null) { mcamera.setPreviewDisplay(mSurfaceHolder); } } catch (IOException exception) { } //开始输出数据 mcamera.startPreview(); } } @Override public void surfaceChanged(SurfaceHolder surfaceHolder, int i, int i1, int i2) { } @Override public void surfaceDestroyed(SurfaceHolder surfaceHolder) { mSurfaceHolder = null; } public void setCamera(HashMap<Integer,LvsAndroidInfo> list_Module_Info, HashMap<Integer,Camera> list_Camera,int streamid_accumulation) { for (int i = 0; i < list_Module_Info.size();i++) { LvsAndroidInfo Module_Info = list_Module_Info.get(i + streamid_accumulation); Camera camera = list_Camera.get(i + streamid_accumulation); //如果需要采集 if(Module_Info.Is_ToNext_Module == 1) { //这里如果多个摄像头同时渲染则需要创建多个渲染对象 mcamera = camera; Camera.Parameters parameters = camera.getParameters();// 摄像头参数集 parameters.setRotation(90); parameters.setPreviewFormat(ImageFormat.NV21); parameters.setPreviewSize(640,480); } } } }
package com.android.lvs.lvs_android_device_camera_module;
/**
* Created by zhuweigang on 2016/7/1.
*/
//包含传出的结构体info类
import com.android.lvs.lvsandroidinfo.LvsAndroidInfo;
import android.graphics.ImageFormat;
import android.os.Bundle;
import android.hardware.Camera;
import android.os.Bundle;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import android.annotation.TargetApi;
import android.app.Activity;
import android.content.pm.PackageManager;
import android.hardware.Camera;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
import java.nio.charset.Charset;
import java.util.HashMap;
import java.util.List;
import java.util.Date;
import java.nio.CharBuffer;
import java.nio.ByteBuffer;
import java.io.IOException;
import java.util.concurrent.locks.Lock;
public class LvsAndroidDeviceCameraCollection
{
//成员
private static final String TAG = "lvs_Camera";
public int m_num_device = 0;
public LvsAndroidInfo m_Module_Info = null; //如果多个摄像头得到当前使用的info
int m_streamid_accumulation = 0; //streamid累加,用于区分streamid,当音视频streamid相同时
Lock m_thread_video_callback_lock; //用于视频采集的锁,防止回调取出数据和处理冲突
File file_video = null; //测试采集到的视频数据是否正确
FileOutputStream fos_video = null; //测试采集到的视频数据是否正确
//android 后面的摄像头
public final Camera.PreviewCallback mPreviewCallbacx_CAMERA_FACING_BACK = new Camera.PreviewCallback()
{
@Override
public void onPreviewFrame(byte[] arg0, Camera ncamera)
{
Camera.Parameters parameters = ncamera.getParameters();
if (m_Module_Info != null)
{
//线程锁
m_thread_video_callback_lock.lock();
//回调这一帧的时间戳
long timenow = System.currentTimeMillis();
m_Module_Info.setBuf(arg0);
//for(int p=0;p<arg0.length;p++){
// m_Module_Info.Buf[p]= (char)arg0[p];
//}
m_Module_Info.ActualLen = arg0.length;
m_Module_Info.pts = timenow;
m_Module_Info.dts = timenow;
//释放线程锁
m_thread_video_callback_lock.unlock();
}
}
};
//android 前面的摄像头
public final Camera.PreviewCallback mPreviewCallbacx_CAMERA_FACING_FRONT = new Camera.PreviewCallback()
{
@Override
public void onPreviewFrame(byte[] arg0, Camera ncamera)
{
Camera.Parameters parameters = ncamera.getParameters();
if (m_Module_Info != null)
{
//线程锁
m_thread_video_callback_lock.lock();
//回调这一帧的时间戳
long timenow = System.currentTimeMillis();
m_Module_Info.setBuf(arg0);
//for(int p=0;p<arg0.length;p++){
// m_Module_Info.Buf[p]= arg0[p];
//}
m_Module_Info.ActualLen = arg0.length;
m_Module_Info.pts = timenow;
m_Module_Info.dts = timenow;
//释放线程锁
m_thread_video_callback_lock.unlock();
//测试采集到的视频数据是否正确
/*
if (file_video == null )
{
file_video = new File(Environment.getExternalStorageDirectory() + File.separator + "lvs_test_camera.yuv");
try
{
fos_video = new FileOutputStream(file_video);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
//写到文件中
try {
fos_video.write(m_Module_Info.Buf, 0, (int) m_Module_Info.ActualLen);
} catch (IOException e) {
e.printStackTrace();
}
*/
}
}
};
//函数
public int init_param(HashMap<Integer,LvsAndroidInfo> list_Module_Info,
HashMap<Integer,Camera> list_Camera,
int streamid_accumulation,Lock thread_video_callback_lock)
{
int ret = 0;
m_thread_video_callback_lock = thread_video_callback_lock;
m_streamid_accumulation = streamid_accumulation;
m_num_device = Camera.getNumberOfCameras();
for (int i = 0 ; i< m_num_device;i++)
{
LvsAndroidInfo Module_Info = new LvsAndroidInfo();
Camera camera = null;
Module_Info.stream_id = i + streamid_accumulation;
Module_Info.Is_ToNext_Module = 1;
Module_Info.device_type = 0; //摄像头
Module_Info.CodecType = 0x1; //视频
Module_Info.pts = 0;
Module_Info.dts = 0;
Module_Info.timebase_num = 1;
Module_Info.timebase_den = 1000; //毫秒转换为妙用
camera = open_camera(Module_Info,i);
if (camera == null)
{
return -1;
}
Module_Info.BufLen = Module_Info.Width *Module_Info.Height*3;
Module_Info.Buf = new byte[Module_Info.Width *Module_Info.Height*3];
Module_Info.ActualLen = 0;
//关闭摄像头 在read/write的时候重新打开
if (camera != null)
{
camera.setPreviewCallback(null); //这里如果不设置会出现崩溃的问题
camera.release();
camera = null;
}
//填写到list中
list_Module_Info.put(i + m_streamid_accumulation,Module_Info);
list_Camera.put(i + m_streamid_accumulation,camera);
}
return 1;
}
public void uninit(HashMap<Integer,LvsAndroidInfo> list_Module_Info,
HashMap<Integer,Camera> list_Camera,Lock thread_video_callback_lock)
{
m_Module_Info = null;
for (int i = 0 ; i< m_num_device;i++)
{
LvsAndroidInfo Module_Info = list_Module_Info.get(i + m_streamid_accumulation);
Camera camera = list_Camera.get(i + m_streamid_accumulation);
if (camera != null)
{
//停止输出数据
camera.stopPreview();
camera.setPreviewCallback(null); //这里如果不设置会出现崩溃的问题
//关闭摄像头
camera.release();
camera = null;
}
if (Module_Info != null)
{
if (Module_Info.Buf != null)
{
Module_Info.Buf = null;
}
Module_Info = null;
}
}
list_Module_Info.clear();
list_Module_Info = null;
list_Camera.clear();
list_Camera = null;
m_thread_video_callback_lock = thread_video_callback_lock;
}
public int CameraRead(HashMap<Integer,LvsAndroidInfo> list_Module_Info,
HashMap<Integer,Camera> list_Camera)
{
int ret = 0;
for (int i = 0 ; i< m_num_device;i++)
{
LvsAndroidInfo Module_Info = list_Module_Info.get(i + m_streamid_accumulation);
Camera camera = list_Camera.get(i + m_streamid_accumulation);
//如果需要采集
if(Module_Info.Is_ToNext_Module == 1)
{
if (camera == null)
{
camera = open_camera(Module_Info,i);
if (camera == null)
{
return -1;
}
//设置回调函数
Camera.CameraInfo cameraInfo = new Camera.CameraInfo();
Camera.getCameraInfo(i,cameraInfo);
if (cameraInfo.facing == cameraInfo.CAMERA_FACING_BACK)
{
camera.setPreviewCallback(mPreviewCallbacx_CAMERA_FACING_BACK);
}
else if(cameraInfo.facing == cameraInfo.CAMERA_FACING_FRONT)
{
camera.setPreviewCallback(mPreviewCallbacx_CAMERA_FACING_FRONT);
}
else
{
return -1;
}
list_Camera.put(i + m_streamid_accumulation,camera);
//得到当前使用的module info
m_Module_Info = Module_Info;
//输出数据在预览类里面做
}
}
}
return 1;
}
public int CameraWrite(HashMap<Integer,LvsAndroidInfo> list_Module_Info,
HashMap<Integer,Camera> list_Camera)
{
int ret = 0;
for (int i = 0 ; i< m_num_device;i++)
{
LvsAndroidInfo Module_Info = list_Module_Info.get(i + m_streamid_accumulation);
Camera camera = list_Camera.get(i + m_streamid_accumulation);
//如果需要采集
if(Module_Info.Is_ToNext_Module == 1)
{
if (camera == null)
{
camera = open_camera(Module_Info,i);
if (camera == null)
{
return -1;
}
//设置回调函数
Camera.CameraInfo cameraInfo = new Camera.CameraInfo();
Camera.getCameraInfo(i,cameraInfo);
if (cameraInfo.facing == cameraInfo.CAMERA_FACING_BACK)
{
camera.setPreviewCallback(mPreviewCallbacx_CAMERA_FACING_BACK);
}
else if(cameraInfo.facing == cameraInfo.CAMERA_FACING_FRONT)
{
camera.setPreviewCallback(mPreviewCallbacx_CAMERA_FACING_FRONT);
}
else
{
return -1;
}
list_Camera.put(i + m_streamid_accumulation,camera);
//得到当前使用的module info
m_Module_Info = Module_Info;
//输出数据在预览类里面做
}
}
}
return 1;
}
//打开摄像头
private Camera open_camera(LvsAndroidInfo Module_Info,int cameraId)
{
int k = 0;
int m = 0;
//打开摄像头
Camera camera = null;
camera = Camera.open(cameraId);
//重试三次
for(int retry = 0;retry < 3 ;retry ++)
{
if (camera == null)
{
return null;
}
}
//参考SDK中的API,获取摄像头的参数:
Camera.Parameters parameters = camera.getParameters();// 摄像头参数集
//获取摄像头支持的各种格式
List<Integer> supportedPictureFormats = parameters.getSupportedPictureFormats();;
//获取预览的各种视频格式
List<Integer> supportedPreviewFormats = parameters.getSupportedPreviewFormats();
//获取摄像头支持的各种分辨率
List<Camera.Size> supportedPictureSizes = parameters.getSupportedPictureSizes();
//获取预览的各种分辨率
List<Camera.Size> supportedPreviewSizes = parameters.getSupportedPreviewSizes();
//获取预览摄像头支持的帧率
List<int[]> SupportedPreviewFpsRange = parameters.getSupportedPreviewFpsRange();
// 设置预浏格式,注意要在预览支持的范围内选择
//parameters.setPreviewFormat(ImageFormat.NV21);
// 设置预浏尺寸,注意要在预览支持的范围内选择
//parameters.setPreviewSize(640, 480);
//设置参数
// 设置视频格式 picture是拍照,Preview是视频
parameters.setPreviewFormat(ImageFormat.NV21); //貌似nv21所有手机都支持
Module_Info.Stream_PixFormat = 24;
// 设置照片分辨率,注意要在摄像头支持的范围内选择
Camera.Size camerasize;
for (k = 0; k < supportedPictureSizes.size() ; k++)
{
camerasize = supportedPictureSizes.get(k);
if (camerasize.width == 640 && camerasize.height == 480) //采集默认640 * 480
{
parameters.setPictureSize(640,480);
parameters.setPreviewSize(640,480);
Module_Info.Width = 640;
Module_Info.Height = 480;
break;
}
}
//如果未找到,取出第一个和最后一个用小的
if (k == supportedPictureSizes.size() )
{
//取出第一个
Camera.Size camerasize_first = supportedPictureSizes.get(0);
//取出最后一个
Camera.Size camerasize_end = supportedPictureSizes.get(supportedPictureFormats.size() - 1);
if (camerasize_first.width >= camerasize_end.width)
{
parameters.setPictureSize(camerasize_end.width,camerasize_end.height);
Module_Info.Width = camerasize_end.width;
Module_Info.Height = camerasize_end.height;
}
else
{
parameters.setPictureSize(camerasize_first.width,camerasize_first.height);
Module_Info.Width = camerasize_first.width;
Module_Info.Height = camerasize_first.height;
}
}
// 设置照片帧率,注意要在摄像头支持的范围内选择,如果不支持25fps 直接用默认
List<int[]> PreviewFpsRang = parameters.getSupportedPreviewFpsRange();
int[] FpsRang;
for (m = 0; m< PreviewFpsRang.size();m++)
{
FpsRang = PreviewFpsRang.get(m);
int FpsRangfirst = FpsRang[0];
int FpsRangend = FpsRang[FpsRang.length -1];
if ((FpsRangfirst < 25000 && FpsRangend >= 25000) ||
(FpsRangfirst >= 25000 && FpsRangend < 25000))
{
parameters.setPreviewFpsRange(25000,FpsRangend);
break;
}
else
{
continue;
}
}
//parameters.setRotation(0);
// 设置摄像头参数
camera.setParameters(parameters); //旋转90度,貌似没用
//camera.setDisplayOrientation(0); //旋转90度,貌似没用
return camera;
}
}
package com.android.lvs.lvs_android_device_microphone_module; /** * Created by zhuweigang on 2016/7/4. */ //包含传出的结构体info类 import android.hardware.Camera; import android.media.AudioFormat; import android.media.AudioRecord; import android.media.MediaRecorder; import android.os.Environment; import android.util.Xml; import java.io.File; import java.io.FileOutputStream; import java.nio.charset.Charset; import java.util.Date; import java.util.HashMap; import java.nio.CharBuffer; import java.nio.ByteBuffer; import android.util.Xml.Encoding; import com.android.lvs.lvsandroidinfo.LvsAndroidInfo; public class LvsAndroidDeviceMicrophoneCollection { private static final String TAG = "lvs_Microphone"; public int m_num_device = 0; int frequency = 44100; //采样率 int channelConfig = AudioFormat.CHANNEL_IN_STEREO; //声道 int audioEncording = AudioFormat.ENCODING_PCM_16BIT; //样本 AudioRecord m_audioRecord = null; //声音采集类,当前使用的麦克风 int m_bufferSize = 0; //声音回调数据buf长度 int m_streamid_accumulation = 0; //streamid累加,用于区分streamid,当音视频streamid相同时 //函数 public int init_param(HashMap<Integer,LvsAndroidInfo> list_Module_Info, HashMap<Integer,AudioRecord> list_AudioRecord,int streamid_accumulation) { int ret = 0; m_streamid_accumulation = streamid_accumulation; //目前的android手机只有一个麦克风 m_num_device = 1; for (int i = 0 ; i< m_num_device;i++) { LvsAndroidInfo Module_Info = new LvsAndroidInfo(); Camera camera = null; Module_Info.stream_id = i + streamid_accumulation; Module_Info.Is_ToNext_Module = 1; Module_Info.device_type = 1; //麦克风 Module_Info.CodecType = 0x10; //音频 Module_Info.pts = 0; Module_Info.dts = 0; Module_Info.timebase_num = 1; Module_Info.timebase_den = 1000; //毫秒转换为妙用 Module_Info.Channel = 2; Module_Info.SampleFormat = 1; //对应ffmpeg的值 Module_Info.SampleRate = frequency; m_bufferSize = AudioRecord.getMinBufferSize(frequency, channelConfig, audioEncording) * 2; AudioRecord audioRecord = new AudioRecord(MediaRecorder.AudioSource.MIC, frequency, channelConfig, audioEncording, m_bufferSize); if (audioRecord == null) { return -1; } Module_Info.BufLen = m_bufferSize; //如果存在先释放 if (Module_Info.Buf != null) { Module_Info.Buf = null; } Module_Info.Buf = new byte[m_bufferSize]; Module_Info.ActualLen = 0; //打开麦克风 audioRecord.startRecording(); //填写到list中 list_Module_Info.put(i + m_streamid_accumulation,Module_Info); list_AudioRecord.put(i + m_streamid_accumulation,audioRecord); } return 1; } public void uninit(HashMap<Integer,LvsAndroidInfo> list_Module_Info, HashMap<Integer,AudioRecord> list_AudioRecord) { for (int i = 0 ; i< m_num_device;i++) { LvsAndroidInfo Module_Info = list_Module_Info.get(i + m_streamid_accumulation); AudioRecord audioRecord = list_AudioRecord.get(i + m_streamid_accumulation); if (Module_Info.Buf != null) { Module_Info.Buf = null; } if (audioRecord != null) { //停止输出数据 audioRecord.stop(); //关闭摄像头 audioRecord.release(); audioRecord = null; } } list_Module_Info.clear(); list_Module_Info = null; list_AudioRecord.clear(); list_AudioRecord = null; } public int CameraRead(HashMap<Integer,LvsAndroidInfo> list_Module_Info, HashMap<Integer,AudioRecord> list_AudioRecord) { int ret = 0; for (int i = 0 ; i< m_num_device;i++) { LvsAndroidInfo Module_Info = list_Module_Info.get(i + m_streamid_accumulation); AudioRecord audioRecord = list_AudioRecord.get(i + m_streamid_accumulation); //如果需要采集 if(Module_Info.Is_ToNext_Module == 1) { ret = audioRecord.read(Module_Info.Buf,0,m_bufferSize); if (ret < 0) { return -1; } //回调这一帧的时间戳 long timenow = new Date().getTime(); Module_Info.ActualLen = ret; Module_Info.pts = timenow; Module_Info.dts = timenow; } } return 1; } public int CameraWrite(HashMap<Integer,LvsAndroidInfo> list_Module_Info, HashMap<Integer,AudioRecord> list_AudioRecord) { int ret = 0; for (int i = 0 ; i< m_num_device;i++) { LvsAndroidInfo Module_Info = list_Module_Info.get(i + m_streamid_accumulation); AudioRecord audioRecord = list_AudioRecord.get(i + m_streamid_accumulation); //如果需要采集 if(Module_Info.Is_ToNext_Module == 1) { ret = audioRecord.read(Module_Info.Buf,0,m_bufferSize); if (ret < 0) { return -1; } //回调这一帧的时间戳 long timenow = new Date().getTime(); Module_Info.ActualLen = ret; Module_Info.pts = timenow; Module_Info.dts = timenow; } } return 1; } }
如有错误请指正:
交流请加QQ群:62054820
QQ:379969650.
相关文章推荐
- Android多媒体技术(一)Camera实时视频采集预览、拍照、JPEG图片方向的处理
- Android音视频-视频采集(Camera预览)
- Android音视频-音频采集
- Android 视频和音频采集
- Android 音视频开发(二):使用 AudioRecord 采集音频PCM并保存到文件
- Android音视频-视频采集(系统API预览)
- Android音视频-视频采集(Camera2预览基础)
- 在Android 中调用选择图片、视频、添加音频、录音、拍摄视频、拍照等其他的功能
- Android视频采集
- android如何浏览并选择图片、音频 、视频
- android之MediaPlayer播放音频或者视频文件
- 在代码中解决 android 视频 音频 上传到sdcard中 但是在多媒体中心 或者目录下面查看不到的方法
- Android视频采集+H264编码
- 转----Android用MediaRecorder 视频采集
- android如何浏览并选择图片 音频 视频【原】
- Android 支持的媒体格式(音频,视频,图片)
- 在Android 中调用选择图片、视频、添加音频、录音、拍摄视频、拍照等其他的功能
- ffmpeg摄像头视频采集 音频采集的正确参数
- Android视频采集+H264编码
- MTK视频预览和采集方法