美文网首页
AndroidTV视频录制遇到的问题

AndroidTV视频录制遇到的问题

作者: markzl | 来源:发表于2017-03-27 16:26 被阅读477次

公司现在的项目是一个在AndroidTV上开发的,要添加一个新的需求,录制视频。记录一下在AndroidTV上开发录制视频时遇到的小问题:

注: 对于只有一个摄像头的手机可能会有同样的问题,未测试过

  • 无法获取到Camera对象
  • 获取到Camera对象,在设置录制质量等一系列数据时MediaRecorder.setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_LOW));时,捕获到空指针

  1. 无法获取到Camera对象(目标TV上只有一个摄像头,QQ在该TV上同样无法获取到摄像头)
    注意的地方: 通常我们获取Camera对象直接调用Camera.open()
        Camera c = null;
        try {
            c = Camera.open();
        } catch (Exception e) {
            LogUtils.e("camera", "Open Camera Failed", e);
        }

Camera类中提供给我们两个获取Camera对象的方法(无参或有参):

  /**
     * Creates a new Camera object to access the first back-facing camera on the
     * device. If the device does not have a back-facing camera, this returns
     * null.
     * @see #open(int)
     */
    public static Camera open() {
        int numberOfCameras = getNumberOfCameras();
        CameraInfo cameraInfo = new CameraInfo();
        for (int i = 0; i < numberOfCameras; i++) {
            getCameraInfo(i, cameraInfo);
            if (cameraInfo.facing == CameraInfo.CAMERA_FACING_BACK) {
                return new Camera(i);
            }
        }
        return null;
    }

注意到该方法的提示信息If the device does not have a back-facing camera, this returns null.,如果没有后置摄像头,那么返回值为 NULL,即我们并没有获取到Camera对象。只有一个摄像头时,系统并没有获取到cameraInfo.facingCamera.open()无参默认打开后置摄像头。讲到这里,你可能已经明白我没有获取到Camera对象的原因了...
接下来继续看一下,Camera.open(number)带参数的系统方法:

 /**
     * Creates a new Camera object to access a particular hardware camera. If
     * the same camera is opened by other applications, this will throw a
     * RuntimeException.
     *
     * <p>You must call {@link #release()} when you are done using the camera,
     * otherwise it will remain locked and be unavailable to other applications.
     *
     * <p>Your application should only have one Camera object active at a time
     * for a particular hardware camera.
     *
     * <p>Callbacks from other methods are delivered to the event loop of the
     * thread which called open().  If this thread has no event loop, then
     * callbacks are delivered to the main application event loop.  If there
     * is no main application event loop, callbacks are not delivered.
     *
     * <p class="caution"><b>Caution:</b> On some devices, this method may
     * take a long time to complete.  It is best to call this method from a
     * worker thread (possibly using {@link android.os.AsyncTask}) to avoid
     * blocking the main application UI thread.
     *
     * @param cameraId the hardware camera to access, between 0 and
     *     {@link #getNumberOfCameras()}-1.
     * @return a new Camera object, connected, locked and ready for use.
     * @throws RuntimeException if opening the camera fails (for example, if the
     *     camera is in use by another process or device policy manager has
     *     disabled the camera).
     * @see android.app.admin.DevicePolicyManager#getCameraDisabled(android.content.ComponentName)
     */
    public static Camera open(int cameraId) {
        return new Camera(cameraId);
    }

注意到该方法返回我们输入参数获取对应的Camera对象,项目中我是通过Camera.open(0)获取到Camera对象的。

  1. 程序运行到mediarecorder.setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_LOW));捕获到空指针异常。
    我们先来了解一下setProfile(getProfile())方法有什么作用:

百度上的解释 设置录制文件质量,格式,分辨率之类

Camcorder.get()方法和Camera.open()相似系统同样有两个重载方法

  • CamcorderProfile.get(int) 单参数
  • CamcorderProfile.get(int,int) 双参数

我们看一下系统中两个方法的定义:

   /**
     * Returns the camcorder profile for the first back-facing camera on the
     * device at the given quality level. If the device has no back-facing
     * camera, this returns null.
     * @param quality the target quality level for the camcorder profile
     * @see #get(int, int)
     */
    public static CamcorderProfile get(int quality) {
        int numberOfCameras = Camera.getNumberOfCameras();
        CameraInfo cameraInfo = new CameraInfo();
        for (int i = 0; i < numberOfCameras; i++) {
            Camera.getCameraInfo(i, cameraInfo);
            if (cameraInfo.facing == CameraInfo.CAMERA_FACING_BACK) {
                return get(i, quality);
            }
        }
        return null;
    }

**和Camera.open()一样,并没有返回要设置的内容,而是返回一个NULL,所以我们只能调用CamcorderProfile.get(int,int);来设置录制质量,看一下双参数的系统方法,如下: **

 /**
     * Returns the camcorder profile for the given camera at the given
     * quality level.
     *
     * A camcorder recording session with higher quality level usually has higher output
     * bit rate, better video and/or audio recording quality, larger video frame
     * resolution and higher audio sampling rate, etc, than those with lower quality
     * level.
     *
     * @param cameraId the id for the camera
     * @param quality the target quality level for the camcorder profile.
     * @see #QUALITY_LOW
    */
    public static CamcorderProfile get(int cameraId, int quality) {
        if (!((quality >= QUALITY_LIST_START &&
               quality <= QUALITY_LIST_END) ||
              (quality >= QUALITY_TIME_LAPSE_LIST_START &&
               quality <= QUALITY_TIME_LAPSE_LIST_END) ||
               (quality >= QUALITY_HIGH_SPEED_LIST_START &&
               quality <= QUALITY_HIGH_SPEED_LIST_END))) {
            String errMessage = "Unsupported quality level: " + quality;
            throw new IllegalArgumentException(errMessage);
        }
        return native_get_camcorder_profile(cameraId, quality);
    }

setProfile(CamcorderProfile)方法也可以看一下具体设置那些东西

 /**
     * Uses the settings from a CamcorderProfile object for recording. This method should
     * be called after the video AND audio sources are set, and before setOutputFile().
     * If a time lapse CamcorderProfile is used, audio related source or recording
     * parameters are ignored.
     *
     * @param profile the CamcorderProfile to use
     * @see android.media.CamcorderProfile
     */
    public void setProfile(CamcorderProfile profile) {
        setOutputFormat(profile.fileFormat);
        setVideoFrameRate(profile.videoFrameRate);
        setVideoSize(profile.videoFrameWidth, profile.videoFrameHeight);
        setVideoEncodingBitRate(profile.videoBitRate);
        setVideoEncoder(profile.videoCodec);
        if (profile.quality >= CamcorderProfile.QUALITY_TIME_LAPSE_LOW &&
             profile.quality <= CamcorderProfile.QUALITY_TIME_LAPSE_QVGA) {
            // Nothing needs to be done. Call to setCaptureRate() enables
            // time lapse video recording.
        } else {
            setAudioEncodingBitRate(profile.audioBitRate);
            setAudioChannels(profile.audioChannels);
            setAudioSamplingRate(profile.audioSampleRate);
            setAudioEncoder(profile.audioCodec);
        }
    }

相关文章

  • AndroidTV视频录制遇到的问题

    公司现在的项目是一个在AndroidTV上开发的,要添加一个新的需求,录制视频。记录一下在AndroidTV上开发...

  • iOS开发 视频压缩

    在我们开发中录制视频时都会遇到一个问题,当我们录制超高清视频的时候会发现录制的视频尺寸很大,寻求了网上各种解决方案...

  • potplayer录制视频带外挂字幕

    以前用potplayer录制视频总遇到一个小问题,就是只能单单保存视频,外挂字幕的视频字幕无法录制进去。现在这个问...

  • MediaRecorder报java.lang.IllegalS

    MediaRecorder + Camera2录制视频遇到这个问题,结果被坑了好久才找到原因,希望和我一样遇到的朋...

  • 教师录课必备技能

    如何录制课程视频?对于很多教师来说,录制课程视频是很多教师经常做的事情!如何录制课程视频?相信这个问题大家都有疑问...

  • Unity中,使用Recorder录制视频时,选择不同的Targ

    问题 Unity中,使用Recorder录制视频时,因为选择的帧率不同,导致录制的视频中的VideoPlayer播...

  • android TV盒子开发心得(一)

    今天给大家介绍一下本人在开发AndroidTV APP的时候所遇到的一些问题及心得体会,希望能帮助各位解决问题 首...

  • iOS录制视频的问题求助

    iOS上内置相机应用录制的mov/mp4视频竖屏拍照的时候产生一个Rotation元数据,表示录制视频时摄像头旋转...

  • jmeter录制遇到问题

    2018-09-04 录制时录制了很多很多的记录。点击stop后,还是在不停的增加。 有时会遇到录制为空的情况。 ...

  • 会声会影如何去除视频噪音

    相信大家都遇到过这样的问题,就是当录制了一段视频之后,想当作视频素材使用的时候,发现视频有一些杂音,不知道怎办去除...

网友评论

      本文标题:AndroidTV视频录制遇到的问题

      本文链接:https://www.haomeiwen.com/subject/klerottx.html