【问题标题】:how do i set android camera view port always landscape?如何设置 android 相机视图端口始终为横向?
【发布时间】:2014-08-01 12:04:58
【问题描述】:

我必须解决 android 硬件摄像头的问题。我希望我的设备始终录制横向视频,即使它的方向是垂直的。我画了一些图片来支持我的问题:

这是我得到的: http://joxi.ru/9IHbU_3JTJDrRyVH-XA

这就是我想要的: http://joxi.ru/IYLbU4wyTJC1LhQcd4Q

我不能说它甚至可能(我认为不可能,因为硬件矩阵不能旋转)。但我的客户认为是。请判断我们。

更新:这是我的代码。

//..import...
public class MainActivity extends Activity {

SurfaceView surfaceView;
Camera camera;
MediaRecorder mediaRecorder;
//...public and private variables...

@Override
protected void onCreate(Bundle savedInstanceState) {
//......
    SurfaceHolder holder = surfaceView.getHolder();
    holder.addCallback(new SurfaceHolder.Callback() {
    @Override
    public void surfaceCreated(SurfaceHolder holder) {
            try {
                 camera.setPreviewDisplay(holder);
                 setCameraDisplayOrientation(CAM_ID);

                 camera.startPreview();
             } catch (Exception e) {
                 e.printStackTrace();
             }
         }

         @Override
         public void surfaceChanged(SurfaceHolder holder, int format,
                 int width, int height) {
         }

        @Override
         public void surfaceDestroyed(SurfaceHolder holder) {
         }
    });
}

@Override
protected void onResume() {
    super.onResume();
    camera = Camera.open(this.CAM_ID);
 }

@Override
protected void onPause() {
    super.onPause();
    releaseMediaRecorder();
    if (camera != null)
        camera.release();
    camera = null;
}

public void setListeners() {/*....*/}
public void onClickStartRecord(View view) {
    if (prepareVideoRecorder()) {
        mediaRecorder.start();
    } else releaseMediaRecorder();
}

public void onClickStopRecord(View view) {
    if (mediaRecorder != null) {
        mediaRecorder.stop();
        releaseMediaRecorder();
    }
}

private boolean prepareVideoRecorder() {

    camera.unlock();

    mediaRecorder = new MediaRecorder();

    mediaRecorder.setCamera(camera);
    mediaRecorder.setAudioSource(MediaRecorder.AudioSource.DEFAULT);
    mediaRecorder.setVideoSource(MediaRecorder.VideoSource.DEFAULT);

    CamcorderProfile profile = CamcorderProfile.get(this.CAM_ID, CamcorderProfile.QUALITY_LOW);
    mediaRecorder.setProfile(profile);
    if(this.orientation == 270 || this.orientation == 90 )
        mediaRecorder.setOrientationHint(90);

    mediaRecorder.setOutputFile(videoFile.getAbsolutePath());
    mediaRecorder.setPreviewDisplay(surfaceView.getHolder().getSurface());

    try {
        mediaRecorder.prepare();
    } catch (Exception e) {
        e.printStackTrace();
        releaseMediaRecorder();
        return false;
    }
    return true;
}

private void releaseMediaRecorder() {
    if (mediaRecorder != null) {
        mediaRecorder.reset();
        mediaRecorder.release();
        mediaRecorder = null;
        camera.lock();
    }
}

private void setCameraDisplayOrientation(int cameraId) {
    // определяем насколько повернут экран от нормального положения
    int rotation = getWindowManager().getDefaultDisplay().getRotation();
    int degrees = 0;
    switch (rotation) {
    case Surface.ROTATION_0:
        degrees = 0;
        break;
    case Surface.ROTATION_90:
        degrees = 90;
        break;
    case Surface.ROTATION_180:
        degrees = 180;
        break;
    case Surface.ROTATION_270:
        degrees = 270;
        break;
    }

    int result = 0;

    CameraInfo info = new CameraInfo();
    Camera.getCameraInfo(cameraId, info);

    if (info.facing == CameraInfo.CAMERA_FACING_BACK) {
        result = ((360 - degrees) + info.orientation);
    } else
    if (info.facing == CameraInfo.CAMERA_FACING_FRONT) {
        result = ((360 - degrees) - info.orientation);
        result += 360;
    }
    result = result % 360;
    camera.setDisplayOrientation(result);

    this.orientation = result;
}

}

【问题讨论】:

  • 您是否通过意图启动了 cam?
  • SilentKiller,恐怕我没有太多尝试。我可以使用 mediaRecorder.setOrientationHint 和 camera.setDisplayOrientation 方法设置视频录制方向。但这些都不能解决我的问题。我真的认为当我的设计是垂直方向时,硬件不允许录制横向视频。但我不得不问:)
  • Rob,我认为不是。所有这些主题都围绕视频和照片方向,但矩阵方向总是类似于设备(以我的拙见)。换句话说,我可以设置纵向或横向模式,但是当我的设备垂直时我无法录制宽视频,我只能录制窄视频。
  • 我不确定这不可能。你能发布一些代码吗?

标签: android android-camera orientation


【解决方案1】:

我相信很容易实现您的客户想要的。因此,您将设备置于纵向模式,并以 1280x720 的分辨率录制视频。显然,它是面向纵向的:720 是宽度,1280 是高度(请注意,编码的帧可能仍然是 1280 宽度和 720 高度,但是视频具有特殊的旋转标志,因此兼容的解码器将以正确的方向显示输出)。

现在,裁剪视频,使结果为 406x720(是的,这样会丢失很多像素)。但结果将具有所需的横向方向。 406 是高度,720 是宽度。

现在是技术细节:您可以在实时或录制后进行裁剪。在后一种情况下,您可以在服务器或设备上运行ffmpeg

在前一种情况下,您必须接收相机回调,裁剪到达的数据,并将其传递给编码器。您可以使用现代 MediaCodec API 完全在 Java 中完成。如果您选择编写一些原生代码,您可以使用ffmpeg 库来执行必要的操作。

您甚至可以调整生成的帧的大小,以便视频解码器以 1280x720 的分辨率播放 406x720 的原件。质量永远不会像原始(人像)视频。

为什么我要谈论奇怪的 406 高度?保持标准的纵横比。如果可以使用 4:3 的纵横比,则可以选择 540x720。

【讨论】:

  • 谢谢,亚历克斯。我所有的研究都让我得出结论,裁剪是做他想做的唯一正确的方法。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多