2014-01-18 76 views
1

我使用mediaplayer.xml播放視頻文件surfaceview播放視頻的拉伸視圖

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
android:id="@+id/MainView" 
android:layout_width="fill_parent" 
android:layout_height="fill_parent" 
android:background="#4d4d4d" 
android:gravity="center" 
android:keepScreenOn="true" 
android:orientation="vertical" > 

<SurfaceView 
    android:id="@+id/surfaceView" 
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
    android:layout_gravity="center" 
    /> 

</LinearLayout> 

使用SurfaceView和MediaPlayer的 以下MediaPlayerActivity類雖然打在縱向模式下的視頻看來,視頻拉伸一個。我想垂直播放視頻,不應占用全屏幕,然後在橫向模式下播放全屏模式。

public class MediaPlayerActivity extends Activity implements OnCompletionListener, 
OnErrorListener, OnInfoListener, OnBufferingUpdateListener, 
OnPreparedListener, OnSeekCompleteListener, SurfaceHolder.Callback, 
MediaController.MediaPlayerControl { 

private MediaController controller; 
Display currentDisplay; 
private SurfaceView surfaceView; 
private SurfaceHolder surfaceHolder; 
private MediaPlayer mediaPlayer; 

int videoWidth = 0; 
int videoHeight = 0; 
boolean readyToPlay = false; 

private String streamingVideoUrl; 

private ProgressDialog dialog; 

public final String TAG = "VIDEO_PLAYER"; 

@Override 
protected void onCreate(Bundle savedInstanceState) { 

    super.onCreate(savedInstanceState); 
    Log.d(TAG,"Media player activity called "); 
    setContentView(R.layout.mediaplayer); 

    if(getIntent() != null){ 
     streamingVideoUrl = getIntent().getStringExtra("stream_url"); 
    } 

    surfaceView = (SurfaceView) findViewById(R.id.surfaceView); 
    surfaceView.setOnClickListener(surViewClickListener); 

    surfaceHolder = surfaceView.getHolder(); 

    surfaceHolder.addCallback(this); 

    surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); 
    /*setVideoSize();*/ 
    try { 
    mediaPlayer = new MediaPlayer(); 

    mediaPlayer.setOnCompletionListener(this); 
    mediaPlayer.setOnErrorListener(this); 
    mediaPlayer.setOnInfoListener(this); 
    mediaPlayer.setOnPreparedListener(this); 
    mediaPlayer.setOnSeekCompleteListener(this); 


    mediaPlayer.setOnBufferingUpdateListener(this); 
    mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC); 
    //Log.d(TAG,"Returned by getDatasource :"+getDataSource(streamingVideoUrl)); 
     mediaPlayer.setDataSource(streamingVideoUrl); 
    } catch (IllegalArgumentException e) { 

     e.printStackTrace(); 
    } catch (SecurityException e) { 

     e.printStackTrace(); 
    } catch (IllegalStateException e) { 

     e.printStackTrace(); 
    } catch (IOException e) { 

     e.printStackTrace(); 
    } 

    catch(Exception e) 
    { 
     e.printStackTrace(); 
    } 

    currentDisplay = getWindowManager().getDefaultDisplay(); 
    controller = new MediaController(this); 

    dialog = new ProgressDialog(this); 
    //dialog.setMessage("Preparing File to Streaming"); 
    dialog.setProgressStyle(ProgressDialog.STYLE_SPINNER); 
    dialog.setCanceledOnTouchOutside(false); 
    if(this!= null && !this.isFinishing()){ 

     dialog.show(); 
    } 

    handler.postDelayed(r, 100); 
} 

/*private void setVideoSize() { 


    try { 
     // // Get the dimensions of the video 
     int videoWidth = mediaPlayer.getVideoWidth(); 
     int videoHeight = mediaPlayer.getVideoHeight(); 
     float videoProportion = (float) videoWidth/(float) videoHeight; 

     // Get the width of the screen 
     int screenWidth = getWindowManager().getDefaultDisplay().getWidth(); 
     int screenHeight = getWindowManager().getDefaultDisplay().getHeight(); 
     float screenProportion = (float) screenWidth/(float) screenHeight; 

     // Get the SurfaceView layout parameters 
     android.view.ViewGroup.LayoutParams lp = surfaceView.getLayoutParams(); 
     if (videoProportion > screenProportion) { 
      lp.width = screenWidth; 
      lp.height = (int) ((float) screenWidth/videoProportion); 
     } else { 
      lp.width = (int) (videoProportion * (float) screenHeight); 
      lp.height = screenHeight; 
     } 
     // Commit the layout parameters 
     surfaceView.setLayoutParams(lp); 
    } catch (Exception e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 
}*/ 


/*//coded by Karthikeyan V 
    //converting url to byte 
    private String getDataSource(String path) throws IOException { 
     Log.d(TAG,"getDataSource called"); 
     if (!URLUtil.isNetworkUrl(path)) { 
      return path; 
     } else { 
      URL url = new URL(path); 
      URLConnection cn = url.openConnection(); 
      cn.connect(); 
      InputStream stream = cn.getInputStream(); 
      if (stream == null) 
       throw new RuntimeException("stream is null"); 
      File temp = File.createTempFile("mediaplayertmp", "dat"); 
      temp.deleteOnExit(); 
      String tempPath = temp.getAbsolutePath(); 
      FileOutputStream out = new FileOutputStream(temp); 
      byte buf[] = new byte[128]; 
      do { 
       int numread = stream.read(buf); 
       if (numread <= 0) 
        break; 
       out.write(buf, 0, numread); 
      } while (true); 
      try { 
       stream.close(); 
      } catch (IOException ex) { 
       Log.e(TAG, "error: " + ex.getMessage(), ex); 
      } 
      Log.d(TAG,"temp path :"+tempPath); 
      return tempPath; 
     } 
    }*/ 


@Override 
public boolean canPause() { 

    return true; 
} 

@Override 
public boolean canSeekBackward() { 

    return true; 
} 

@Override 
public boolean canSeekForward() { 

    return true; 
} 

@Override 
public int getBufferPercentage() { 

    return 0; 
} 

@Override 
public int getCurrentPosition() { 

    if(mediaPlayer !=null) 
     return mediaPlayer.getCurrentPosition(); 
    else 
     return 0; 
} 

@Override 
public int getDuration() { 

    return mediaPlayer.getDuration(); 
} 

@Override 
public boolean isPlaying() { 

    return mediaPlayer.isPlaying(); 
} 

@Override 
public void pause() { 

    if (mediaPlayer != null) { 
     if (mediaPlayer.isPlaying()) { 
      mediaPlayer.pause(); 
     } 
    } 
} 

@Override 
public void seekTo(int pos) { 

    mediaPlayer.seekTo(pos); 
} 

@Override 
public void start() { 

    mediaPlayer.start(); 
} 

@Override 
public void surfaceChanged(SurfaceHolder holder, int format, int width, 
     int height) { 
    if(Constants.DEBUG) 
     Log.v(TAG, "Media Flow surfaceChanged Called"); 
} 
@Override 
public void surfaceCreated(SurfaceHolder holder) { 

    if(Constants.DEBUG) 
     Log.v(TAG, "Media Flow surfaceCreated Called"); 
    mediaPlayer.setDisplay(holder); 

    try { 
     mediaPlayer.prepareAsync(); 
    } catch (IllegalStateException e) { 
     if(Constants.DEBUG) 
      Log.v(TAG, "Media Flow IllegalStateException " + e.getMessage()); 
     finish(); 
    } 

    if(Constants.DEBUG) 
     Log.d(TAG, "Media Flow MediaPlayer Preparing"); 

} 

@Override 
public void surfaceDestroyed(SurfaceHolder holder) { 
    if(Constants.DEBUG) 
     Log.v(TAG, "Media Flow surfaceDestroyed Called"); 
} 


@Override 
public void onSeekComplete(MediaPlayer mp) { 
    if(Constants.DEBUG) 
     Log.v(TAG, "Media Flow onSeekComplete Called"); 
} 

@Override 
public void onPrepared(MediaPlayer mp) { 

    if(Constants.DEBUG) 
     Log.v(TAG, "Media Flow onPrepared Called"); 

    // dismissProgressLoading(); 

    controller.setMediaPlayer(this); 
    controller.setAnchorView(this.findViewById(R.id.MainView)); 
    controller.setEnabled(true); 
    controller.show(); 
    mp.start(); 

} 

@Override 
public void onBufferingUpdate(MediaPlayer mp, int percent) { 

    if(Constants.DEBUG) 
     Log.v(TAG, "Media Flow MediaPlayer Buffering: " + percent + "%"); 
    dismissProgressLoading(); 
} 

@Override 
public boolean onInfo(MediaPlayer mp, int whatInfo, int extra) { 
    // 
    dismissProgressLoading(); 

    if(Constants.DEBUG) 
    { 
     if (whatInfo == MediaPlayer.MEDIA_INFO_BAD_INTERLEAVING) { 
      if(Constants.DEBUG) 
       Log.v(TAG, "Media Flow Media Info, Media Info Bad Interleaving " + extra); 
     } else if (whatInfo == MediaPlayer.MEDIA_INFO_NOT_SEEKABLE) { 
      if(Constants.DEBUG) 
       Log.v(TAG, "Media Flow Media Info, Media Info Not Seekable " + extra); 
     } else if (whatInfo == MediaPlayer.MEDIA_INFO_UNKNOWN) { 
      Log.v(TAG, "Media Flow Media Info, Media Info Unknown " + extra); 
     } else if (whatInfo == MediaPlayer.MEDIA_INFO_VIDEO_TRACK_LAGGING) { 
      Log.v(TAG, "Media Flow MediaInfo, Media Info Video Track Lagging " + extra); 
     } else if (whatInfo == MediaPlayer.MEDIA_INFO_METADATA_UPDATE) { 
      Log.v(TAG, "Media Flow MediaInfo, Media Info Metadata Update " + extra); 
     } 
    } 

    return false; 
} 

@Override 
public boolean onError(MediaPlayer mp, int what, int extra) { 
    // TODO Auto-generated method stub 

    dismissProgressLoading(); 

    StringBuilder sb = new StringBuilder(); 
    sb.append("Media Player Error: "); 
    switch (what) { 
    case MediaPlayer.MEDIA_ERROR_NOT_VALID_FOR_PROGRESSIVE_PLAYBACK: 
     sb.append("Not Valid for Progressive Playback"); 
     break; 
    case MediaPlayer.MEDIA_ERROR_SERVER_DIED: 
     sb.append("Server Died"); 
     break; 
    case MediaPlayer.MEDIA_ERROR_UNKNOWN: 
     sb.append("Media Error Unknown"); 
     break; 
    default: 
     sb.append(" Non standard ("); 
     sb.append(what); 
     sb.append(")"); 
    } 
    //sb.append(" (" + what + ") "); 
    sb.append(extra); 

    showErrorDialog("Cannot play video", sb.toString()); 


    return true; 
} 

void dismissProgressLoading() { 
    if (dialog != null && dialog.isShowing()) { 
     dialog.dismiss(); 
    } 
} 

@Override 
public void onCompletion(MediaPlayer mp) { 
    if(Constants.DEBUG) 
    Log.v(TAG, "Media Flow onCompletion Called"); 
    dismissProgressLoading(); 
    onBackPressed(); 
} 


@Override 
public void onBackPressed() { 
    // TODO Auto-generated method stub 
    super.onBackPressed(); 
} 


final Runnable r = new Runnable() { 
    public void run() { 

     if (mediaPlayer != null) { 
      if (mediaPlayer.isPlaying() 
        && mediaPlayer.getCurrentPosition() > 0) { 
       if(Constants.DEBUG) 
       Log.d(TAG, "isPlaying : " + mediaPlayer.isPlaying()); 
       if(Constants.DEBUG) 
       Log.d(TAG, 
         "currentPosition : " 
           + mediaPlayer.getCurrentPosition()); 

       handler.sendEmptyMessage(0); 
      } else { 
       handler.postDelayed(this, 100); 
      } 
     } 
    } 
}; 

Handler handler = new Handler() { 

    public void handleMessage(Message msg) { 
     dismissProgressLoading(); 
    } 

}; 

@Override 
protected void onResume() { 

    if(Constants.SHOULD_FINISH_APPLICATION) 
     finish(); 
    super.onResume(); 
} 

@Override 
protected void onRestart() {   
    super.onRestart(); 

} 

protected void onPause() { 
    super.onPause(); 
    pause(); 
} 

@Override 
protected void onDestroy() { 

    super.onDestroy(); 

    dismissProgressLoading(); 

    if (mediaPlayer != null) { 
     mediaPlayer.stop(); 
     mediaPlayer.release(); 
     mediaPlayer = null; 
    } 
    if(controller !=null) 
    { 
     controller.hide(); 
    } 
} 

OnClickListener surViewClickListener = new OnClickListener() { 

    @Override 
    public void onClick(View v) { 


     if (controller != null) { 
      if (controller.isShowing()) { 
       controller.hide(); 

      } else { 
       controller.show(); 

      } 
     } 
    } 
}; 

@SuppressWarnings("deprecation") 
void showErrorDialog(String title, String message) { 
    AlertDialog alertDialog = new AlertDialog.Builder(this).create(); 

    // Setting Dialog Title 
    alertDialog.setTitle(title); 

    // Setting Dialog Message 
    alertDialog.setMessage(message); 

    // Setting Icon to Dialog 
    alertDialog.setIcon(android.R.drawable.ic_dialog_alert); 

    // Setting OK Button 
    alertDialog.setButton("OK", new DialogInterface.OnClickListener() { 
     public void onClick(DialogInterface dialog, int which) { 
      // Write your code here to execute after dialog closed 

      dialog.dismiss(); 
      finish(); 
     } 
    }); 


    // Showing Alert Message 
    if(this!= null && !this.isFinishing()){ 
     alertDialog.show(); 
    } 


} 

}

+0

有沒有機會找到解決方案?我正在努力解決同樣的問題。可以修復然後預覽,但然後我的記錄器失敗停止 – Chris

+0

@Chris我已經使用VideoView而不是SurfaceView。我不確定這是否是一個正確的解決方案。我沒有實現記錄器選項。 –

+0

好東西,謝謝你讓我知道哥們!還沒有看VideoView,絕對值得研究。總是很好學習新事物 – Chris

回答

1

我遇到了同樣的問題之前,之後我看着VideoView源代碼,API 23,我找到了好方法, here is my solution,我們可以創建一個自定義SurfaceView並覆蓋onMeasure(),然後在這裏,使用VideoSurfaceView來播放視頻。

public class VideoSurfaceView extends SurfaceView implements MediaPlayer.OnVideoSizeChangedListener { 
    private int mVideoWidth; 
    private int mVideoHeight; 

    public VideoSurfaceView(Context context) { 
     super(context); 
    } 

    public VideoSurfaceView(Context context, AttributeSet attrs) { 
     super(context, attrs); 
    } 

    public VideoSurfaceView(Context context, AttributeSet attrs, int defStyleAttr) { 
     super(context, attrs, defStyleAttr); 
    } 

    /** 
    * Set video size. 
    * 
    * @see MediaPlayer#getVideoWidth() 
    * @see MediaPlayer#getVideoHeight() 
    */ 
    public void setVideoSize(int videoWidth, int videoHeight) { 
     mVideoWidth = videoWidth; 
     mVideoHeight = videoHeight; 
    } 

    @Override 
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 
     //Log.i("@@@@", "onMeasure(" + MeasureSpec.toString(widthMeasureSpec) + ", " 
     //  + MeasureSpec.toString(heightMeasureSpec) + ")"); 

     int width = getDefaultSize(mVideoWidth, widthMeasureSpec); 
     int height = getDefaultSize(mVideoHeight, heightMeasureSpec); 
     if (mVideoWidth > 0 && mVideoHeight > 0) { 

      int widthSpecMode = MeasureSpec.getMode(widthMeasureSpec); 
      int widthSpecSize = MeasureSpec.getSize(widthMeasureSpec); 
      int heightSpecMode = MeasureSpec.getMode(heightMeasureSpec); 
      int heightSpecSize = MeasureSpec.getSize(heightMeasureSpec); 

      if (widthSpecMode == MeasureSpec.EXACTLY && heightSpecMode == MeasureSpec.EXACTLY) { 
       // the size is fixed 
       width = widthSpecSize; 
       height = heightSpecSize; 

       // for compatibility, we adjust size based on aspect ratio 
       if (mVideoWidth * height < width * mVideoHeight) { 
        //Log.i("@@@", "image too wide, correcting"); 
        width = height * mVideoWidth/mVideoHeight; 
       } else if (mVideoWidth * height > width * mVideoHeight) { 
        //Log.i("@@@", "image too tall, correcting"); 
        height = width * mVideoHeight/mVideoWidth; 
       } 
      } else if (widthSpecMode == MeasureSpec.EXACTLY) { 
       // only the width is fixed, adjust the height to match aspect ratio if possible 
       width = widthSpecSize; 
       height = width * mVideoHeight/mVideoWidth; 
       if (heightSpecMode == MeasureSpec.AT_MOST && height > heightSpecSize) { 
        // couldn't match aspect ratio within the constraints 
        height = heightSpecSize; 
       } 
      } else if (heightSpecMode == MeasureSpec.EXACTLY) { 
       // only the height is fixed, adjust the width to match aspect ratio if possible 
       height = heightSpecSize; 
       width = height * mVideoWidth/mVideoHeight; 
       if (widthSpecMode == MeasureSpec.AT_MOST && width > widthSpecSize) { 
        // couldn't match aspect ratio within the constraints 
        width = widthSpecSize; 
       } 
      } else { 
       // neither the width nor the height are fixed, try to use actual video size 
       width = mVideoWidth; 
       height = mVideoHeight; 
       if (heightSpecMode == MeasureSpec.AT_MOST && height > heightSpecSize) { 
        // too tall, decrease both width and height 
        height = heightSpecSize; 
        width = height * mVideoWidth/mVideoHeight; 
       } 
       if (widthSpecMode == MeasureSpec.AT_MOST && width > widthSpecSize) { 
        // too wide, decrease both width and height 
        width = widthSpecSize; 
        height = width * mVideoHeight/mVideoWidth; 
       } 
      } 
     } else { 
      // no size yet, just adopt the given spec sizes 
     } 
     setMeasuredDimension(width, height); 
    } 

    @Override 
    public void onVideoSizeChanged(MediaPlayer mp, int width, int height) { 
     mVideoWidth = mp.getVideoWidth(); 
     mVideoHeight = mp.getVideoHeight(); 
     if (mVideoWidth != 0 && mVideoHeight != 0) { 
      getHolder().setFixedSize(mVideoWidth, mVideoHeight); 
      requestLayout(); 
     } 
    } 
} 
1
handleAspectRatio() { 
    int surfaceView_Width = surfaceView.getWidth(); 
    int surfaceView_Height = surfaceView.getHeight(); 

    float video_Width = mediaPlayer.getVideoWidth(); 
    float video_Height = mediaPlayer.getVideoHeight(); 

    float ratio_width = surfaceView_Width/video_Width; 
    float ratio_height = surfaceView_Height/video_Height; 
    float aspectratio = video_Width/video_Height; 

    LayoutParams layoutParams = surfaceView.getLayoutParams(); 

    if (ratio_width > ratio_height){ 
     layoutParams.width = (int) (surfaceView_Height * aspectratio); 
     layoutParams.height = surfaceView_Height; 
    }else{ 
     layoutParams.width = surfaceView_Width; 
     layoutParams.height = (int) (surfaceView_Width/aspectratio); 
    } 

    surfaceView.setLayoutParams(layoutParams); 
} 

調用上面的函數調用

mediaPlayer.start();