代码之家  ›  专栏  ›  技术社区  ›  Mark B

VideoView上的MediaController定位

  •  58
  • Mark B  · 技术社区  · 14 年前

    我有一个视频视图,它占据了活动的上半部分,在屏幕的下半部分显示一些图像和文本。活动开始时,我正在视频视图中播放rtsp视频流。我已通过以下代码将MediaController连接到VideoView:

        MediaController controller = new MediaController(this);
        controller.setAnchorView(this.videoView);
        controller.setMediaPlayer(this.videoView);
        this.videoView.setMediaController(controller);
    

    当我点击VideoView在屏幕上调出MediaController时,我期望播放控件出现在VideoView的底部区域(MediaController的底部甚至与VideoView的底部重叠)。相反,MediaController在屏幕的下方弹出,覆盖了视频视图下方的一些图形和文本。

    9 回复  |  直到 14 年前
        1
  •  7
  •   CommonsWare    13 年前

    坦白说,我只会写我自己的控制器。事实上, I did once .

    话说回来,试试看 setAnchorView() --通过我对源代码的阅读 MediaController

        2
  •  52
  •   Attacktive    10 年前

    video.setOnPreparedListener(new OnPreparedListener() {
            @Override
            public void onPrepared(MediaPlayer mp) {
                mp.setOnVideoSizeChangedListener(new OnVideoSizeChangedListener() { 
                @Override
                public void onVideoSizeChanged(MediaPlayer mp, int width, int height) {
                    /*
                     * add media controller
                     */
                    mc = new MediaController(YourActivity.this);
                    video.setMediaController(mc);
                    /*
                     * and set its position on screen
                     */
                    mc.setAnchorView(video);
                }
            });
        }
    });
    
        3
  •  22
  •   bughi    10 年前

    我找到了很简单的解决办法。

        MediaController mc = new MediaController(context);
        videoView.setMediaController(mc);
    
        FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
        lp.gravity = Gravity.BOTTOM;
        mc.setLayoutParams(lp);
    
        ((ViewGroup) mc.getParent()).removeView(mc);
    
        ((FrameLayout) findViewById(R.id.videoViewWrapper)).addView(mc);
    

    编辑:自从我发布了这个答案,我遇到了很多问题,让它隐藏和控制它的大小,所以我最终做的是我只是创建了我自己的控制,我可以动画和工作没有头痛的布局

        4
  •  12
  •   Hafiz    11 年前

    下面是我在不编写完整的自定义控制器(仅重写 onSizeChanged (要向上移动锚点的MediaController的名称):

    使用FrameLayout作为MediaContoller的锚点,将其与VideoView打包,如下所示:

    <RelativeLayout
        android:id="@+id/videoLayout"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1.3"
        android:layout_gravity="center"
        android:background="#000000">
    
        <VideoView
            android:id="@+id/videoView1"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_centerInParent="true" />
    
        <FrameLayout android:id="@+id/controllerAnchor"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentBottom="true"
            android:layout_alignParentLeft="true" 
            android:layout_alignParentRight="true" 
            />
    
    </RelativeLayout>
    

    创建自定义的MediaController,当FrameLayout的大小更改时,它将向上移动FrameLayout(锚定到它的MediaController将跟随它):

    public class MyMediaController extends MediaController
    {
        private FrameLayout anchorView;
    
    
        public MyMediaController(Context context, FrameLayout anchorView)
        {
            super(context);
            this.anchorView = anchorView;       
        }
    
        @Override
        protected void onSizeChanged(int xNew, int yNew, int xOld, int yOld)
        {
            super.onSizeChanged(xNew, yNew, xOld, yOld);
    
            RelativeLayout.LayoutParams lp = (RelativeLayout.LayoutParams) anchorView.getLayoutParams();
            lp.setMargins(0, 0, 0, yNew);
    
            anchorView.setLayoutParams(lp);
            anchorView.requestLayout();
        }       
    }
    

    使用上面的自定义控制器代替标准控制器,然后将其锚定到FrameLayout:

    protected void onCreate(Bundle savedInstanceState)
    {
    
        //...
    
        videoView = (VideoView) findViewById(R.id.videoView1);      
        videoController = new MyMediaController(this, (FrameLayout) findViewById(R.id.controllerAnchor));               
        videoView.setMediaController(videoController);      
    
        //...       
    }
    
    public void onPrepared(MediaPlayer mp) 
    {
        videoView.start();              
    
        FrameLayout controllerAnchor = (FrameLayout) findViewById(R.id.controllerAnchor);
        videoController.setAnchorView(controllerAnchor);                
    }
    
        5
  •  9
  •   Rongan    13 年前

    mediaController.setPadding(0, 0, 0, px);
    

    将mediacontroller视图设置为所需位置。 希望这对你有帮助。

        6
  •  6
  •   Vishnu Priyaa    6 年前

    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context="com.example.hp.videoplayer.MainActivity">
    
        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content">
    
            <VideoView
                android:layout_width="300dp"
                android:layout_height="180dp"
                android:id="@+id/player"
                android:layout_marginTop="40dp"
                android:layout_centerHorizontal="true"/>
    
        </LinearLayout>
    
    </RelativeLayout>
    
        7
  •  5
  •   Anh Duy    10 年前
        //It work good with me
    
    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent" >
    
        <VideoView
            android:id="@+id/videoview"
            android:layout_width="640dp"
            android:layout_height="400dp"
            android:layout_centerInParent="true" >
        </VideoView>
    
            <FrameLayout
                android:id="@+id/videoViewWrapper"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_alignParentBottom="true" >
            </FrameLayout>
    
        </RelativeLayout>
    
    package com.example.videoview;
    
    import android.app.Activity;
    import android.content.res.Configuration;
    import android.media.MediaPlayer;
    import android.media.MediaPlayer.OnCompletionListener;
    import android.media.MediaPlayer.OnPreparedListener;
    import android.media.MediaPlayer.OnVideoSizeChangedListener;
    import android.os.Bundle;
    import android.os.Handler;
    import android.view.MotionEvent;
    import android.view.View;
    import android.view.View.OnTouchListener;
    import android.view.ViewGroup;
    import android.widget.FrameLayout;
    import android.widget.MediaController;
    import android.widget.RelativeLayout;
    import android.widget.RelativeLayout.LayoutParams;
    import android.widget.Toast;
    import android.widget.VideoView;
    
    public class MainActivity extends Activity {
    
        // private String path = "http://clips.vorwaerts-gmbh.de/VfE_html5.mp4";
        private String path = "http://2387227f13276d2e8940-fbe0b8d9df729a57ca0a851a69d15ebb.r55.cf1.rackcdn.com/hero_2012_demo.mp4";
    
        private VideoView mVideoView;
    
        MediaController mc;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            if (mVideoView != null)
                return;
            /**
             * TODO: Set the path variable to a streaming video URL or a local media
             * file path.
             */
    
            mVideoView = (VideoView) findViewById(R.id.videoview);
            mVideoView.setOnCompletionListener(new OnCompletionListener() {
    
                @Override
                public void onCompletion(MediaPlayer mp) {
                    Toast.makeText(MainActivity.this, "The End", Toast.LENGTH_LONG)
                            .show();
                }
            });
    
            if (path == "") {
                // Tell the user to provide a media file URL/path.
                Toast.makeText(
                        MainActivity.this,
                        "Please edit MainActivity, and set path"
                                + " variable to your media file URL/path",
                        Toast.LENGTH_LONG).show();
    
            } else {
                /*
                 * Alternatively,for streaming media you can use
                 * mVideoView.setVideoURI(Uri.parse(path));
                 */
                mVideoView.setVideoPath(path);
    
                mVideoView
                        .setMediaController(new MediaController(MainActivity.this));
                mVideoView.requestFocus();
    
                mVideoView.setOnPreparedListener(new OnPreparedListener() {
    
                    @Override
                    public void onPrepared(MediaPlayer mp) {
                        // TODO Auto-generated method stub
                        mp.setOnVideoSizeChangedListener(new OnVideoSizeChangedListener() {
                            @Override
                            public void onVideoSizeChanged(MediaPlayer mp,
                                    int width, int height) {
                                /*
                                 * add media controller
                                 */
                                mc = new MediaController(MainActivity.this);
                                mVideoView.setMediaController(mc);
                                /*
                                 * and set its position on screen
                                 */
                                mc.setAnchorView(mVideoView);
    
                                ((ViewGroup) mc.getParent()).removeView(mc);
    
                                ((FrameLayout) findViewById(R.id.videoViewWrapper))
                                        .addView(mc);
                                mc.setVisibility(View.INVISIBLE);
                            }
                        });
                        mVideoView.start();
                    }
                });
    
                mVideoView.setOnTouchListener(new OnTouchListener() {
    
                    @Override
                    public boolean onTouch(View v, MotionEvent event) {
                        // TODO Auto-generated method stub
                        if (mc != null) {
                            mc.setVisibility(View.VISIBLE);
                            new Handler().postDelayed(new Runnable() {
    
                                @Override
                                public void run() {
                                    mc.setVisibility(View.INVISIBLE);
                                }
                            }, 2000);
                        }
    
                        return false;
                    }
                });
    
            }
        }
    
        private RelativeLayout.LayoutParams paramsNotFullscreen, paramsFullscreen;
    
        /**
         * handle with the configChanges attribute in your manifest
         */
        @Override
        public void onConfigurationChanged(Configuration newConfig) {
            // TODO Auto-generated method stub
            super.onConfigurationChanged(newConfig);
    
            if (paramsFullscreen == null) {
                paramsNotFullscreen = (RelativeLayout.LayoutParams) mVideoView
                        .getLayoutParams();
                paramsFullscreen = new LayoutParams(paramsNotFullscreen);
                paramsFullscreen.setMargins(0, 0, 0, 0);
                paramsFullscreen.height = ViewGroup.LayoutParams.MATCH_PARENT;
                paramsFullscreen.width = ViewGroup.LayoutParams.MATCH_PARENT;
                paramsFullscreen.addRule(RelativeLayout.CENTER_IN_PARENT);
                paramsFullscreen.addRule(RelativeLayout.ALIGN_PARENT_LEFT);
                paramsFullscreen.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
                paramsFullscreen.addRule(RelativeLayout.ALIGN_PARENT_TOP);
                paramsFullscreen.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
            }
            // To fullscreen
            if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
                mVideoView.setLayoutParams(paramsFullscreen);
    
            } else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT) {
                mVideoView.setLayoutParams(paramsNotFullscreen);
            }
        }
    
        @Override
        protected void onPause() {
            if (mVideoView.isPlaying()) {
                mVideoView.pause();
            }
            super.onPause();
        }
    
        @Override
        public void onBackPressed() {
            if (mVideoView != null) {
                mVideoView.stopPlayback();
            }
            finish();
        }
    }
    
    
    <?xml version="1.0" encoding="utf-8"?>
    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="com.example.videoview"
        android:versionCode="1"
        android:versionName="1.0" >
    
        <uses-sdk
            android:minSdkVersion="8"
            android:targetSdkVersion="17" />
    
        <uses-permission android:name="android.permission.INTERNET" />
        <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    
        <application
            android:allowBackup="true"
            android:icon="@drawable/ic_launcher"
            android:label="@string/app_name"
            android:theme="@style/AppTheme" >
            <activity
                android:name="com.example.videoview.MainActivity"
                android:configChanges="orientation|screenSize"
                android:label="@string/app_name"
                android:theme="@android:style/Theme.Dialog" >
                <intent-filter>
                    <action android:name="android.intent.action.MAIN" />
    
                    <category android:name="android.intent.category.LAUNCHER" />
                </intent-filter>
            </activity>
        </application>
    
    </manifest>
    
        8
  •  1
  •   Humberto2991    7 年前

    这是我第一次在stackoverflow中回答问题,我只在FrameLayout中插入了一个VideoView,两种方法都是相同的。MediaController将位于FrameLayout的底部。这对我有用:

    主要_活动.XML:

               <FrameLayout      
                android:id="@+id/frame_layout_video"
                android:layout_centerHorizontal="true"
                android:layout_width="wrap_content"
                android:layout_height="400dp">
    
                <VideoView
                    android:id="@+id/video_select"
                    android:layout_width="wrap_content"
                    android:layout_height="400dp"
                    android:adjustViewBounds="true"
                    android:clickable="true"
                    android:scaleType="centerCrop"
                     />
    
            </FrameLayout>
    

    @Override
    public void onClick(View v) {
        int i = v.getId();
    
        if(i == R.id.select_video){
            selectVideo();
        }
    
    private void selectVideo(){
        //this code is to get videos from gallery:
        Intent galleryIntent = new Intent(Intent.ACTION_GET_CONTENT);
        galleryIntent.addCategory(Intent.CATEGORY_OPENABLE);
        galleryIntent.setAction(Intent.ACTION_GET_CONTENT);
        galleryIntent.setType("video/*");
        startActivityForResult(galleryIntent, GALLERY_REQUEST);
    
        MediaController mediaController = new MediaController(this);
        mediaController.setAnchorView(mVideo);
        //mVideo is the VideoView where I insert the video
        mVideo.setMediaController(mediaController);
        mVideo.pause();
    }
    
    
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    
        switch (requestCode) {
            case 1:
                if (resultCode == RESULT_OK) {
                    mVideoUri = data.getData();
                    mVideo.setVideoURI(mVideoUri);
                    mVideo.start();
                }
        }
    }
    
        9
  •  1
  •   Stefan Zhelyazkov    5 年前

    我是用包装纸做的 VideoView 内部 LinearView 以至于 layout_width="match_parent" 所以它总是延伸到屏幕的范围,但是 layout_height="wrap_content" 因此,线性视图的高度始终固定为内容的高度。这样,当视频播放时,控件总是与视频视图一起放置。

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        tools:context=".DisplayClipActivity">
    
        <VideoView android:id="@+id/episode_clip"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"/>
    </LinearLayout>
    

    // create media controller
    val mediaController = MediaController(this@DisplayClipActivity)
    mediaController.setAnchorView(videoView)
    mediaController.setMediaPlayer(videoView)
    
    // video view
    videoView.setVideoURI(uri)
    videoView.setMediaController(mediaController)
    videoView.start()
    
        10
  •  0
  •   Sasha Shpota A-Bag    6 年前

    :

    videoView.setOnPreparedListener(mediaPlayer ->
        mediaPlayer.setOnVideoSizeChangedListener(
            (player, width, height) -> {
                MediaController controller = new MediaController(YourActivity.this);
                videoView.setMediaController(controller);
                controller.setAnchorView(videoView);
            }
        )
    );