2011-11-23 31 views
6

Tôi gặp sự cố mà tôi không thể giải quyết được. Tôi đang sử dụng lớp MediaPlayer để phát video; tuy nhiên, tôi luôn luôn mất tỷ lệ khung hình gốc. Mã trình phát phương tiện và mã xml được đề cập ở đây. Tôi đã thử rất nhiều thứ nhưng vẫn không thể giải quyết vấn đề. Tôi cần phải duy trì tỷ lệ khung hình gốc. Tôi đã tuyên bố hoạt động này là toàn màn hình trong Tệp kê khai Android của tôi. Tôi cũng đã đính kèm mã xml ở đây sau mã trình phát phương tiện. Xin vui lòng tư vấn cho tôi.Android: Vấn đề về tỷ lệ co của videoPlayerPlayer

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; 
} 

Và đây là 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> 

bất cứ ai có thể vui lòng tư vấn cho tôi làm thế nào tôi có thể duy trì tỷ lệ khung hình của video?

Trả lời

10

Trước tiên hãy tạo Bố cục tương đối với Gravity.CENTER và đính kèm Chế độ xem bề mặt của bạn trong đó. Điều này sẽ đảm bảo rằng video sẽ được căn giữa bên trong màn hình.

Ngoài ra nếu bạn đang sử dụng một hoạt động, sử dụng các chủ đề 'đen' để tránh gradient

Trong SurfaceView của bạn, tạo ra một Listener:

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

    } 
}; 

...

Cuối cùng phù hợp để điền vào phương pháp trong SurfaceView của bạn. Điều này sẽ hoạt động trên phong cảnh và chân dung

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

Có thể có SurfaceView luôn có cùng kích thước (cùng LayoutParams) nhưng chỉ điều chỉnh video sao cho nó được cắt/đóng hộp một cách thích hợp? – mbonnin

Các vấn đề liên quan