Reputation: 4314
I wonder if I can get a way to let video run via videoview in full screen?
I searched a lot and tried many ways such as:
Apply theme in manifest:
android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
but that does not force the video to be in full screen.
Apply in activity itself:
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
also does not force the video to be in full screen.
The only way force video to full screen is:
<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>
This way it results in full screen video but it stretches the video itself (elongated video) ,
I'm not applying this improper solution to my videoview, so is there is any way to do it without stretching the video?
Video Class:
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>
Upvotes: 32
Views: 89290
Reputation: 249
The current upvoted solution works, but there may be a simpler solution to the original problem. A commenter correctly pointed out that you could resize a VideoView using the same methodology without the cost of converting everything to a SurfaceView. I tested this in one of my apps and it seems to work. Just add the calculated layout parameters to the VideoView in the OnPreparedListener callback:
mInspirationalVideoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() { @Override public void 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;
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);
...
}
});
Upvotes: 3
Reputation: 21
Here is my function which works for the full screen video without stretching it. It will automatically crop the sides of the video. It worked both portrait and landscape modes.
It was actually taken from the 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();
}
Upvotes: 2
Reputation: 52790
I have solved this one by Custom VideoView:
I have added VideoView to ParentView in two ways From xml & programatically.
Add Custom class for VideoView named with FullScreenVideoView.java:
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);
}
}
How to bind with 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>
OR
How to add Programatically VideoView to ParentView:
FullScreenVideoView videoView = new FullScreenVideoView(getActivity());
parentLayout.addView(videoView, new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.MATCH_PARENT));
Hope this will help you.
Upvotes: -1
Reputation: 86
Well, I hope it helps FullscreenVideoView
It handles all boring code about surfaceView and fullscreen view and let you focus only in UI buttons.
And you can use the FullscreenVideoLayout if you don't want to build your custom buttons.
Upvotes: 1
Reputation: 7788
Like this you can set the properties of the video by yourself.
Use a SurfaceView (gives you more control on the view), set it to fill_parent to match the whole screen
<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>
then on your java code get the surface view and add your media player to it
surfaceViewFrame = (SurfaceView) findViewById(R.id.surfaceViewFrame);
player = new MediaPlayer();
player.setDisplay(holder);
set on your media player a onPreparedListener and manually calculate the desired size of the video, to fill the screen in the desired proportion avoiding stretching the video!
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();
}
}
});
I modified this from a tutorial for video streaming that I followed some time ago, can't find it right now to reference it, if someone does please add the link to the answer!
Hope it helps!
EDIT
Ok, so, if you want the video to occupy the whole screen and you don't want it to stretch you will end up with black stripes in the sides. In the code I posted we are finding out what is bigger, the video or the phone screen and fitting it the best way we can.
There you have my complete activity, streaming a video from a link. It's 100% functional. I can't tell you how to play a video from your own device because I don't know that. I'm sure you will find it in the documentation here or here.
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);
}
}
}
}
}
Upvotes: 48
Reputation: 24857
Have you tried adjusting the underlying surface holder size? Try the code below it should adjust the surface holder to be the same width and height of the screen size. You should still have your activity be full screen without a title bar.
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();
}
}
Upvotes: 1
Reputation: 1506
A SurfaceView gives u an optimized drawing surface
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 calls should be wrapped in a 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();
}
Upvotes: 0
Reputation: 835
@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>
try this it's working for me
Upvotes: 4