Подтвердить что ты не робот

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/

Спасибо заранее.

4b9b3361

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