Nexus 6和MediaPlayer.VIDEO_SCALING_MODE_SCALE_TO_FIT_WITH_CROPPING);

嗨,我试图实现一个活动与video文件的背景。 下面发布的解决scheme是在大多数设备上工作,除了Nexus 6 Android 5.1。 video正在工作,缩放但没有裁剪,所以长宽比不被保留。

经过Galaxy Note,HTC One m7,Xperia Z3,Nexus 5testing。

这里是代码:

public class MainActivity extends ActionBarActivity implements SurfaceHolder.Callback, OnClickListener { private static final int VIDEO_START_HACK_DELAY = 0; private static final String BG_VIDEO_PATH = "/raw/construction"; private SurfaceView mSurface; private Button mTour, mLogin; private MediaPlayer mMediaPlayer; private Handler mHandler = new Handler(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_start_main); setupUI(); } private void setupUI() { mMediaPlayer = new MediaPlayer(); mSurface = (SurfaceView) findViewById(R.id.surface); SurfaceHolder holder = mSurface.getHolder(); holder.addCallback(this); mTour = (Button) findViewById(R.id.tour); mLogin = (Button) findViewById(R.id.login); mTour.setOnClickListener(this); mLogin.setOnClickListener(this); } @Override public void surfaceCreated(SurfaceHolder holder) { startVideo(holder); } @SuppressLint("NewApi") public void startVideo(SurfaceHolder holder) { String path = "android.resource://" + getPackageName() + BG_VIDEO_PATH; Uri uri = Uri.parse(path); try { android.view.ViewGroup.LayoutParams lp = mSurface.getLayoutParams(); mMediaPlayer.setDisplay(holder); mMediaPlayer.setDataSource(this, uri); mMediaPlayer.setVideoScalingMode(MediaPlayer.VIDEO_SCALING_MODE_SCALE_TO_FIT_WITH_CROPPING); mMediaPlayer.setLooping(true); mMediaPlayer.setOnPreparedListener(new OnPreparedListener() { @Override public void onPrepared(MediaPlayer mp) { mHandler.postDelayed(new Runnable() { @Override public void run() { mMediaPlayer.start(); } }, VIDEO_START_HACK_DELAY); } }); mMediaPlayer.prepareAsync(); } catch (Exception e) { Log.e("VID", "Problem starting video bg", e); } } @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { // TODO Auto-generated method stub } @Override public void surfaceDestroyed(SurfaceHolder holder) { // TODO Auto-generated method stub } @Override public void onBackPressed() { mSurface.setVisibility(View.INVISIBLE); mMediaPlayer.stop(); super.onBackPressed(); } @Override protected void onDestroy() { mMediaPlayer.stop(); mMediaPlayer.release(); super.onDestroy(); } } 

这里是布局文件:

 <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" > <SurfaceView android:id="@+id/surface" android:layout_width="fill_parent" android:layout_height="fill_parent" /> <LinearLayout android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:layout_marginBottom="40dp" android:gravity="center" android:orientation="vertical" > <Button android:id="@+id/tour" android:layout_height="wrap_content" android:layout_width="wrap_content" android:textAppearance="@style/Base.TextAppearance.AppCompat.Medium" android:padding="10dp" android:text="@string/ma_tour"/> <Button android:id="@+id/login" android:layout_height="wrap_content" android:layout_width="wrap_content" android:padding="10dp" android:textAppearance="@style/Base.TextAppearance.AppCompat.Medium" android:text="@string/ma_log_in"/> </LinearLayout> </RelativeLayout> 

目标sdk设置为22.你有没有经历过这样的行为,可以给任何build议?

Solutions Collecting From Web of "Nexus 6和MediaPlayer.VIDEO_SCALING_MODE_SCALE_TO_FIT_WITH_CROPPING);"

下面是我在我的一个应用程序中做到的:

  1. 在MediaPlayer对象上设置OnPreparedListener。

    mediaPlayer.setOnPreparedListener(本);

  2. 当调用public void onPrepared(MediaPlayer mp) ,调整SurfaceView大小,使其产生裁剪video的错觉。 Log.v(LOG_TAG,“onPrepared要求MediaPlayer”); //调整video的大小,使其适合屏幕int videoWidth = mInitialVideoPlayer.getVideoWidth(); int videoHeight = mInitialVideoPlayer.getVideoHeight(); float videoProportion =(float)videoWidth /(float)videoHeight;

     ViewGroup.LayoutParams lp = mSplashVideoSurfaceView.getLayoutParams(); // We always want to fill entire view port. So, we keep the smallest dimension and proportionately // scale the other dimension. if (videoWidth < videoHeight) { lp.width = UiUtils.sScreenWidth; lp.height = (int) ((float) UiUtils.sScreenWidth / videoProportion); } else { lp.width = (int) (videoProportion * (float) UiUtils.sScreenHeight);If you are targetting API level 14 and above, <code>TextureView</code> allows you to play cropped video lp.height = UiUtils.sScreenHeight; } Log.v(LOG_TAG, "old video size: " + videoWidth + ", " + videoHeight); Log.v(LOG_TAG, "screen size: " + UiUtils.sScreenWidth + ", " + UiUtils.sScreenHeight); Log.v(LOG_TAG, "new video size: " + lp.width + ", " + lp.height); mSplashVideoSurfaceView.setLayoutParams(lp);