Java 不拉伸视频的全屏视频视图

Java 不拉伸视频的全屏视频视图,java,android,fullscreen,android-videoview,Java,Android,Fullscreen,Android Videoview,我想知道我是否能找到一种方法让视频通过videoview全屏运行 我搜索了很多,尝试了很多方法,比如: 在清单中应用主题: android:theme="@android:style/Theme.NoTitleBar.Fullscreen" 但这并不强制视频全屏显示 应用于活动本身: requestWindowFeature(Window.FEATURE_NO_TITLE); getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULL

我想知道我是否能找到一种方法让视频通过videoview全屏运行

我搜索了很多,尝试了很多方法,比如:

  • 在清单中应用主题:

    android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
    
    但这并不强制视频全屏显示

  • 应用于活动本身:

    requestWindowFeature(Window.FEATURE_NO_TITLE);  
    getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,  
        WindowManager.LayoutParams.FLAG_FULLSCREEN);
    
    也不会强制视频全屏显示

  • 强制视频全屏显示的唯一方法是:

    <VideoView android:id="@+id/myvideoview"
        android:layout_width="fill_parent"
        android:layout_alignParentRight="true"
        android:layout_alignParentLeft="true" 
        android:layout_alignParentTop="true" 
        android:layout_alignParentBottom="true" 
        android:layout_height="fill_parent"> 
    </VideoView> 
    
    main.xml:

    public class Video extends Activity {
        private VideoView myvid;
    
        @Override
        public void onCreate(Bundle icicle) {
            super.onCreate(icicle);
            setContentView(R.layout.main);
            myvid = (VideoView) findViewById(R.id.myvideoview);
            myvid.setVideoURI(Uri.parse("android.resource://" + getPackageName() 
                +"/"+R.raw.video_1));
            myvid.setMediaController(new MediaController(this));
            myvid.requestFocus();
            myvid.start();
        }
    }
    
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:orientation="vertical" >
    
        <VideoView
            android:id="@+id/myvideoview"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent" />
    
    </LinearLayout>
    
    
    
    @覆盖
    创建时的公共void(Bundle savedInstanceState){
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    videoView1=(VideoView)findviewbyd(R.id.VideoView);
    字符串SrcPath=“/mnt/sdcard/final.mp4”;
    videoView1.setVideoPath(SrcPath);
    videoView1.setMediaController(新MediaController(本));
    videoView1.requestFocus();
    videoView1.start();
    }
    }
    

    试试这个,它对我有效

    表面视图为你提供了一个优化的绘图表面

    public class YourMovieActivity extends Activity implements SurfaceHolder.Callback {
            private MediaPlayer media = null;
            //...
    
            @Override
            public void onCreate(Bundle savedInstanceState) {
                super.onCreate(savedInstanceState);
    
                media = new MediaPlayer();
                mSurfaceView = (SurfaceView) findViewById(R.id.surface);
                //...
            }
        }
    
    MediaPlayer调用应包装在try{}中

        @Override
        public void surfaceCreated(SurfaceHolder holder) {
    
            media.setDataSource("android.resource://" + getPackageName() 
                +"/"+R.raw.video_);
            media.prepare();
    
                int videoWidth = mp.getVideoWidth();
            int videoHeight = mp.getVideoHeight();
    
                int screenWidth = getWindowManager().getDefaultDisplay().getWidth();
    
                android.view.
    
    ViewGroup.LayoutParams layout = mSurfaceView.getLayoutParams();
    
        layout.width = screenWidth;
    
        layout.height = (int) (((float)videoHeight / (float)videoWidth) * (float)screenWidth);
    
        mSurfaceView.setLayoutParams(layout);        
    
        mp.start();
    }
    

    您是否尝试过调整下垫面固定器的大小?尝试下面的代码,它应该将表面支架调整为与屏幕大小相同的宽度和高度。你仍然应该让你的活动是全屏的,没有标题栏

        public class Video extends Activity {
            private VideoView myvid;
    
            @Override
            public void onCreate(Bundle icicle) {
                super.onCreate(icicle);
                setContentView(R.layout.main);
                myvid = (VideoView) findViewById(R.id.myvideoview);
                myvid.setVideoURI(Uri.parse("android.resource://" + getPackageName() 
                    +"/"+R.raw.video_1));
                myvid.setMediaController(new MediaController(this));
                myvid.requestFocus();
    
                //Set the surface holder height to the screen dimensions
                Display display = getWindowManager().getDefaultDisplay();
                Point size = new Point();
                display.getSize(size);
                myvid.getHolder().setFixedSize(size.x, size.y);
    
                myvid.start();
            }
        }
    

    像这样,你可以自己设置视频的属性

    使用SurfaceView(提供对视图的更多控制),将其设置为“填充父视图”,以匹配整个屏幕

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"     
                  android:orientation="vertical" 
                  android:layout_width="match_parent"
                  android:layout_height="fill_parent">
    
        <SurfaceView
            android:id="@+id/surfaceViewFrame"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:layout_gravity="center" >
        </SurfaceView>
    </Linearlayout>
    
    在媒体播放器上设置onPreparedListener并手动计算所需的视频大小,以按所需比例填充屏幕,避免拉伸视频

    player.setOnPreparedListener(new OnPreparedListener() {
    
            @Override
            public void onPrepared(MediaPlayer mp) {
                        // Adjust the size of the video
        // so it fits on the screen
        int videoWidth = player.getVideoWidth();
        int videoHeight = player.getVideoHeight();
        float videoProportion = (float) videoWidth / (float) videoHeight;       
        int screenWidth = getWindowManager().getDefaultDisplay().getWidth();
        int screenHeight = getWindowManager().getDefaultDisplay().getHeight();
        float screenProportion = (float) screenWidth / (float) screenHeight;
        android.view.ViewGroup.LayoutParams lp = surfaceViewFrame.getLayoutParams();
    
        if (videoProportion > screenProportion) {
            lp.width = screenWidth;
            lp.height = (int) ((float) screenWidth / videoProportion);
        } else {
            lp.width = (int) (videoProportion * (float) screenHeight);
            lp.height = screenHeight;
        }
        surfaceViewFrame.setLayoutParams(lp);
    
        if (!player.isPlaying()) {
            player.start();         
        }
    
            }
        });
    
    我修改了这个视频流教程,我遵循了一些时间,现在找不到它来参考它,如果有人这样做,请添加链接到答案

    希望有帮助

    编辑

    好的,所以,如果你想让视频占据整个屏幕,而你又不想让它拉伸,那么你会在侧面留下黑色条纹。在我发布的代码中,我们找到了更大的屏幕,视频或手机屏幕,并尽我们所能安装它

    这里有我完整的活动,从链接流式传输视频。这是100%的功能。我不能告诉你如何从你自己的设备播放视频,因为我不知道。我相信您会在文档或文档中找到它


    我通过自定义视频视图解决了这个问题:

    <FrameLayout
       android:id="@+id/secondMedia"
       android:layout_width="match_parent"
       android:layout_height="match_parent">
    
         <com.my.package.customview.FullScreenVideoView
               android:layout_width="match_parent"
               android:layout_height="match_parent" 
               android:id="@+id/fullScreenVideoView"/>
    
    </FrameLayout>
    
    FullScreenVideoView videoView = new FullScreenVideoView(getActivity());
    parentLayout.addView(videoView, new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.MATCH_PARENT));
    
    我通过两种方式从xml向ParentView添加了VideoView&编程方式

    为名为FullScreenVideoView.java的VideoView添加自定义类:

    import android.content.Context;
    import android.util.AttributeSet;
    import android.widget.VideoView;
    
    public class FullScreenVideoView extends VideoView {
        public FullScreenVideoView(Context context) {
            super(context);
        }
    
        public FullScreenVideoView(Context context, AttributeSet attrs) {
            super(context, attrs);
        }
    
        public FullScreenVideoView(Context context, AttributeSet attrs, int defStyle) {
            super(context, attrs, defStyle);
        }
    
        @Override
        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec){
            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
            setMeasuredDimension(widthMeasureSpec, heightMeasureSpec);
        }
    }
    
    如何使用xml绑定

    <FrameLayout
       android:id="@+id/secondMedia"
       android:layout_width="match_parent"
       android:layout_height="match_parent">
    
         <com.my.package.customview.FullScreenVideoView
               android:layout_width="match_parent"
               android:layout_height="match_parent" 
               android:id="@+id/fullScreenVideoView"/>
    
    </FrameLayout>
    
    FullScreenVideoView videoView = new FullScreenVideoView(getActivity());
    parentLayout.addView(videoView, new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.MATCH_PARENT));
    
    希望这能对你有所帮助。

    好吧,我希望它能帮助你

    它可以处理所有关于surfaceView和fullscreen view的无聊代码,并让您只关注UI按钮


    如果您不想构建自定义按钮,您可以使用FullscreenVideoLayout。

    当前的向上投票解决方案可行,但可能有一个更简单的解决方案来解决原始问题。一位评论者正确地指出,您可以使用相同的方法调整视频视图的大小,而无需将所有内容转换为SurfaceView。我在我的一个应用程序中测试了这一点,它似乎起了作用。只需将计算出的布局参数添加到OnPreparedListener回调中的VideoView:

    MinsPirationVideoView.setOnPreparedListener(新的MediaPlayer.OnPreparedListener(){ @凌驾 已准备好公开作废(MediaPlayer mp){ //MME层=mp

                mp.setOnSeekCompleteListener(new MediaPlayer.OnSeekCompleteListener() {
                    @Override
                    public void onSeekComplete(MediaPlayer mp) {
                        if(isPlaying = true) {
                            stopPosition = 0;
                            mp.start();
                            mVideoProgressTask = new VideoProgress();
                            mVideoProgressTask.execute();
                        }
                    }
                });
    
    
                // so it fits on the screen
                int videoWidth = mp.getVideoWidth();
                int videoHeight = mp.getVideoHeight();
                float videoProportion = (float) videoWidth / (float) videoHeight;
    
    
                DisplayMetrics mDisplayMetrics = new DisplayMetrics();
                getWindowManager().getDefaultDisplay().getMetrics(mDisplayMetrics);
    
                float screenWidth = mDisplayMetrics.widthPixels;
                float screenHeight = mDisplayMetrics.heightPixels;
    
                float screenProportion = (float) screenWidth / (float) screenHeight;
                android.view.ViewGroup.LayoutParams lp = mInspirationalVideoView.getLayoutParams();
    
                if (videoProportion > screenProportion) {
                    lp.width = screenWidth;
                    lp.height = (int) ((float) screenWidth / videoProportion);
                } else {
                    lp.width = (int) (videoProportion * (float) screenHeight);
                    lp.height = screenHeight;
                }
    
                mInspirationalVideoView.setLayoutParams(lp);
    
               ...
    
            }
        });
    

    这是我的功能,适用于全屏视频,无需拉伸。它会自动裁剪视频的侧面。它可以在纵向和横向模式下工作

    事实上,它是从那张照片上取走的


    只需删除布局xml文件中的4个android:layout\u alignXXX,您的视频视图就可以在保持视频纵横比的同时使用尽可能多的屏幕空间。这就是API的设计和工作原理。@yorkw我知道,正常的视频显示通常需要1/3的屏幕,我也不会将该xml应用于4个android:Layou alignXXX到我的应用程序,这是一个不合适的解决方案,我发现强制全屏,我想任何适当的方式,以迫使它在全屏,但(没有伸展),我假设这是预期的结果。如果在纵向模式下播放,视频通常全宽,但在顶部和底部留有很多空间;如果在横向模式下播放,视频通常全高,但在侧面留有一些空间。@yorkw android默认播放器和许多自定义播放器在全屏上播放任何视频,没有间距,因此这里必须有一个技巧或代码黑客来做到这一点,这就是我要找的我的亲爱的他们仍然是纵横比吗?我怀疑。有很多设备有不同的屏幕大小。以三星Galaxy S2为例,屏幕大小是480 x 800,在横向模式下是5:3,你可以看到这不是一个正常的纵横比,如4:3或16:9。如果布局为fill\u parent,是否需要所有对齐属性?听起来像是重复的。是的,要将视频视图设置为全屏,我们需要所有对齐,此代码使视频视图全屏显示,但如果视频不完全匹配,则会拉伸视频。此代码不会保持纵横比。比您的实现更健壮、更智能当视频太高或太宽时,它都能处理这两种情况,所以请使用VideoView。但是当你使用views时,你可以动态地为视频设置参数,我认为你是对的at@Yorkw:SurfaceView充当容器。因此您可以在其中添加videoView。因此您的健壮性仍然占优势。不,您不能将videoView包装在SurfaceView中w、 由于VideoView本身是一个SurfaceView
    公共类,VideoView扩展了SurfaceView,实现了MediaPlayerControl{…}
    。这正是API提供VideoView的原因
                mp.setOnSeekCompleteListener(new MediaPlayer.OnSeekCompleteListener() {
                    @Override
                    public void onSeekComplete(MediaPlayer mp) {
                        if(isPlaying = true) {
                            stopPosition = 0;
                            mp.start();
                            mVideoProgressTask = new VideoProgress();
                            mVideoProgressTask.execute();
                        }
                    }
                });
    
    
                // so it fits on the screen
                int videoWidth = mp.getVideoWidth();
                int videoHeight = mp.getVideoHeight();
                float videoProportion = (float) videoWidth / (float) videoHeight;
    
    
                DisplayMetrics mDisplayMetrics = new DisplayMetrics();
                getWindowManager().getDefaultDisplay().getMetrics(mDisplayMetrics);
    
                float screenWidth = mDisplayMetrics.widthPixels;
                float screenHeight = mDisplayMetrics.heightPixels;
    
                float screenProportion = (float) screenWidth / (float) screenHeight;
                android.view.ViewGroup.LayoutParams lp = mInspirationalVideoView.getLayoutParams();
    
                if (videoProportion > screenProportion) {
                    lp.width = screenWidth;
                    lp.height = (int) ((float) screenWidth / videoProportion);
                } else {
                    lp.width = (int) (videoProportion * (float) screenHeight);
                    lp.height = screenHeight;
                }
    
                mInspirationalVideoView.setLayoutParams(lp);
    
               ...
    
            }
        });
    
        public void onPrepared(MediaPlayer mp) {
            int videoWidth = mediaPlayer.getVideoWidth();
            int videoHeight = mediaPlayer.getVideoHeight();
    
            DisplayMetrics displayMetrics = new DisplayMetrics();
            getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
            int screenWidth = displayMetrics.widthPixels;
            int screenHeight = displayMetrics.heightPixels;
    
            float scaleY = 1.0f;
            float scaleX = (videoWidth * screenHeight / videoHeight) / screenWidth;
    
            int pivotPointX = (int) (screenWidth / 2);
            int pivotPointY = (int) (screenHeight / 2);
    
            surfaceView.setScaleX(scaleX);
            surfaceView.setScaleY(scaleY);
            surfaceView.setPivotX(pivotPointX);
            surfaceView.setPivotY(pivotPointY);
    
            mediaPlayer.setLooping(true);
            mediaPlayer.start();
        }