写在前面
- 这段时间接了个安卓功能,把扔了很久的安卓又复习了一遍。其实就是个调用相机录像上传的功能。但是要注意的是系统自带的相机会出现几个无法避免的问题,那就是像素无法具体控制,可以简单调参数,如果对文件大小和像素没有特殊要求的,也可采用此方案,这里简单介绍一下
调用系统相机优点: 界面比较美观,功能相对完善。毕竟系统自带的相机。 调用系统相机缺点: 系统相机其实相当于一个已经封装好的工具,个性化的定义参数相对有限,比如无法自定义具体的分辨率,文件要么清晰粘内存,要么低至kb 画质糊成奥利给。
博主最后也是因为画质无法满足需求,最后放弃了调用系统相机。选择自定义相机,参数设置相对灵活。关于自定义相机我后面会在另一篇博客进行分享。
一、录像上传的思路
- 1、调用系统相机录像,所以得获取摄像头和麦克疯的权限
- 2、缓存到本地内存再进行上传,所以得获取
- 3、通过okhttp以流的方式上传到后台
二、添加相关权限
<!-- 授予该程序使用摄像头的权限 -->
<uses-permission android:name="android.permission.CAMERA"/>
<!-- 授予使用外部存储器的权限 -->
<permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
<!-- 授予修改系统设置权限 -->
<uses-permission android:name="android.permission.WRITE_SETTINGS" />
<!-- 授予该程序使用麦克疯的权限 -->
<uses-permission android:name="android.permission.RECORD_AUDIO" />
三、按钮设置监听,调用相机录像并回调
1、按钮设置监听:
2、调用代码
public void startCamera(View view) {
// 激活系统的照相机进行录像
Intent captureImageCamera = new Intent(
MediaStore.ACTION_VIDEO_CAPTURE);
//画质 高 1min 100M 低 1min 1.8M 不限制此参数 1min 15M
captureImageCamera.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, Constants.VideoQuality.HIGH);
//允许记录的最长时间(以 秒 为单位) 例如:限制为30分钟
captureImageCamera.putExtra(MediaStore.EXTRA_DURATION_LIMIT, 30*60);
//允许的最大大小(以 B 为单位) 例如:限制大小为500M
captureImageCamera.putExtra(MediaStore.EXTRA_SIZE_LIMIT, 1024L * 1024 * 500);
Uri fileUri = CommonCode.getOutputMediaFileUri(MEDIA_TYPE_VIDEO);
captureImageCamera.putExtra(MediaStore.EXTRA_OUTPUT, fileUri); //指定要保存的位置。
startActivityForResult(captureImageCamera, MainActivity.VIDEO_RECORD);
}
关于MediaStore.EXTRA_VIDEO_QUALITY这个参数我要说两句,安卓开发文档里面只支持0和1两个参数。博主4800万像素的手机,画质 高 1min 100M 低 1min 1.8M 不限制此参数 1min 15M,大概就是这样子,同事小米11不限制1min就飙到了一百多M,是我的一百多倍。所以说虽然调用系统相机很简单,就上面几行代码就搞定了。但是存在的弊端也显而易见。这个应该是不同的手机按一定比例压缩的。出来的效果也不一样。
开发文档如下:可以看到其实就两个参数,而这两个参数一个高的离谱, 一个低到离谱,基本没法打到想要的效果。所以博主最后还是选择了自定义相机;文档传送门路径》》》:
》》英文的
》》中文的:
3、回调代码(划重点奥)
/**
* 选择回调
*/
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
//检验返回的code值是否是录像返回的,如果还有其他的code一定区分开来
if(requestCode == MainActivity.VIDEO_RECORD_DEFAULT){
uploadVideo(data);
}
}
public boolean uploadVideo(Intent data){
try {
if(null == data || null == data.getStringExtra("url")){
return false;
}
//这里回传的uri其实就是我们startCamera里面传过去的fileUri
Uri uri = data.getData();
path = uri.getPath();
Log.d("返回文件路径:", path.substring(path.lastIndexOf("/") + 1));
}catch (Exception e){
e.printStackTrace();
return false;
}
new Thread(new Runnable() {
@Override
public void run() {
//后台服务器接收视频的接口
String url = CommonCode.getPortalUrl("/chatRecord/uploadFile");
File file = new File(path);
if (file.length()<1024*1024*800) {
OkHttpClient client = new OkHttpClient();
RequestBody requestBody = new MultipartBody.Builder()
.setType(MultipartBody.FORM)
.addFormDataPart("file", file.getName(),
RequestBody.create(MediaType.parse("multipart/form-data"), file))
.build();
Request request = new Request.Builder()
.header("Authorization", "ClientID" + UUID.randomUUID())
.url(url)
.post(requestBody)
.build();
Response response = null;
try {
response = client.newCall(request).execute();
String result = response.body().string();
JSONObject jsonObject = JSONObject.parseObject(result);
serverPath = jsonObject.getString("serverPath");
} catch (IOException e) {
e.printStackTrace();
}
if (!response.isSuccessful())
try {
throw new IOException("Unexpected code " + response);
} catch (IOException e) {
e.printStackTrace();
}
Message msg = Message.obtain();
msg.what = 2;
handler.sendMessage(msg);
} else {
String filenames = UUID.randomUUID().toString();
byte[] inStream;
//接受流的容量
long streamTotal = 0;
//流需要分开的数量
int streamNum = 0;
//文件剩下的字符数
int leave = 0;
try {
FileInputStream inputStream = new FileInputStream(file);
streamTotal = inputStream.available();
streamNum = (int)Math.floor(streamTotal/MAX_BYTE);
leave = (int)streamTotal % MAX_BYTE;
//文件的容量大于60Mb时进入循环
if (streamNum > 0) {
for (int i = 0; i < streamNum; ++i) {
inStream = new byte[MAX_BYTE];
inputStream.read(inStream,0,MAX_BYTE);
//向后台传inStream
JSONObject param = new JSONObject();
param.put("instream",inStream);
String searchUrl = CommonCode.getPortalUrl("/chatRecord/uploadStream");
JSONObject result = CommonCode.postGetJson(param, searchUrl);
}
}
inStream = new byte[leave];
JSONObject param = new JSONObject();
param.put("instream",inStream);
param.put("fileName", filenames);
String searchUrl = CommonCode.getPortalUrl("/chatRecord/uploadStream");
JSONObject result = CommonCode.postGetJson(param, searchUrl);
inputStream.close();
serverPath = filenames +".mp4";
Message msg = Message.obtain();
msg.what = 2;
handler.sendMessage(msg);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}).start();
return true;
}
关于一些用到的静态方法:
public static String getPortalUrl(String portalname){
String url = "http://" + imageServerIpPort + portalname;
return url;
}
public static Uri getOutputMediaFileUri(int type){
return Uri.fromFile(getOutputMediaFile(type));
}
public static File getOutputMediaFile(int type){
File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES), "MyCameraApp");
if (! mediaStorageDir.exists()){
if (! mediaStorageDir.mkdirs()){
Log.d("MyCameraApp", "failed to create directory");
return null;
}
}
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
File mediaFile;
if (type == MEDIA_TYPE_IMAGE){
mediaFile = new File(mediaStorageDir.getPath() + File.separator +
"IMG_"+ timeStamp + ".jpg");
} else if(type == MEDIA_TYPE_VIDEO) {
mediaFile = new File(mediaStorageDir.getPath() + File.separator +
"VID_"+ timeStamp + ".mp4");
} else {
return null;
}
return mediaFile;
}
- getOutputMediaFileUri 获取文件URi
public static Uri getOutputMediaFileUri(File file){
return Uri.fromFile(file);
}
最后的最后:
- 你以为还有么,没有了,以上便是调用相机录像并上传的所有过程。自定义相机录像后面博主找时间给补上吧,花了一周时间业余时间研究的,还是值得记录一下的。
- 以上便是所有内容,如有错误,还望指正!欢迎大家留言交流!
|