28

我试图允许用户录制与他们在录制时可以看到的实际屏幕预览不同大小的视频。这似乎可以从有关以下功能的getSupportedVideoSizes功能的文档中获得:

如果返回的列表不为空,则返回的列表将包含至少一个 Size,并且如果使用相机作为视频源,则返回列表中的其中一个尺寸必须传递给 MediaRecorder.setVideoSize() 用于摄像机应用程序。在这种情况下,预览的大小可能与视频录制期间录制的视频的分辨率不同。

这表明某些手机会从此 fn 返回 null(根据我的经验 Galaxy SIII 会),但对于那些不这样做的人,可以提供与实际视频不同分辨率的预览。这种理解正确吗?有些手机允许这种行为而其他手机不允许吗?

尝试解决方案:

漫长的录像设置过程中使用的该功能的官方说明中setPreviewDisplay提到:

如果此方法以空表面调用或根本不调用,媒体记录器将不会更改相机的预览表面。

这似乎是我想要的,但不幸的是,如果我这样做,整个视频录制过程就完全搞砸了。我假设在录制视频的过程中,这个函数不能传递 null 或根本不调用。也许在其他情况下这是可以的。不幸的是,这似乎对我没有帮助。

我接下来的唯一步骤是查看TextureViews 并使用预览纹理而不是典型的 SurfaceView 实现,以便使用 openGL 将纹理拉伸到与实际分辨率不同的所需大小(并裁剪屏幕上多余的部分) ,然后用 SurfacesetPreviewDisplay的构造函数为函数Surface(SurfaceTexture surfaceTexture)构造一个 Surface。由于在 ICS 下不兼容,我想避免使用 a TextureView,因为这会增加显着的复杂性。

这似乎是一个微妙的过程,但我希望有人可以在这方面提供一些建议。

谢谢你。

4

3 回答 3

2

a.假设用户将x,y的大小设置为视频大小

b.现在使用 getSupportedVideoSizes 函数获取整个列表并查看 x,y 是否属于其中之一并设置 MediaRecorder.setVideoSize()。如果 x,y 不属于 getSupportedVideoSizes 列表,则设置视频的默认配置文件记录。

这是关于视频大小

现在来到预览大小,没有太多的解决方法选项。取一个保存 SurfaceView 的 RelativeLayout。

<android.view.SurfaceView xmlns:android="http://schemas.android.com/apk/res/android"
 android:id="@+id/preview"
 android:layout_width="fill_parent"
 android:layout_height="fill_parent"
 />

preview 是 SurfaceView 的名称。在这里,我给出了一个将其重新调整为宽度和高度一半的示例。

resetCamera();  //reset the camera   

ViewGroup.LayoutParams params = preview.getLayoutParams();
RelativeLayout myRelLayout = (RelativeLayout) findViewById(R.id.myRelLayout);
params.width = (int) (myRelLayout.getWidth()/2);
params.height = (int)(myRelLayout.getHeight()/2);
preview.setLayoutParams(params);

initCamera(); //initiate the camera(open camera, set parameter, setPreviewDisplay,startPreview)

请查看预览的分辨率,然后根据视频大小相应地缩小高度或宽度。

希望能帮助到你。

于 2013-02-06T11:23:34.913 回答
1

正如您所提到的,这只有在 getSupportedVideoSizes() 返回非空列表时才有可能。

但是,如果您确实看到了一个非空列表,那么这个简单的方法应该可以工作:

  1. 使用setPreviewSize设置所需的预览分辨率;您选择的尺寸必须是getSupportedPreviewSizes给定的尺寸之一。

  2. 分别使用setPreviewDisplaysetPreviewTexture将预览显示设置为 SurfaceView 或 SurfaceTexture 。

  3. 开始预览。

  4. 创建媒体记录器,并使用getSupportedVideoSizes中的一种尺寸直接使用setVideoSize设置其视频大小,或者使用预定义的摄像机配置文件之一为给定的质量/大小配置所有媒体记录器设置。

  5. 将相机对象传递给 MediaRecorder 的setCamera调用,配置媒体记录器的其余部分,然后开始录制。

在具有非空 getSupportedVideoSizes 列表的设备上,这应该会导致预览保持在 setPreviewSize 调用设置的分辨率,并以设置的视频大小/摄像机配置文件分辨率进行录制。在不支持视频大小的设备上,MediaRecorder 将重置预览大小以匹配录制大小。您应该能够通过设置非常低的预览分辨率和高录制分辨率(例如,160x120 用于预览,720p 用于录制)来测试这一点。如果 MediaRecorder 在录制开始时将预览分辨率切换到 720p,这应该很明显,因为预览质量会大幅提升。

注意预览尺寸不直接与显示SurfaceView的尺寸挂钩;相机预览的输出将被缩放以适应 SurfaceView,因此如果您的 SurfaceView 的尺寸由于您的布局和设备而为 100x100 像素,那么无论您使用的预览分辨率如何,都将被缩放为 100x100 以进行显示。所以你仍然需要确保保持 SurfaceView 的纵横比正确,这样预览才不会失真。

并且为了能效,您不应该使用远高于 SurfaceView 中实际像素数的预览分辨率,因为在将预览拟合到 SurfaceView 时会丢失额外的分辨率。当然,只有当 getSupportedVideoSizes() 返回非空值时才可能进行录制。

于 2013-02-06T20:28:39.317 回答
0

首先,我将尝试回答您的具体问题。

  1. 可以提供与实际视频不同分辨率的预览。这种理解正确吗?

是的,预览大小通常与录制大小不同。预览尺寸通常与您的显示尺寸无关。因此,如果手机显示 CIF (352 x 288),但能够录制 D1 (720 x 480),则预览大小和录制大小会有所不同。我觉得其他专家在这一点上已经给出了充分的回答。

  1. 有些手机允许这种行为而其他手机不允许吗?

大多数最新款手机都支持此功能,可能只有少数低端手机。

除了setPreviewDisplay,我们还必须考虑这一点:

一个例外是,如果在调用 startPreview() 之前未设置预览表面(或设置为 null),则可以使用非 null 参数调用此方法一次以设置预览表面。(这允许相机设置和表面创建并行进行,从而节省时间。)预览表面可能不会在预览运行时更改。

您能否分享一下您在setPreviewDisplay使用表面调用时面临的问题NULL

于 2013-02-10T13:39:26.203 回答