1. 程式人生 > >Android 自定義視訊錄製終極解決方案(翻轉問題)

Android 自定義視訊錄製終極解決方案(翻轉問題)

Android 自定義視訊錄製翻轉問題終極解決方案

  • 自定義視訊錄製
  • 使用系統可用播放器
  • 前後攝像和視訊反轉問題
  • 總結

自定義視訊錄製

mediarecorder = new MediaRecorder();// 建立mediarecorder物件
        mCamera = getCameraInstance(); // 獲取camera

        if (null == mCamera) {
            LogUtil.d("沒有攝像頭!");
            return;
        }
        mCamera.unlock();
mediarecorder.setCamera(mCamera); // 設定錄製視訊源為Camera(相機) mediarecorder.setAudioSource(MediaRecorder.AudioSource.MIC); mediarecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA); // 設定錄製檔案質量,格式,解析度之類,這個全部包括了 // //mediarecorder.setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY
_LOW)); //注意:這裡如果呼叫了setProfile這個方法的話, 再呼叫setOutputFormat();則會報錯。 看看setProfile的原始碼實現:

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

所以,一般本人不使用上面這個方法。

mediarecorder.setOutputFormat(MediaRecorder.OutputFormat.DEFAULT);

/ 設定錄製的視訊編碼h263 h264
        mediarecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
        mediarecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);

outPath = getOutMediaPath(); //造一個存放3gp檔案路徑
mediarecorder.setOutputFile(outPath);
mediarecorder.setPreviewDisplay(surfaceHolder.getSurface()); // 設定視訊檔案輸出的路徑
  try { // 準備錄製
      mediarecorder.prepare(); // 開始錄製
      mediarecorder.start();

  } catch (Exception e) {
      e.printStackTrace();
      e.getLocalizedMessage());
  }

此處省略了幾處的程式碼:
1.camera於surfaceview的關聯
2.生成視訊檔案存放路徑
3.獲取camera物件

使用系統可用播放器

以上講述自定義視訊錄製的程式碼邏輯,下面說說怎麼呼叫系統的播放器來播放你剛成功錄製下的視訊檔案。

Uri data = Uri.fromFile(mediaEntity);
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.putExtra("configchange", 0); //忽略頁面橫豎屏切換
intent.setDataAndType(data, "video/3gp");
startActivity(intent);

注意一個點:video/3gp mediaType可以傳video/* 或者具體的型別。
但是有一個小區別了。
像樓主設定的video/3gp 啟動的時候會調用出系統中可以用來播放的播放器來提供選擇,如UC播放器,愛奇藝播放器等。
如果設定的是video/* 則會直接呼叫系統的播放器播放。

前後攝像和視訊反轉問題

這裡也是最煩人的地方, 網上的解決方案魚龍混雜, 試了好多。
貼下幾種看到的解決方案:
1.設定 mCamera.set(“rotation”,90); 試過,不行。
2.設定mCamera.setDisplayOrientation(90); 然並卵//

下面說下本人的解決方案:

mCamera.setDisplayOrientation(90); 這句必須要的。
第二:
2.1豎屏情況下:
如果是前置攝像頭:
mediaRecorder.setOrientationHint(270);
如果是後置攝像頭:
mediaRecorder.setOrientationHint(90);
2.2橫情況下:
如果是前置攝像頭:
mediaRecorder.setOrientationHint(180);
如果是後置攝像頭:
mediaRecorder.setOrientationHint(0);
看了下原始碼解釋:

/**
     * Sets the orientation hint for output video playback.
     * This method should be called before prepare(). This method will not
     * trigger the source video frame to rotate during video recording, but to
     * add a composition matrix containing the rotation angle in the output
     * video if the output format is OutputFormat.THREE_GPP or
     * OutputFormat.MPEG_4 so that a video player can choose the proper
     * orientation for playback. Note that some video players may choose
     * to ignore the compostion matrix in a video during playback.
     *
     * @param degrees the angle to be rotated clockwise in degrees.
     * The supported angles are 0, 90, 180, and 270 degrees.
     * @throws IllegalArgumentException if the angle is not supported.
     *
     */
    public void setOrientationHint(int degrees) {
        if (degrees != 0   &&
            degrees != 90  &&
            degrees != 180 &&
            degrees != 270) {
            throw new IllegalArgumentException("Unsupported angle: " + degrees);
        }
        setParameter("video-param-rotation-angle-degrees=" + degrees);
    }

大概的意思的設定視訊檔案生成的翻轉角度。那麼前面那個
mCamera.setDisplayOrientation(90);應該就是攝像頭翻轉的角度。
可能有的人有點繞, 轉來轉去頭暈暈的。樓主找了個帖子描述相機拍照成像原理,方便大家理解。傳送門:
相機成像原理

總結

主要也是相機裝置的成像原理沒搞清楚。說實在,現在搞懂了也不太記得住。反正這問題也是困了我好幾天了, 看了很多帖子也是被繞進去了, 各種不行,就是斜的, 要麼左邊斜,要麼右邊斜,來來回回反正正反面又不一樣。兩種成像原理。終於搞定了, 記錄一下。希望對看官有幫助, thks 你的閱讀,祝生活愉快!!