Android如何在SurfaceView中调整视频宽度和高度以适应MediaPlayer?

5
想要在Surface视图中调整视频大小
我正在使用Surface视图和持有器在Media Player中播放视频...
// 但是在一些设备上实现MediaPlayerControl,比如Micromax、iball、Akash平板电脑,它会给出抽象方法不可用的错误,这个问题已经被ACRA bug tracking追踪。
现在我想解决以下问题:
- 如何在所有设备上激活媒体播放器控件,避免由于某些设备中媒体控制器的抽象方法而导致崩溃。 - 如何调整视频的Surface视图大小。
代码在Samsung Galaxy GT P1000 OS 2.2和一些更便宜的设备WorldTeck等上都可以正常运行。
但在Creative Ziio 7 OS版本为2.2.1 (480*800),分辨率密度为160 dpi时,视频似乎被放大并且从边缘处被裁剪。
以下是示例代码:
/* Media Player Control is commented due to force close in some devices say *micromax,Creative ziio, akash etc */

    public class VideoViewerActivity extends Activity implements
            OnBufferingUpdateListener, OnCompletionListener, OnPreparedListener,
            OnVideoSizeChangedListener, SurfaceHolder.Callback {
        // implements  ERROR in some devices , MediaPlayerControl
        private static final String TAG = "MediaPlayerDemo";
        private int mVideoWidth;
        private int mVideoHeight;
        private MediaPlayer mMediaPlayer;
        private SurfaceView mPreview;
        private SurfaceHolder holder;
        private String path = "";
        private Bundle extras;
        private static final String MEDIA = "media";
        private static final int LOCAL_AUDIO = 1;
        private static final int STREAM_AUDIO = 2;
        private static final int RESOURCES_AUDIO = 3;
        private static final int LOCAL_VIDEO = 4;
        private static final int STREAM_VIDEO = 5;
        private boolean mIsVideoSizeKnown = false;
        private boolean mIsVideoReadyToBePlayed = false;
        /* ERROR In Abstract method implementation in the other devices */
        // private MediaController mediaController;
        private Context context;
        private final Handler handler = new Handler();

        /**
         * 
         * Called when the activity is first created.
         */
        @Override
        public void onCreate(Bundle icicle) {
            super.onCreate(icicle);
            setContentView(R.layout.video_layout);
            context = this;
            path = getIntent().getExtras().getString("media");

            Log.v("arpit", "path " + path);
            mPreview = (SurfaceView) findViewById(R.id.surfaceview1);
            holder = mPreview.getHolder();
            holder.addCallback(this);
            holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
            extras = getIntent().getExtras();

        }

        private void playVideo() {
            doCleanUp();
            try {

                // Create a new media player and set the listeners
                File f = new File(path);
                // FileInputStream in = new FileInputStream(f);

                RandomAccessFile randomAccessFile = new RandomAccessFile(f, "r");
                // randomAccessFile.skipBytes(1024);
                FileDescriptor fileDescriptor = randomAccessFile.getFD();

                mMediaPlayer = new MediaPlayer();
                mMediaPlayer.setDataSource(fileDescriptor, Constant.key1.length
                        + Data.deviceID.length(), f.length());

                mMediaPlayer.setDisplay(holder);
                mMediaPlayer.prepare();
                mMediaPlayer.setOnBufferingUpdateListener(this);
                mMediaPlayer.setOnCompletionListener(this);
                mMediaPlayer.setOnPreparedListener(this);
                mMediaPlayer.setOnVideoSizeChangedListener(this);
                mMediaPlayer.setScreenOnWhilePlaying(true);

                // mediaController = new MediaController(this);
                mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);

            } catch (Exception e) {
                Log.e(TAG, "error: " + e.getMessage(), e);
                Toast.makeText(context, "supported video was not found",
                        Toast.LENGTH_SHORT).show();
                finish();
            }
        }

        public void onVideoSizeChanged(MediaPlayer mp, int width, int height) {
            Log.v(TAG, "onVideoSizeChanged called");
            if (width == 0 || height == 0) {
                Log.e(TAG, "invalid video width(" + width + ") or height(" + height
                        + ")");
                return;
            }
            mIsVideoSizeKnown = true;
            mVideoWidth = width;
            mVideoHeight = height;
            if (mIsVideoReadyToBePlayed && mIsVideoSizeKnown) {
                startVideoPlayback();
            }
        }


        public void surfaceDestroyed(SurfaceHolder surfaceholder) {
            Log.d(TAG, "surfaceDestroyed called");
        }

        public void surfaceCreated(SurfaceHolder holder) {
            Log.d(TAG, "surfaceCreated called");
            playVideo();

        }

        private void doCleanUp() {
            mVideoWidth = 0;
            mVideoHeight = 0;
            mIsVideoReadyToBePlayed = false;
            mIsVideoSizeKnown = false;
        }

        private void startVideoPlayback() {
            Log.v(TAG, "startVideoPlayback");
//also tried and used the below line but nothing good 


// holder.setFixedSize(480, 800);

holder.setFixedSize(mVideoWidth, mVideoHeight);

mMediaPlayer.start();

        }


    }

尝试使用我的答案。希望能对你有所帮助。 - Chirag Shah
2个回答

2

我在代码中使用了TextureView而不是SurfaceView(它允许旋转视频),并适当地设置了其setScale{X|Y}():

@Override
public void onVideoSizeChanged(MediaPlayer mp, int w, int h) {
    if (w > 0 && h > 0) {
        RelativeLayout.LayoutParams l;
        DisplayMetrics metrics = new DisplayMetrics();
        getWindowManager().getDefaultDisplay().getMetrics(metrics);
        l = new RelativeLayout.LayoutParams(metrics.heightPixels, metrics.widthPixels);
        l.addRule(RelativeLayout.CENTER_IN_PARENT, -1);
        float scale = (metrics.heightPixels * 1.0f) / (metrics.widthPixels * 1.0f);
        videoView.setScaleX(scale);
        videoView.setLayoutParams(l);
        Log.d(YourApp.TAG, "video size: " + mp.getVideoWidth() + "x" + mp.getVideoHeight() + " vertical scale: " + scale);
    }
}

请注意,我已经旋转了我的视频,这就是为什么我设置了X轴的比例。

1

嗨,arpit,我也在使用你提到的设备播放视频文件,但是当我对视频播放器应用控件时遇到了同样的问题(抽象方法不可用)。

根据我对这个主题的研究,我得出结论,这些定制的Android操作系统和这些设备的硬件不兼容,因为它们与三星设备相比质量非常差,所以许多方法虽然在Android操作系统中,但不受此类设备支持。

因此,我认为在这些设备上没有解决这些问题的方法。

请尝试在开发任何项目时专注于使用标准设备,这可能会对您有很大帮助。

谢谢。 :)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接