surfaceview播放视频的拉伸视图 [英] surfaceview playing video as stretched view

查看:481
本文介绍了surfaceview播放视频的拉伸视图的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我现在用的是mediaplayer.xml播放视频文件

I am using the mediaplayer.xml to play the video file

<?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类 虽然打在纵向模式下的视频看来,视频拉伸之一。我想播放的视频垂直居中,不应该占据整个屏幕,然后在横向模式应该以全屏模式播放。

The following MediaPlayerActivity class using SurfaceView and MediaPlayer While playing video in portrait mode it seems that the video stretched one. I want to play the video vertically center and should not occupy the full screen and then in landscape mode should play in full screen mode.

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


}

}

推荐答案

我遇到了同样的问题,我看看 VideoView 源$ C ​​$ C API中23后,我找到了好的方法,这里是我的解决方案,我们可以创建一个自定义的 SurfaceView 和覆盖 onMeasure(),那么在这里你去,使用 VideoSurfaceView 玩视频。

I met the same problem,after i look into VideoView source code in API 23,i found the good method,here is my solution,we can create a custom SurfaceView and override onMeasure(),then here you go,use VideoSurfaceView to play the video.

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

}

这篇关于surfaceview播放视频的拉伸视图的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆