2014-02-17 59 views
4

在我的Android應用程序中,我有一個自定義視頻播放器,可以播放來自URL的視頻。但是,當以縱向拍攝視頻時,視頻會在應用程序中逆時針旋轉90度。Android檢測來自URL的視頻是否爲縱向

有沒有辦法讓我獲得視頻的方向並相應地旋轉視圖?我需要動態檢測方向,因爲應用程序應該仍然能夠播放風景視頻(目前沒有定位問題)。

這裏是我用來顯示視頻:

// create the video controller 
videoController = new MediaController(this); 
videoControllerExists = true; 
videoController.setAnchorView(mediaHolder); 
videoController.setPadding(0, 0, 0, bottomButtonHeight); 

s3Video = new VideoView(MediaPreview.this); 
s3Video.setVideoURI(Uri.parse(mediaURL)); 
s3Video.setMediaController(videoController); 
// do something here to determine if video is in portrait orientation 
DisplayMetrics displaymetrics = new DisplayMetrics(); 
getWindowManager().getDefaultDisplay().getMetrics(displaymetrics); 
int h = displaymetrics.heightPixels; 
int w = displaymetrics.widthPixels; 

// add the video player to the view and play 
mediaHolder.addView(s3Video); 
s3Video.start(); 
s3Video.bringToFront(); 
videoController.requestFocus(); 

這裏有一個人像視頻,你可以與如果你想這一點測試: https://dl.dropboxusercontent.com/u/1000620/portrait.mp4

編輯

看過一些例子後,我從一個VideoView切換到一個TextureView,並能夠旋轉視頻。儘管如此,我仍然不知道如何從URL中檢測視頻的方向,因此所有視頻都將立即旋轉。

如何從URL中檢測視頻的方向?

這裏是我更新的代碼:

public class MediaPreview extends SherlockActivity implements YouTubePlayer.OnInitializedListener, TextureView.SurfaceTextureListener, OnBufferingUpdateListener, OnCompletionListener, OnPreparedListener, 
OnVideoSizeChangedListener, MediaPlayerControl { 

    private MediaPlayer s3VideoPlayer; 
    private TextureView s3TextureView; 
    private Surface s; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 

    // set up textureview 
     s3TextureView = (TextureView) findViewById(R.id.s3_video); 
     s3TextureView.setSurfaceTextureListener(this); 
    } 

    @Override 
    public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, 
      int height) { 
     s = new Surface(surface); 
     if(isFromVideo){ 
      playAmazonVideo(mediaHolder); 
     } 

    } 

    private void playAmazonVideo(FrameLayout mediaHolder){ 

      // set up mediacontroller 
      videoController = new MediaController(this); 
      videoControllerExists = true; 
      videoController.setAnchorView(mediaHolder); 
      videoController.setPadding(0, 0, 0, bottomButtonHeight); 

      // set scale for textureview 
      DisplayMetrics displaymetrics = new DisplayMetrics(); 
      getWindowManager().getDefaultDisplay().getMetrics(displaymetrics); 
      int h = displaymetrics.heightPixels; 
      int w = displaymetrics.widthPixels; 
      LayoutParams videoLayoutParams = new LayoutParams(h, w); 
      videoLayoutParams.gravity = Gravity.CENTER; 
      s3TextureView.setScaleX(h/w); 
      s3TextureView.setLayoutParams(videoLayoutParams); 

     // Setting up video view using Media Player 
     try{ 
      s3VideoPlayer = MediaPlayer.create(this, Uri.parse(mediaURL)); 
      s3VideoPlayer.setSurface(s); 
      s3VideoPlayer.setOnBufferingUpdateListener(this); 
      s3VideoPlayer.setOnCompletionListener(this); 
      s3VideoPlayer.setOnPreparedListener(this); 
      s3VideoPlayer.setScreenOnWhilePlaying(true); 
      s3VideoPlayer.setOnVideoSizeChangedListener(this); 
      s3VideoPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC); 
      s3VideoPlayer.start(); 
    } 

    @Override 
    public void onPrepared(MediaPlayer mp) { 
     if(isAmazon && mediaURL.length() > 0){ 
      mediaProgress.setVisibility(View.GONE); 
      videoController.setMediaPlayer(this); 
      videoController.setEnabled(true); 
      videoController.show();  
     }  
    } 

    @Override 
    public boolean onTouchEvent(MotionEvent event){ 
     if(isAmazon){ 
      Log.d(TAG, "showing video controller"); 
      videoController.show();  
     } 
     return false; 
    } 

@Override 
    public boolean canPause() { 
     return true; 
    } 

    @Override 
    public boolean canSeekBackward() { 
     return true; 
    } 

    @Override 
    public boolean canSeekForward() { 
     return true; 
    } 

    @Override 
    public int getCurrentPosition() { 
     return s3VideoPlayer.getCurrentPosition(); 
    } 

    @Override 
    public int getDuration() { 
     return s3VideoPlayer.getDuration();   
    } 

    @Override 
    public boolean isPlaying() { 
     return s3VideoPlayer.isPlaying(); 
    } 

@Override 
    public void pause() { 
     s3VideoPlayer.pause(); 
    } 

    @Override 
    public void seekTo(int pos) { 
     s3VideoPlayer.seekTo(pos); 

    } 

    @Override 
    public void start() { 
     s3VideoPlayer.start(); 

    } 


    } 

編輯#2

我一直在尋找到選項用於檢測視頻定位,發現http://wseemann.github.io/FFmpegMediaMetadataRetriever/

不幸的是,這並不似乎是獲得視頻的旋轉,即使我看着視頻文件的exif,我可以看到方向值爲90.因此,如果任何人有任何其他解決方案, 請分享!

編輯#3

這裏是別的東西,我試過了。我看到您可以爲MediaPlayer設置OnVideoSizeChangedListener以獲取視頻的寬度和高度。但是對於我使用的視頻,寬度總是大於高度,玩家知道是否根據旋轉EXIF值旋轉視頻。所以我不能使用這個...

+0

如果寬度總是大於高度,那麼您的視頻在橫向模式下總是** **!據我所知,縱向視頻是那些高度大於寬度的視頻... –

+0

這是不正確的。如果視頻的EXIF旋轉值不爲零,則會在某些播放器中旋轉,而不是其他播放器。這就是導致問題的原因。你可以看看這個視頻:https://dl.dropboxusercontent.com/u/1000620/portrait.mp4 – scientiffic

+0

你不能只使用替代佈局的肖像和風景? –

回答

2

我無法弄清楚旋轉問題,因此我最終更新了Rails應用程序,以便在更新視頻時保存視頻的旋轉。然後,當我從網站獲取視頻到Android應用程序時,我還檢索視頻的旋轉並相應地更新紋理視圖旋轉。這真的不是一個理想的方式,但我找不到任何其他解決方案。

這是它到底看起來像:

 // set scale for textureview 
     final Intent i = getIntent(); 
     videoRotation = i.getIntExtra("videoRotation", 0); 
     Log.d(TAG, "setting video rotation..."); 
     DisplayMetrics displaymetrics = new DisplayMetrics(); 
     getWindowManager().getDefaultDisplay().getMetrics(displaymetrics); 
     int h = displaymetrics.heightPixels; 
     int w = displaymetrics.widthPixels; 
     Log.d(TAG, "hxw: " + h + w); 
     LayoutParams videoLayoutParams = new LayoutParams(h, w); 
     videoLayoutParams.gravity = Gravity.CENTER; 
     s3TextureView.setScaleX(h/w);  
     s3TextureView.setRotation(Math.abs(360-videoRotation)); 
     s3TextureView.setLayoutParams(videoLayoutParams); 
     Log.d(TAG, "done setting video rotation"); 
0

你可以得到視頻的寬度和高度,然後你做一個測試 例如,如果(寬度> 800)和(!isTablet),然後強制該活動是風景。

0

能否下面的代碼幫助?

activity.setRequestedOrientation(videoView.getWidth() < videoView.getHeight() ? ActivityInfo.SCREEN_ORIENTATION_PORTRAIT : ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); 
相關問題