Android

Full screen videoview without stretching the video

Полноэкранный просмотр видео без растягивания видео

Интересно, могу ли я найти способ разрешить просмотр видео через 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);

    также не выводит видео в полноэкранном режиме.


Единственный способ принудительно отобразить видео на весь экран - это:

<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>
Переведено автоматически
Ответ 1

Таким образом, вы можете самостоятельно настроить свойства видео.

Используйте 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-коде получите surface view и добавьте в него свой медиаплеер

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% функционально. Я не могу сказать вам, как воспроизвести видео с вашего собственного устройства, потому что я этого не знаю. Я уверен, вы найдете это в документации здесь или здесь.

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

}
Ответ 2
    @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>

попробуйте это, у меня это работает

Ответ 3

Текущее решение, за которое проголосовали, работает, но может быть более простое решение исходной проблемы. Комментатор правильно указал, что вы можете изменить размер видеообзора, используя ту же методологию, без затрат на преобразование всего в SurfaceView. Я протестировал это в одном из своих приложений, и, кажется, это работает. Просто добавьте вычисленные параметры макета в видеообзор в обратном вызове onPreparedListener:

Пошаговый просмотр видео.setOnPreparedListener(новый медиаплеер.onPreparedListener() { @Переопределить общедоступную пустоту 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);

...

}
});
Ответ 4

Вот моя функция, которая работает с полноэкранным видео без его растягивания. Она автоматически обрезает стороны видео. Она работала как в портретном, так и в альбомном режимах.

На самом деле это было взято из ответа.

    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();
}
2023-05-21 18:21 java android