AndroidTV視頻錄制遇到的問題

公司現(xiàn)在的項(xiàng)目是一個(gè)在AndroidTV上開發(fā)的励负,要添加一個(gè)新的需求谨究,錄制視頻昔案。記錄一下在AndroidTV上開發(fā)錄制視頻時(shí)遇到的小問題:

注: 對(duì)于只有一個(gè)攝像頭的手機(jī)可能會(huì)有同樣的問題瓤荔,未測(cè)試過

  • 無法獲取到Camera對(duì)象
  • 獲取到Camera對(duì)象,在設(shè)置錄制質(zhì)量等一系列數(shù)據(jù)時(shí)MediaRecorder.setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_LOW));時(shí)梅惯,捕獲到空指針

  1. 無法獲取到Camera對(duì)象(目標(biāo)TV上只有一個(gè)攝像頭,QQ在該TV上同樣無法獲取到攝像頭)
    注意的地方: 通常我們獲取Camera對(duì)象直接調(diào)用Camera.open()
        Camera c = null;
        try {
            c = Camera.open();
        } catch (Exception e) {
            LogUtils.e("camera", "Open Camera Failed", e);
        }

Camera類中提供給我們兩個(gè)獲取Camera對(duì)象的方法(無參或有參):

  /**
     * 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對(duì)象脚作。只有一個(gè)攝像頭時(shí),系統(tǒng)并沒有獲取到cameraInfo.facing缔刹,Camera.open()無參默認(rèn)打開后置攝像頭球涛。講到這里,你可能已經(jīng)明白我沒有獲取到Camera對(duì)象的原因了...
接下來繼續(xù)看一下校镐,Camera.open(number)帶參數(shù)的系統(tǒng)方法:

 /**
     * 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);
    }

注意到該方法返回我們輸入?yún)?shù)獲取對(duì)應(yīng)的Camera對(duì)象亿扁,項(xiàng)目中我是通過Camera.open(0)獲取到Camera對(duì)象的。

  1. 程序運(yùn)行到mediarecorder.setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_LOW));捕獲到空指針異常鸟廓。
    我們先來了解一下setProfile(getProfile())方法有什么作用:

百度上的解釋 設(shè)置錄制文件質(zhì)量从祝,格式,分辨率之類

Camcorder.get()方法和Camera.open()相似系統(tǒng)同樣有兩個(gè)重載方法

  • CamcorderProfile.get(int) 單參數(shù)
  • CamcorderProfile.get(int,int) 雙參數(shù)

我們看一下系統(tǒng)中兩個(gè)方法的定義:

   /**
     * 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()一樣引谜,并沒有返回要設(shè)置的內(nèi)容牍陌,而是返回一個(gè)NULL,所以我們只能調(diào)用CamcorderProfile.get(int,int);來設(shè)置錄制質(zhì)量员咽,看一下雙參數(shù)的系統(tǒng)方法毒涧,如下: **

 /**
     * 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)方法也可以看一下具體設(shè)置那些東西

 /**
     * 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);
        }
    }
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市贝室,隨后出現(xiàn)的幾起案子契讲,更是在濱河造成了極大的恐慌,老刑警劉巖滑频,帶你破解...
    沈念sama閱讀 211,561評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件捡偏,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡峡迷,警方通過查閱死者的電腦和手機(jī)霹琼,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,218評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來凉当,“玉大人枣申,你說我怎么就攤上這事】春迹” “怎么了忠藤?”我有些...
    開封第一講書人閱讀 157,162評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長楼雹。 經(jīng)常有香客問我模孩,道長尖阔,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,470評(píng)論 1 283
  • 正文 為了忘掉前任榨咐,我火速辦了婚禮介却,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘块茁。我一直安慰自己齿坷,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,550評(píng)論 6 385
  • 文/花漫 我一把揭開白布数焊。 她就那樣靜靜地躺著永淌,像睡著了一般。 火紅的嫁衣襯著肌膚如雪佩耳。 梳的紋絲不亂的頭發(fā)上遂蛀,一...
    開封第一講書人閱讀 49,806評(píng)論 1 290
  • 那天,我揣著相機(jī)與錄音干厚,去河邊找鬼李滴。 笑死,一個(gè)胖子當(dāng)著我的面吹牛蛮瞄,可吹牛的內(nèi)容都是我干的悬嗓。 我是一名探鬼主播,決...
    沈念sama閱讀 38,951評(píng)論 3 407
  • 文/蒼蘭香墨 我猛地睜開眼裕坊,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼包竹!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起籍凝,我...
    開封第一講書人閱讀 37,712評(píng)論 0 266
  • 序言:老撾萬榮一對(duì)情侶失蹤周瞎,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后饵蒂,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體声诸,經(jīng)...
    沈念sama閱讀 44,166評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,510評(píng)論 2 327
  • 正文 我和宋清朗相戀三年退盯,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了彼乌。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,643評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡渊迁,死狀恐怖慰照,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情琉朽,我是刑警寧澤毒租,帶...
    沈念sama閱讀 34,306評(píng)論 4 330
  • 正文 年R本政府宣布,位于F島的核電站箱叁,受9級(jí)特大地震影響墅垮,放射性物質(zhì)發(fā)生泄漏惕医。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,930評(píng)論 3 313
  • 文/蒙蒙 一算色、第九天 我趴在偏房一處隱蔽的房頂上張望抬伺。 院中可真熱鬧,春花似錦灾梦、人聲如沸峡钓。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,745評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至给郊,卻和暖如春牡肉,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背淆九。 一陣腳步聲響...
    開封第一講書人閱讀 31,983評(píng)論 1 266
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人砂豌。 一個(gè)月前我還...
    沈念sama閱讀 46,351評(píng)論 2 360
  • 正文 我出身青樓泵肄,卻偏偏與公主長得像,于是被迫代替她去往敵國和親焕蹄。 傳聞我的和親對(duì)象是個(gè)殘疾皇子逾雄,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,509評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容