Android: Mediaplayer: как использовать SurfaceView или медиаплеер для воспроизведения видео в правильном размере
Я играю в локальный видеофайл с помощью MediaPlayer и SurfaceView. SurfaceView - единственный элемент управления в действии, в то время как мои видеофайлы - QVGA или другие. Проблема в том, что видео растягивается, как я могу воспроизводить видео в его первоначальном размере, например. qvga с оставшейся областью черного.
Из итерации
Когда я принудительно устанавливает layout_height/width Surfaceview в XML, видео отображается в порядке.
surface_holder.setFixedSize(w,h)
не действует, ни mp.setdisplay().
В этом руководстве.
UPDATE
XML flie
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/home_container"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<SurfaceView
android:id="@+id/surface"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:paddingTop="10dip" />
</framelayout>
Использование MediaPlayer соответствует следующей ссылке
http://davanum.wordpress.com/2007/12/29/android-videomusic-player-sample-from-local-disk-as-well-as-remote-urls/
Спасибо заранее.
Ответы
Ответ 1
На вашем SurfaceView в XML вы используете wrap_content? Это должно решить вашу проблему, если нет. Возможно, вам понадобится вставить еще немного кода для дальнейшего изучения, если это не решит вашу проблему.
Измените ширину вида поверхности на wrap_content.
Ответ 2
При настройке макета SurfaceView на wrap_content будет не размер видео для воспроизведения с соответствующим соотношением сторон.
- SurfaceView - это оптимизированная поверхность рисования.
- Видео обращается к SurfaceView, не содержащемуся в нем
wrap_content является синонимом fill_parent для SurfaceView.
Что вы хотите сделать, так это получить размеры вашего видео с объекта MediaPlayer. Затем вы можете установить соотношение сторон SurfaceView в соответствии с видео.
Некоторая базовая инициализация
public class YourMovieActivity extends Activity implements SurfaceHolder.Callback {
private MediaPlayer mp = null;
//...
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mp = new MediaPlayer();
mSurfaceView = (SurfaceView) findViewById(R.id.surface);
//...
}
}
Тогда хороший материал. Здесь я пропустил проверку ошибок, чтобы уменьшить код, вызовы MediaPlayer должны быть завернуты в try {}.
@Override
public void surfaceCreated(SurfaceHolder holder) {
mp.setDataSource("/sdcard/someVideo.mp4");
mp.prepare();
//Get the dimensions of the video
int videoWidth = mp.getVideoWidth();
int videoHeight = mp.getVideoHeight();
//Get the width of the screen
int screenWidth = getWindowManager().getDefaultDisplay().getWidth();
//Get the SurfaceView layout parameters
android.view.ViewGroup.LayoutParams lp = mSurfaceView.getLayoutParams();
//Set the width of the SurfaceView to the width of the screen
lp.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
lp.height = (int) (((float)videoHeight / (float)videoWidth) * (float)screenWidth);
//Commit the layout parameters
mSurfaceView.setLayoutParams(lp);
//Start video
mp.start();
}
Обратите внимание, что этот код делает некоторые предположения относительно размеров вашего видео. As-is, он максимизирует ширину и предполагает, что высота не превышает высоту экрана.
Возможно, вы захотите установить высоту вместо ширины, также вы можете проверить расчет размера и убедиться, что он не больше экрана или экрана - другие_layout_elements.
Ответ 3
вот код, который я сейчас использую в проекте:
private MediaPlayer mMediaPlayer;
private SurfaceView mSurfaceView;
private SurfaceHolder holder;
private int mPos = 0;
...
int width = mSurfaceView.getWidth();
int height = mSurfaceView.getHeight();
float boxWidth = width;
float boxHeight = height;
float videoWidth = mMediaPlayer.getVideoWidth();
float videoHeight = mMediaPlayer.getVideoHeight();
Log.i(TAG, String.format("startVideoPlayback @ %d - video %dx%d - box %dx%d", mPos, (int) videoWidth, (int) videoHeight, width, height));
float wr = boxWidth / videoWidth;
float hr = boxHeight / videoHeight;
float ar = videoWidth / videoHeight;
if (wr > hr)
width = (int) (boxHeight * ar);
else
height = (int) (boxWidth / ar);
Log.i(TAG, String.format("Scaled to %dx%d", width, height));
holder.setFixedSize(width, height);
mMediaPlayer.seekTo(mPos);
mMediaPlayer.start();
макет, который я использую (вы можете просто игнорировать индикатор выполнения)
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical" >
<ProgressBar
android:id="@+id/progressBar1"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<SurfaceView
android:id="@+id/surface"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center" >
</SurfaceView>