
(資料圖)
我們在做Android平臺gb28181設備接入模塊的時候,遇到這樣的情況,比如橫豎屏分辨率不鎖定,采集攝像頭的時候,可以實現,橫屏狀態采集橫屏,豎屏狀態采集豎屏,簡單來說,橫屏狀態比如采集的1280*720的,豎屏狀態,采集的數據源成了720*1280。
這塊對我們來說,已經輕車熟路了,老早就已經處理,分辨率發生變化的時候,會重啟encoder,確保正常兼容,不幸的是,好多gb28181平臺側,對分辨率切換,支持的并不友好,分辨率發生變化的時候,有些國標平臺播放上來的視頻流的時候,會直接crash。
分辨率變化,其實多數國標平臺廠商都可以兼容,或者說應該兼容,如果國標平臺側不兼容的話,我們可以在android平臺gb28181設備接入側做一定的處理。
以Android的camera2為例,我們做了“鎖定圖像方向”選項:
對應的代碼實現如下:
class ButtonCameraImageOrientationLockListener implements View.OnClickListener { public void onClick(View v) { is_need_lock_image_orientation_ = !is_need_lock_image_orientation_; if (cur_image_orientation_ >= 0) cur_image_orientation_ = orientation_; if(camera2Helper != null) cameraImageRotationDegree_ = camera2Helper.getCameraImageRotationDegree(cur_image_orientation_ < 0 ?orientation_ : cur_image_orientation_); btnCameraImageOrientationLock.setText(is_need_lock_image_orientation_?"解鎖圖像方向" : "鎖定圖像方向"); } }
其中,getCameraImageRotationDegree實現如下:
public int getCameraImageRotationDegree(int device_degree) { if (device_degree < 0) return -1; String camera_id = getCameraId(); int degree; if (CAMERA_ID_BACK.equals(camera_id)) { degree = (mSensorOrientation + device_degree + 360) % 360; Log.i(TAG, "getCameraImageRotationDegree BACK device_degree:" + device_degree + " SENSOR_ORIENTATION:" + mSensorOrientation + " degree:" + degree); } else { degree = (mSensorOrientation - device_degree + 360) % 360; Log.i(TAG, "getCameraImageRotationDegree FRONT device_degree:" + device_degree + " SENSOR_ORIENTATION:" + mSensorOrientation + " degree:" + degree); } return degree; }
針對攝像頭rotation變化監測listener:
/* * Github: https://github.com/daniulive/SmarterStreaming */ class OnOriChangedListener implements OrientationDetector.OriginListener { @Override public void onOrientationChanged(int orientation, int rotation) { orientation_ = orientation; if (!is_need_lock_image_orientation_ || cur_image_orientation_ < 0) cur_image_orientation_ = orientation_; Log.i(TAG, "onOrientationChanged:" + orientation + " rotation:" + rotation + " rotation.toString:" + Camera2Helper.getRotationString(rotation)); if(camera2Helper != null) { camera2Helper.updateOrientation(orientation); cameraImageRotationDegree_ = camera2Helper.getCameraImageRotationDegree(cur_image_orientation_ < 0 ?orientation_ : cur_image_orientation_); } if (layer_post_thread_ != null ) { int rotation_degree = cameraImageRotationDegree_; if (rotation_degree < 0) layer_post_thread_.updateVideoSize(0, 0); else if (90 == rotation_degree || 270 == rotation_degree) layer_post_thread_.updateVideoSize(video_height_, video_width_); else layer_post_thread_.updateVideoSize(video_width_, video_height_); } } }
值得一提的是,如果視頻分辨率發生變化,本地錄像的話,一般來說會切換新的錄像文件,國標平臺側如果做的比較好的話,一般都會兼容這種分辨率變化的場景,起碼確保分辨率切換的時候,不至于直接crash。
實際上,比如一些執法記錄儀等場景下,只需要一個固定的采集方向即可,這種情況下,鎖定方向,反而是最好的。