2011-11-23 2 views
6

해결할 수없는 문제가 있습니다. MediaPlayer 클래스를 사용하여 비디오를 재생합니다. 그러나 나는 항상 원래의 종횡비를 잃어 가고 있습니다. 미디어 플레이어 코드와 xml 코드는 여기에 언급되어 있습니다. 나는 많은 것을 시도했지만 여전히 문제를 해결할 수 없습니다. 원본 가로 세로 비율을 유지해야합니다. Android Manifest File에서이 활동을 전체 화면으로 선언했습니다. 또한 미디어 플레이어 코드 뒤에 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를); 당신의 서피스 뷰 SurfaceView에 방법을 채우기 위해

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

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

     setFitToFillAspectRatio(mp, width, height); 

    } 
}; 

...

마지막으로 적합. 가로 및 세로로 작동합니다.

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