在Android中调整表面视图大小以适应视频显示的纵横比变化

14

我正在开发一个视频会议项目。我的视频显示使用表面视图(surface view)。在视频通话期间,传入帧的宽高比可能会发生变化。因此我尝试了以下代码来处理它。

public void surfaceResize() {

   // WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
    Point size = new Point();
    int screenWidth = 0;
    //Get the SurfaceView layout parameters

    float aspectRatio = (float) recv_frame_width / recv_frame_height;

    if(getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) 
    {   
        //Get the width of the screen
        getWindowManager().getDefaultDisplay().getSize(size);
        screenWidth = size.x;

        //Set the width of the SurfaceView to the width of the screen
        surflp.width = screenWidth;

        //Set the height of the SurfaceView to match the aspect ratio of the video 
        //be sure to cast these as floats otherwise the calculation will likely be 0
        surflp.height = (int) ((1 / aspectRatio) * (float)screenWidth);

        //Commit the layout parameters

    } else {

        size.x = size.y = 0;
        //Get the width of the screen
        getWindowManager().getDefaultDisplay().getSize(size);

        int screenHeight = size.y;

        //Set the width of the SurfaceView to the width of the screen
        surflp.height = screenHeight;

        //Set the width of the SurfaceView to match the aspect ratio of the video 
        //be sure to cast these as floats otherwise the calculation will likely be 0
        surflp.width = (int) ( aspectRatio * (float)screenHeight);

        //Commit the layout parameters
        // code to do for Portrait Mode        
    }
    surflp.addRule(RelativeLayout.CENTER_HORIZONTAL);
    surflp.addRule(RelativeLayout.CENTER_VERTICAL);

    if(myVideoSurfaceView != null) 
        myVideoSurfaceView.setLayoutParams(surflp);  
    System.out.println("Surface resized*****************************************");
}
如果我在调用的开始处调用此函数,一切都很好。 我的问题是,当我在调用更改纵横比的过程中调用此函数时,显示下一帧需要太长时间。有时甚至会卡住视频。
我尝试使用销毁并重新创建表面来解决问题。
myVideoSurface.setVisibility(VIEW.GONE);

但表面没有被创建。

我正在使用Mediacodec进行视频解码,当分辨率发生更改时将收到通知。

如果已经播放视频,那么调整SurfaceView的大小是否需要做其他处理?

感谢帮助……


如果您的问题已经解决,请接受一个答案。这样您的问题就不会出现在“未回答”的列表中了。 - Alexander Malakhov
这里有一个很好的解决方案 - Folyd
2个回答

32

你好,请尝试以下代码:

private void setVideoSize() {

            // // Get the dimensions of the video
            int videoWidth = mediaPlayer.getVideoWidth();
            int videoHeight = mediaPlayer.getVideoHeight();
            float videoProportion = (float) videoWidth / (float) videoHeight;

            // Get the width of the screen
            int screenWidth = getWindowManager().getDefaultDisplay().getWidth();
            int screenHeight = getWindowManager().getDefaultDisplay().getHeight();
            float screenProportion = (float) screenWidth / (float) screenHeight;

            // Get the SurfaceView layout parameters
            android.view.ViewGroup.LayoutParams lp = surfaceView.getLayoutParams();
            if (videoProportion > screenProportion) {
                lp.width = screenWidth;
                lp.height = (int) ((float) screenWidth / videoProportion);
            } else {
                lp.width = (int) (videoProportion * (float) screenHeight);
                lp.height = screenHeight;
            }
            // Commit the layout parameters
            surfaceView.setLayoutParams(lp);
        }

感谢kyogs的快速回复。但我也做了类似的事情,recv_frame_width和recv_frame_height是当前帧的高度和宽度。我想知道是否需要对surfaceView进行其他更改,因为视频已经在播放中。 - Kevin K
从表面上看,您可以获取视频的高度和宽度。 - kyogs
@kyogs 是的,我知道,但即使没有它,我也有新的宽度和高度以及纵横比。但问题在于当我尝试调整我的SurfaceView大小时,这需要太长时间,有时视频会卡住。 - Kevin K
myVideoSurfaceView.setLayoutParams(surflp); 这行代码抛出了一些异常... - Kevin K
2
你必须从 UI 线程发起修改 View 的调用。你可以使用 Handler 来“转发”这个调用。例如,参见 https://developer.android.com/training/multiple-threads/communicate-ui.html。 - fadden
显示剩余6条评论

3

此处输入图片描述 可以通过以下方法解决这个问题。


9
你应该将其打出来供“复制粘贴大军”使用 :P - Sahith Vibudhi
1
@SahithVibudhi 和为了易于访问性 - Myzel394

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接