web-dev-qa-db-fra.com

Android: Mediaplayer: Comment utiliser SurfaceView ou mediaplayer pour lire des vidéos à la bonne taille

Je joue un fichier vidéo local à l'aide de MediaPlayer et SurfaceView. SurfaceView est le seul contrôle en activité, alors que mes fichiers vidéo sont QVGA ou autres. Le problème est que la vidéo est étirée, comment puis-je lire la vidéo dans sa taille d'origine, par exemple qvga avec zone restante noire.

Depuis l'itération,

Lorsque je définit avec force la disposition_hauteur/largeur de Surfaceview en XML, la vidéo s'affiche correctement. surface_holder.setFixedSize(w,h) n'a aucun effet, ni mp.setdisplay ().

Veuillez guider à ce sujet.

[~ # ~] mise à jour [~ # ~]

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>

L'utilisation de MediaPlayer est conforme au lien suivant

http://davanum.wordpress.com/2007/12/29/Android-videomusic-player-sample-from-local-disk-as-well-as-remote-urls/

Merci d'avance.

19
JRC

Définir votre mise en page SurfaceView sur wrap_content pas dimensionnera une vidéo à lire au rapport d'aspect approprié.

  • Une SurfaceView est une surface de dessin optimisée
  • Une vidéo est dessinée sur une SurfaceView, non contenue dans celle-ci

wrap_content est synonyme de fill_parent pour une SurfaceView.

Ce que vous voulez faire, c'est obtenir les dimensions de votre vidéo à partir de l'objet MediaPlayer. Vous pouvez ensuite définir le rapport d'aspect de SurfaceView pour qu'il corresponde à la vidéo.

Quelques initialisations de base

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

Ensuite, les bonnes choses. J'ai omis de vérifier les erreurs ici pour réduire le code, les appels MediaPlayer devraient être encapsulés dans un essai {}.

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

Notez que ce code fait des hypothèses sur les dimensions de votre vidéo. En l'état, il maximise la largeur et suppose que la hauteur n'est pas supérieure à la hauteur de l'écran.

Vous pouvez vouloir ajuster la hauteur au lieu de la largeur, vous pouvez également vérifier le calcul de la dimension et vous assurer qu'il n'est pas supérieur à l'écran ou à l'écran - other_layout_elements.

79
Error 454

voici le code que j'utilise actuellement dans un projet:

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

la disposition que j'utilise (vous pouvez simplement ignorer la barre de progression)

<?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>
4
sherpya