videoview


科学/班会/信息 2019-06-11 22:41:43 科学/班会/信息
[摘要]videoview篇(1):android利用VideoView实现视频全屏播放android实现视频全屏播放,开始加入了进度等待和随时更换影片底色,判断用户屏幕方向,根据用户屏幕方向给出正确的视频资源,来更好的播放视频。实现影片全屏播放视频,就是把头部信息去掉,其方法是:。。。 去掉头信息

【www.shanpow.com--科学/班会/信息】

videoview篇(1):android利用VideoView实现视频全屏播放


android实现视频全屏播放,开始加入了进度等待和随时更换影片底色,判断用户屏幕方向,根据用户屏幕方向给出正确的视频资源,来更好的播放视频。
   实现影片全屏播放视频,就是把头部信息去掉,其方法是:
   。。。
        //去掉头信息        requestWindowFeature(Window.FEATURE_NO_TITLE);         getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,                     WindowManager.LayoutParams.FLAG_FULLSCREEN);         setContentView(R.layout.videoview);
   。。。
 
注意:一定要在setContentView之前加入上面的信息。不然不会实现其效果。
影片加载需要一定的时间,在这是利用进度条显示给用户,××影片正在加载。实现方法如下:
在创建VideoView之后,实现进度框显示
。。。
         //创建进度条         dialog=ProgressDialog.show(this, "正在加载…", "三枪马上开始");
。。。
在影片加载完毕,开始播放时,销毁进度条
dialog.dismiss();
实现的效果如下:
在实现全屏显示之后,就要根据用户当前手机屏幕方向,给用户适合手机屏幕大小的视频资源。判断手机横竖屏的方法是,取得手机的宽和高,根据长宽比判断手机是处于什么状态:

        //判断手机屏幕的方向        DisplayMetrics dm = new DisplayMetrics();        getWindowManager().getDefaultDisplay().getMetrics(dm);        width=dm.widthPixels;        heigh=dm.heightPixels;        if(width/heigh>0)        {            //横屏            path = bundle.getString("widthurl");        }        if(width/heigh==0)        {            //竖屏            path = bundle.getString("heighturl");        }

实现的效果如下:
源代码:http://easymorse.googlecode.com/svn/tags/android.customer.player-0.5

videoview篇(2):MediaPlayer使用之四 VideoView的使用


原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 、作者信息和本声明。否则将追究法律责任。http://mikewang.blog.51cto.com/3826268/852214
本文的思路将按照我的项目实际过程来展开。
 
第一部分:问题的出现
需求:页面有很多布局,其中有一块区域播放视频,当我单击这块区域的时候,全屏播放。
我使用MediaPlayer + SurfaceView,当全屏时,改变SurfaceView的大小,然后MediaPlayer.setHolder(mSurfaceViewHolder),但是 ,只有SurfaceView改变了,但是视频大小仍然没有改变。而且在不设置surfaceHolder的情况下,视频仍以奇特的方式播放,具体方法可以参看我之前的例子,链接是:。大家可以尝试,我在后面会进行一些测试来一步一步来排除问题。
 
第二部分:转换思路,解决问题
解决问题优先,换了一种思路解决问题,使用Android框架封装好的VideoView解决,很快实现。
思路:当需要全屏时,gone掉无关紧要的其他布局。让VideoView的父组件(的父组件)FILL_PARENT。当要回到默认的显示布局时,将之前保存的原始尺寸设置回来,原来gone掉的布局显示出来即可。
关键代码如下:
public void onClick(View v) { 
        switch (v.getId()) { 
        case R.id.videoView: 
            if (!isFullScreen) { 
                toFullScreen(); 
            } else { 
                toDefaultScreen(); 
            } 
            break; 
        } 
    } 
 
 
    private void toFullScreen() { 
        // TODO Auto-generated method stub 
 
        mVideoBarDefaultWidth = mVideoView.getWidth(); 
        mVideoBarDefaultHeight = mVideoView.getHeight(); 
 
        mTitleBar.setVisibility(View.GONE); 
        mAppBar.setVisibility(View.GONE); 
        mCategoryBar.setVisibility(View.GONE); 
        mIndicatorBar.setVisibility(View.GONE); 
 
        mContentLayout.setLayoutParams(new LinearLayout.LayoutParams( 
                LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT)); 
 
        mVideoViewLayout.setLayoutParams(new LinearLayout.LayoutParams( 
                LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT)); 
 
        mVideoView.setLayoutParams(new LinearLayout.LayoutParams( 
                LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT)); 
 
        isFullScreen = true; 
 
    } 
 
    private void toDefaultScreen() { 
        // TODO Auto-generated method stub 
        mTitleBar.setVisibility(View.VISIBLE); 
        mAppBar.setVisibility(View.VISIBLE); 
        mCategoryBar.setVisibility(View.VISIBLE); 
        mIndicatorBar.setVisibility(View.VISIBLE); 
         
        mContentLayout.setLayoutParams(new LinearLayout.LayoutParams( 
                LayoutParams.FILL_PARENT, mVideoBarDefaultHeight)); 
        mVideoViewLayout.setLayoutParams(new LinearLayout.LayoutParams( 
                mVideoBarDefaultWidth, mVideoBarDefaultHeight)); 
        mVideoView.setLayoutParams(new LinearLayout.LayoutParams( 
                mVideoBarDefaultWidth, mVideoBarDefaultHeight)); 
         
        isFullScreen = false; 
    } 
 
第三部分: 原因 + 设计测试
VideoView本身是SurfaceView的子类,既然VideoView没有问题,显然问题出在我对SurfaceView的处理上。因为出现了上面提到的不设置SurfaceViewHolder,MediaPlayer也能播放的问题。So,
第一个问题:MediaPlayer播放视频的依赖条件是什么?
查找到android的视频播放框架,见下图(双击图片可以放大)。
显然,视频播放需要通过:
(1) JAVA Framework(即Android Framework),通过VideoView,经过Surface,
(2) 再到Native Framework,
(3) 最后到达Driver.
在这里要重申一句:我们的问题是,为什么 SurfaceView没能实现全屏? 那么go on !!!
我们只需要关注到Android Framework之间的关联关系即可。显然,VideoView的父类是SurfaceView,最终通过其与Surface产生关联。
即VideoView?----------------SurfaceView?----------------------Surface
SurfaceView和Surface:
分析:文档
首先,SurfaceView的父类是View,最终父类是Object,但是Surface的父类是Object。类的层级见下图所示(双击可放大)。
所以两者是对等的关系,那么这两个是如何产生关系的。
SurfaceView的Class Overview见下图(双击图片可放大):
蓝色选中部分为关键内容:SurfaceView在它的Window上凿出一个洞,以便让Surface层的内容显示出来。本身它只提供一个显示Surface的窗口。
为方便期间,在此提供SurfaceView类的翻译,来自:http://www.cnblogs.com/xuling/archive/2011/06/06/android.html
在此贴出来供参考:
SurfaceView是视图(View)的继承类,这个视图里内嵌了一个专门用于绘制的Surface。你可以控制这个Surface的格式和尺寸。Surfaceview控制这个Surface的绘制位置。         surface是纵深排序(Z-ordered)的,这表明它总在自己所在窗口的后面。surfaceview提供了一个可见区域,只有在这个可见区域内 的surface部分内容才可见,可见区域外的部分不可见。surface的排版显示受到视图层级关系的影响,它的兄弟视图结点会在顶端显示。这意味者 surface的内容会被它的兄弟视图遮挡,这一特性可以用来放置遮盖物(overlays)(例如,文本和按钮等控件)。注意,如果surface上面 有透明控件,那么它的每次变化都会引起框架重新计算它和顶层控件的透明效果,这会影响性能。 你可以通过SurfaceHolder接口访问这个surface,getHolder()方法可以得到这个接口。         surfaceview变得可见时,surface被创建;surfaceview隐藏前,surface被销毁。这样能节省资源。如果你要查看 surface被创建和销毁的时机,可以重载surfaceCreated(SurfaceHolder)和 surfaceDestroyed(SurfaceHolder)。         surfaceview的核心在于提供了两个线程:UI线程和渲染线程。这里应注意:         1> 所有SurfaceView和SurfaceHolder.Callback的方法都应该在UI线程里调用,一般来说就是应用程序主线程。渲染线程所要访问的各种变量应该作同步处理。         2> 由于surface可能被销毁,它只在SurfaceHolder.Callback.surfaceCreated()和 SurfaceHolder.Callback.surfaceDestroyed()之间有效,所以要确保渲染线程访问的是合法有效的surface。
第一个问题已经解决: Android的视频播放必须通过SurfaceView(或其封装类VideoView)实现。
第二个问题:视频播放中,可以切换到不同的SurfaceView上吗?
测试。
测试之前有必要上一张图,就是MediaPlayer的状态机(State-Machine),状态时刻指导代码。见下图。(双击图片可放大)。
 
建立测试Demo,如下图所示(双击图片可以放大):
 
Test1:指定初始SurfaceView的大小(demo中有左小右大两个SurfaceView),播放视频
显然,MediaPlayer和显示是独立的两个部分,为简化起见,MediaPlayer直接准备好。代码如下,
public void onClick(View v) { 
 
        switch (v.getId()) { 
        case R.id.buttonToSmall: 
            Log.d("testSurfaceView", "onClick buttonToSmall"); 
            try { 
                if (mMediaPlayer.isPlaying()) { 
                    mMediaPlayer.release(); 
                    mMediaPlayer.setDataSource(mPath); 
                    mMediaPlayer.prepare(); 
                } 
                mMediaPlayer.setDisplay(mSurfaceView1.getHolder()); 
                mMediaPlayer.start(); 
 
            } catch (IllegalArgumentException e) { 
                // TODO Auto-generated catch block 
                e.printStackTrace(); 
            } catch (IllegalStateException e) { 
                // TODO Auto-generated catch block 
                e.printStackTrace(); 
            } catch (IOException e) { 
                // TODO Auto-generated catch block 
                e.printStackTrace(); 
            } 
            break; 
        case R.id.buttonToBig: 
            Log.d("testSurfaceView", "onClick buttonToBig"); 
                try { 
                    if (mMediaPlayer.isPlaying()) { 
                        mMediaPlayer.release(); 
                    mMediaPlayer.setDataSource(mPath); 
                    mMediaPlayer.prepare(); 
                    } 
                mMediaPlayer.setDisplay(mSurfaceView2.getHolder()); 
                mMediaPlayer.start(); 
                } catch (IllegalArgumentException e) { 
                    // TODO Auto-generated catch block 
                    e.printStackTrace(); 
                } catch (IllegalStateException e) { 
                    // TODO Auto-generated catch block 
                    e.printStackTrace(); 
                } catch (IOException e) { 
                    // TODO Auto-generated catch block 
                    e.printStackTrace(); 
                } 
            break; 
测试结果:初始的surfaceview将决定视频的播放大小。系统会自动适配SurfaceView和Video的大小比例,使之恰当,但是在实际的显示效果并不佳,所以最好能通过运算计算一下。
 
Test2:既然两个SurfaceView都能单独播放,那么能否从一个切换到另一个上呢?
MediaPlayer通过SurfaceView显示出来,而SurfaceView由SurfaceViewHolder控制。MediaPlayer通过方法setDisplay(SurfaceViewHolder sh)实现。
参看SurfaceHolder的文档,见下图(双击图片可放大)。
参看setDisplay()方法的文档,见下图(双击图片可放大):
要点:在非播放状况下,使用此方法。
2-2-1代码如下: 
public void onClick(View v) { 
 
        switch (v.getId()) { 
        case R.id.buttonToSmall: 
            Log.d("testSurfaceView", "onClick buttonToSmall"); 
            mMediaPlayer.setDisplay(mSurfaceView1.getHolder()); 
            mMediaPlayer.start(); 
            break; 
        case R.id.buttonToBig: 
            Log.d("testSurfaceView", "onClick buttonToBig"); 
            mMediaPlayer.pause(); 
            mMediaPlayer.setDisplay(mSurfaceView2.getHolder()); 
            mMediaPlayer.start(); 
            break; 
测试结果:根本没变,还是在原来的Surface上显示。
2-2-2参考之前写的代码,做联想,如果重新Prepare,是否可以播放?
代码如下:
public void start() { 
        // TODO Auto-generated method stub 
        mMediaPlayer.start(); 
    } 
 
    public void onClick(View v) { 
 
        switch (v.getId()) { 
        case R.id.buttonToSmall: 
            Log.d("testSurfaceView", "onClick buttonToSmall"); 
            mMediaPlayer.setDisplay(mSurfaceView1.getHolder()); 
            mMediaPlayer.start(); 
            break; 
        case R.id.buttonToBig: 
            Log.d("testSurfaceView", "onClick buttonToBig"); 
            try { 
                mMediaPlayer.stop(); 
                mMediaPlayer.setDisplay(mSurfaceView2.getHolder()); 
                mMediaPlayer.prepare(); 
                mMediaPlayer.start(); 
            } catch (IllegalStateException e1) { 
                // TODO Auto-generated catch block 
                e1.printStackTrace(); 
            } catch (IOException e1) { 
                // TODO Auto-generated catch block 
                e1.printStackTrace(); 
            } 
            break; 
测试结果:不能切换,有一个暂停,即是停止和重新做准备的所得。
结论:第一次设置holder之后,似乎就绑定了,无法切换到其他holder所控制的SurfaceView对应的display surface。
 More:为什么setDisplay()方法不能使得显示视频的SurfaceView进行切换,查找源码:如下图所示:
 
因为我暂时对Native Framework不是很了解,所以只提到这里。原因就在:_setVideoSurface();
updateSurfaceScreenOn();
这两个方法中,可以去查找相关内容。
 
Test3:既然不能再两个SurfaceView之间切换,那么更改其中一个大小,可以变化吗?
点击Enlarge1按钮,gone掉Big SurfaceView,增大small SurfaceView
代码如下:
public void onClick(View v) { 
         
        switch (v.getId()) { 
        case R.id.buttonToSmall: 
            Log.d("testSurfaceView", "onClick buttonToSmall"); 
            try { 
                mMediaPlayer.setDisplay(mSurfaceView1.getHolder()); 
                mMediaPlayer.prepare(); 
                mMediaPlayer.start(); 
            } catch (IllegalStateException e) { 
                // TODO Auto-generated catch block 
                e.printStackTrace(); 
            } catch (IOException e) { 
                // TODO Auto-generated catch block 
                e.printStackTrace(); 
            } 
             
            break; 
        case R.id.buttonToBig: 
            Log.d("testSurfaceView", "onClick buttonToBig"); 
            Log.d("testSurfaceView", "has finished buttonToBig"); 
            break; 
             
        case R.id.buttonEnlarge1: 
            Log.d("testSurfaceView", "onClick buttonEnlarge1"); 
            try { 
                 
                mMediaPlayer.pause(); 
                mSurfaceView2.setVisibility(View.GONE); 
                mSurfaceView1.setLayoutParams(new LinearLayout.LayoutParams(500, 500)); 
                mSurfaceView1.getHolder().setFixedSize(500, 500);            
                mMediaPlayer.setDisplay(mSurfaceView1.getHolder()); 
                mMediaPlayer.start(); 
            } catch (IllegalStateException e) { 
                // TODO Auto-generated catch block 
                e.printStackTrace(); 
            } catch (IllegalArgumentException e) { 
                // TODO Auto-generated catch block 
                e.printStackTrace(); 
            } 
            break; 
        } 
     
    } 
测试结果:我靠!居然ok了。再写此篇博文的时候,这个问题并没有解决。我是准备按照我的思路一步一步测试。
原因分析:很简单的道理。真正显示的是surface,通过SurfaceView.getHolder()获得SurfaceView对应下的Surface的控制器SurfaceHolder,获得SurfaceView的初始大小,但是,SurfaceHolder并未与SurfaceView动态关联(即虽然凿出的洞很大,但是真正播放的大小仍然是初始大小)。我们需要使用方法SurfaceHolder让真正播放的大小与凿的洞的大小相适应。这样视频才会大。
解决了MediaPlayer +SurafaceView 全屏的问题。

videoview篇(3):Android的VideoView如何循环播放


Android的VideoView如何循环播放
分类:
android 进阶
2013-07-26 15:28
120人阅读
评论(0)
收藏
举报
Java代码  
package com.hangcheng;  
  
import com.example.bdcustomer_demo.R;  
import com.hangcheng.view.MyVideoView;  
  
import android.app.Activity;  
import android.media.MediaPlayer;  
import android.os.Bundle;  
import android.view.Window;  
  
public class VideoActivity extends Activity {  
    private MyVideoView myVideoView;  
    private String videopath;  
  
    @Override  
    protected void onCreate(Bundle savedInstanceState) {  
        super.onCreate(savedInstanceState);  
        requestWindowFeature(Window.FEATURE_NO_TITLE);  
        setContentView(R.layout.video);  
  
        initView();  
  
        videopath = VideoActivity.this.getIntent().getStringExtra("videopath");  
  
        myVideoView.setVideoPath(videopath);  
        myVideoView.start();  
        myVideoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {  
  
            @Override  
            public void onPrepared(MediaPlayer mp) {  
                mp.start();  
                mp.setLooping(true);  
  
            }  
        });  
  
        myVideoView  
                .setOnCompletionListener(new MediaPlayer.OnCompletionListener() {  
  
                    @Override  
                    public void onCompletion(MediaPlayer mp) {  
                        myVideoView.setVideoPath(videopath);  
                        myVideoView.start();  
  
                    }  
                });  
  
    }  
  
    private void initView() {  
  
        myVideoView = (MyVideoView) findViewById(R.id.video);  
  
    }  
  
}  

本文来源:https://www.shanpow.com/jx/332436/

《videoview.doc》
将本文的Word文档下载到电脑,方便收藏和打印
推荐度:
点击下载文档

文档为doc格式

相关阅读
  • 信息工作经验交流材料 信息工作经验交流材料
  • 淮北师范大学信息学院要多少分录取能考上,2020淮北师范大学信息学院录取分数线预测 淮北师范大学信息学院要多少分录取能考上,2020淮北师范大学信息学院录取分数线预测
  • 阜阳师范大学信息工程学院要多少分录取能考上,2020阜阳师范大学信息工程学院录取分数线预测 阜阳师范大学信息工程学院要多少分录取能考上,2020阜阳师范大学信息工程学院录取分数线预测
  • 疫情心得体会100字(十篇) 疫情心得体会100字(十篇)
  • 院校在阅到预录取多久 到录取需要多少时间 院校在阅到预录取多久 到录取需要多少时间
  • [2019普通话成绩什么时候出]2019普通话成绩查询入口:畅言网和全国普通话培训测试信息资源网 [2019普通话成绩什么时候出]2019普通话成绩查询入口:畅言网和全国普通话培训测试信息资源网
  • 2019年全国普通话成绩查询入口|2019年全国普通话成绩查询入口及查询方法【已公布】 2019年全国普通话成绩查询入口|2019年全国普通话成绩查询入口及查询方法【已公布】
  • 2019考军校难度大吗 军校要多少分|2019考军校难吗军校录取分数线是多少 2019考军校难度大吗 军校要多少分|2019考军校难吗军校录取分数线是多少
为您推荐