写在前面

  • 这段时间接了个安卓功能,把扔了很久的安卓又复习了一遍。其实就是个调用相机录像上传的功能。但是要注意的是系统自带的相机会出现几个无法避免的问题,那就是像素无法具体控制,可以简单调参数,如果对文件大小和像素没有特殊要求的,也可采用此方案,这里简单介绍一下

调用系统相机优点: 界面比较美观,功能相对完善。毕竟系统自带的相机。
调用系统相机缺点: 系统相机其实相当于一个已经封装好的工具,个性化的定义参数相对有限,比如无法自定义具体的分辨率,文件要么清晰粘内存,要么低至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、回调代码(划重点奥)
  • 继承Activity

在这里插入图片描述


  • 在onActivityResult下面写回调函数
 /**
     * 选择回调
     */
    @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;
    }

关于一些用到的静态方法:


  • getPortalUrl 地址拼接
    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);
    }

最后的最后:

这里附上另一篇关于调用系统相机录像上传的文章,也是博主自己踩出来的:

你以为还有么,没有了,以上便是调用相机录像并上传的所有过程。自定义相机录像后面博主找时间给补上吧,花了一周时间业余时间研究的,还是值得记录一下的。

以上便是所有内容,如有错误,还望指正!欢迎大家留言交流!

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐