2011-11-23 613 views
6

我遇到了無法解決的問題。我使用MediaPlayer類播放視頻;然而,我總是失去原始的寬高比。媒體播放器代碼和xml代碼在這裏提到。我嘗試了很多東西,但仍然無法解決問題。我需要保持原始的寬高比。我已經宣佈此活動是在我的Android清單文件中全屏顯示。媒體播放器代碼後,我也在這裏附加了xml代碼。請建議我。Android:MediaPlayer視頻寬高比問題

private class ErrorListener implements OnErrorListener { 
    // FIXME: @Override 
    public boolean onError(MediaPlayer mp, int what, int extra) { 
     String message = "Unknown error"; 
     switch (what) { 
     case MediaPlayer.MEDIA_ERROR_UNKNOWN: 
      message = "Unable to play media"; 
      showError(message); 
      break; 
     case MediaPlayer.MEDIA_ERROR_SERVER_DIED: 
      message = "Server failed"; 
      showError(message); 
      break; 
     case MediaPlayer.MEDIA_ERROR_NOT_VALID_FOR_PROGRESSIVE_PLAYBACK: 
      message = "Invalid media"; 
      showError(message); 
      break; 
     } 
     return false; 
    } 
} 

public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); 
    setContentView(R.layout.videoview); 
    Intent intent = getIntent(); 
    uri = intent.getData(); 
    new loadMovie().execute(); 
    mPreview = (SurfaceView) findViewById(R.id.videoview); 
    mPreview.bringToFront(); 
    holder = mPreview.getHolder(); 
    holder.addCallback(this); 
    holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); 
    mediaPlayer = new MediaPlayer(); 

}// onCreate Method Ends 

private void playVideo() { 
    doCleanUp(); 
    try { 
     mediaPlayer.setDataSource(this, uri); 
    } catch (IllegalArgumentException e) { 
     e.printStackTrace(); 
    } catch (SecurityException e) { 
     e.printStackTrace(); 
    } catch (IllegalStateException e) { 
     e.printStackTrace(); 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 
    mediaPlayer.setDisplay(holder); 
    try { 
     mediaPlayer.prepare(); 
    } catch (IllegalStateException e) { 
     e.printStackTrace(); 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 
    mediaPlayer.setOnErrorListener(new ErrorListener()); 
    mediaPlayer.setOnBufferingUpdateListener(this); 
    mediaPlayer.setOnCompletionListener(this); 
    mediaPlayer.setOnPreparedListener(this); 
    mediaPlayer.setOnVideoSizeChangedListener(this); 
    mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC); 
    mediaController = new MediaController(this); 
} 

@Override 
public boolean onTouchEvent(MotionEvent event) { 
    mediaController.show(); 
    return false; 
} 

// --MediaPlayerControl 
// methods---------------------------------------------------- 
public void start() { 
    mediaPlayer.start(); 
} 

public void pause() { 
    mediaPlayer.pause(); 
} 

public int getDuration() { 
    return mediaPlayer.getDuration(); 
} 

public int getCurrentPosition() { 
    return mediaPlayer.getCurrentPosition(); 
} 

public void seekTo(int i) { 
    mediaPlayer.seekTo(i); 
} 

public boolean isPlaying() { 
    return mediaPlayer.isPlaying(); 
} 

public int getBufferPercentage() { 
    return 0; 
} 

public boolean canPause() { 
    return true; 
} 

public boolean canSeekBackward() { 
    return true; 
} 

public boolean canSeekForward() { 
    return true; 
} 

// End of MediaPlayer 
// Controls-------------------------------------------------------- 
// ------------------------ 

public void onPrepared(MediaPlayer mediaPlayer) { 
    mediaController.setMediaPlayer(this); 
    mediaController.setAnchorView(findViewById(R.id.videoview)); 
    mIsVideoReadyToBePlayed = true; 

    if (mIsVideoReadyToBePlayed && mIsVideoSizeKnown) { 
     startVideoPlayback(); 
    } 

    handler.post(new Runnable() { 
     public void run() { 
      mediaController.setEnabled(true); 
      mediaController.show(); 
     } 
    }); 
} 

public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) { 
    // TODO Auto-generated method stub 

} 

public void surfaceCreated(SurfaceHolder holder) { 
    // TODO Auto-generated method stub 
    playVideo(); 
} 

public void surfaceDestroyed(SurfaceHolder arg0) { 

} 

private void startVideoPlayback() { 
    holder.setFixedSize(mVideoWidth, mVideoHeight); 
    mediaPlayer.start(); 
} 

public void onVideoSizeChanged(MediaPlayer mp, int width, int height) { 
    if (width == 0 || height == 0) { 
     return; 
    } 
    mIsVideoSizeKnown = true; 
    mVideoWidth = width; 
    mVideoHeight = height; 
    if (mIsVideoReadyToBePlayed && mIsVideoSizeKnown) { 
     startVideoPlayback(); 
    } 

} 

public void onCompletion(MediaPlayer arg0) { 

} 

public void onBufferingUpdate(MediaPlayer mp, int percent) { 

} 

private void releaseMediaPlayer() { 
    mediaPlayer.release(); 
    mediaPlayer = null; 
} 

private void doCleanUp() { 
    mVideoWidth = 0; 
    mVideoHeight = 0; 
    mIsVideoReadyToBePlayed = false; 
    mIsVideoSizeKnown = false; 
} 

這裏是XML:

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
android:orientation="horizontal" 
android:layout_width="fill_parent" 
android:layout_height="fill_parent" 
android:gravity="center" 
> 
<SurfaceView android:id="@+id/videoview" 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    /> 
</LinearLayout> 

誰能請告訴我我怎麼能保持視頻的寬高比?

回答

10

首先用Gravity.CENTER創建一個相對佈局,然後在其中附上您的曲面視圖。這將確保視頻將在屏幕中居中。

此外,如果你使用的是活動,用 '黑' 的主題,以避免梯度

在你SurfaceView,創建一個監聽器:

mMediaPlayer = new MediaPlayer(); 

mMediaPlayer.setOnVideoSizeChangedListener(mOnVideoSizeChangedListener);

...

MediaPlayer.OnVideoSizeChangedListener mOnVideoSizeChangedListener = new MediaPlayer.OnVideoSizeChangedListener() { 

    @Override 
    public void onVideoSizeChanged(MediaPlayer mp, int width, int height) { 

     setFitToFillAspectRatio(mp, width, height); 

    } 
}; 

...

最後適合你SurfaceView填寫方法。這將適用於景觀和肖像

private void setFitToFillAspectRatio(MediaPlayer mp, int videoWidth, int videoHeight) 
{ 
    if(mp != null) 
    {  
     Integer screenWidth = ((Activity) mContext).getWindowManager().getDefaultDisplay().getWidth(); 
     Integer screenHeight = ((Activity) mContext).getWindowManager().getDefaultDisplay().getHeight(); 
     android.view.ViewGroup.LayoutParams videoParams = getLayoutParams(); 


     if (videoWidth > videoHeight) 
     { 
      videoParams.width = screenWidth; 
      videoParams.height = screenWidth * videoHeight/videoWidth; 
     } 
     else 
     { 
      videoParams.width = screenHeight * videoWidth/videoHeight; 
      videoParams.height = screenHeight; 
     } 


     setLayoutParams(videoParams); 
    } 
} 
+1

是否有可能讓SurfaceView始終具有相同的尺寸(相同的LayoutParams),但只是調整視頻,以便它適當地裁剪/信箱? – mbonnin