全屏视频视图,无需拉伸视频

时间:2012-08-31 08:44:32

标签: java android fullscreen android-videoview

我想知道我是否可以通过全屏视频播放视频?

我经常搜索并尝试了许多方法,例如:

  1. 在清单中应用主题:

    android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
    

    但这并不会强制视频全屏显示。

  2. 在活动中申请:

    requestWindowFeature(Window.FEATURE_NO_TITLE);  
    getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,  
        WindowManager.LayoutParams.FLAG_FULLSCREEN);
    

    也不会强制视频全屏显示。

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

    <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> 
    

    这样会产生全屏视频,但会延伸视频本身(拉长视频),

    我没有将这种不正确的解决方案应用于我的视频,所以有没有办法在不延长视频的情况下进行操作?

    视频类:

    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();
        }
    }
    

    main.xml中:

    <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>
    

8 个答案:

答案 0 :(得分:42)

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

使用SurfaceView(让您对视图有更多控制权),将其设置为fill_parent以匹配整个屏幕

<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>

然后在你的java代码上获取表面视图并将媒体播放器添加到它

surfaceViewFrame = (SurfaceView) findViewById(R.id.surfaceViewFrame);
player = new MediaPlayer();
player.setDisplay(holder);

在媒体播放器上设置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%功能。我不能告诉你如何从你自己的设备播放视频,因为我不知道。我相信您会在文档herehere中找到它。

public class VideoPlayer extends Activity implements Callback, OnPreparedListener, OnCompletionListener, 
    OnClickListener {   

private SurfaceView surfaceViewFrame;
private static final String TAG = "VideoPlayer";
private SurfaceHolder holder;
private ProgressBar progressBarWait;
private ImageView pause;
private MediaPlayer player; 
private Timer updateTimer;
String video_uri = "http://daily3gp.com/vids/familyguy_has_own_orbit.3gp";  


@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.videosample);       


    pause = (ImageView) findViewById(R.id.imageViewPauseIndicator);
    pause.setVisibility(View.GONE);
    if (player != null) {
        if (!player.isPlaying()) {
            pause.setVisibility(View.VISIBLE);
        }
    }


    surfaceViewFrame = (SurfaceView) findViewById(R.id.surfaceViewFrame);
    surfaceViewFrame.setOnClickListener(this);
    surfaceViewFrame.setClickable(false);

    progressBarWait = (ProgressBar) findViewById(R.id.progressBarWait);

    holder = surfaceViewFrame.getHolder();
    holder.addCallback(this);
    holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);

    player = new MediaPlayer();
    player.setOnPreparedListener(this);
    player.setOnCompletionListener(this);
    player.setScreenOnWhilePlaying(true);
    player.setDisplay(holder);
}

private void playVideo() {
        new Thread(new Runnable() {
            public void run() {
                try {
                    player.setDataSource(video_uri);
                    player.prepare();
                } catch (Exception e) { // I can split the exceptions to get which error i need.
                    showToast("Error while playing video");
                    Log.i(TAG, "Error");
                    e.printStackTrace();
                } 
            }
        }).start();     
}

private void showToast(final String string) {
    runOnUiThread(new Runnable() {
        public void run() {
            Toast.makeText(VideoPlayer.this, string, Toast.LENGTH_LONG).show();
            finish();
        }
    });
}


public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
    // TODO Auto-generated method stub

}

public void surfaceCreated(SurfaceHolder holder) {
    playVideo();
}

public void surfaceDestroyed(SurfaceHolder holder) {
    // TODO Auto-generated method stub

}
//prepare the video
public void onPrepared(MediaPlayer mp) {        
    progressBarWait.setVisibility(View.GONE);

    // 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();         
    }
    surfaceViewFrame.setClickable(true);
}

// callback when the video is over
public void onCompletion(MediaPlayer mp) {
    mp.stop();
    if (updateTimer != null) {
        updateTimer.cancel();
    }
    finish();
}

//pause and resume
public void onClick(View v) {
    if (v.getId() == R.id.surfaceViewFrame) {
         if (player != null) {
            if (player.isPlaying()) {
                player.pause();
                pause.setVisibility(View.VISIBLE);
            } else {
                player.start();
                pause.setVisibility(View.GONE);
            }
        }
    }
}

}

答案 1 :(得分:4)

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        videoView1 = (VideoView) findViewById(R.id.videoview);
                String SrcPath = "/mnt/sdcard/final.mp4";
        videoView1.setVideoPath(SrcPath);
        videoView1.setMediaController(new MediaController(this));
        videoView1.requestFocus();      
        videoView1.start();     
    }
}




<VideoView
    android:id="@+id/videoview"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:layout_alignParentBottom="true"
    android:layout_alignParentLeft="true"
    android:layout_alignParentRight="true"
    android:layout_alignParentTop="true" >
</VideoView>

试试这个为我工作

答案 2 :(得分:2)

当前支持的解决方案有效,但是对于原始问题可能有一个更简单的解决方案。评论者正确地指出,您可以使用相同的方法来调整VideoView的大小,而无需将所有内容都转换为SurfaceView。我在其中一个应用程序中对此进行了测试,它似乎可以正常工作。只需在OnPreparedListener回调中将计算出的布局参数添加到VideoView中即可:

mInspirationalVideoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener(){             @Override             公共无效onPrepared(MediaPlayer mp){                // mMediaPlayer = 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;
            int screenWidth = getWindowManager().getDefaultDisplay().getWidth();
            int screenHeight = getWindowManager().getDefaultDisplay().getHeight();

            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);

           ...

        }
    });

答案 3 :(得分:1)

这是我的功能,适用于全屏视频而无需拉伸。它将自动裁剪视频的侧面。它可以同时使用纵向和横向模式。

它实际上取自answer

    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();
    }

答案 4 :(得分:0)

SurfaceView为您提供优化的绘图表面

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();
}

答案 5 :(得分:0)

您是否尝试过调整下面的表面支架尺寸?尝试下面的代码,应将表面支架调整为与屏幕尺寸相同的宽度和高度。您仍然应该在没有标题栏的情况下全屏显示您的活动。

    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();
        }
    }

答案 6 :(得分:0)

我已通过自定义视频查看

解决了这个问题

我已经以两种方式将VideoView添加到ParentView来自xml&amp;编程。

为以 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>

如何以编程方式将VideoView添加到 ParentView

FullScreenVideoView videoView = new FullScreenVideoView(getActivity());
parentLayout.addView(videoView, new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.MATCH_PARENT));

希望这会对你有所帮助。

答案 7 :(得分:0)

好吧,我希望它有助于FullscreenVideoView 它处理有关surfaceView和全屏视图的所有无聊代码,让您只关注UI按钮。 如果您不想构建自定义按钮,则可以使用FullscreenVideoLayout。