人生倒计时
- 今日已经过去小时
- 这周已经过去天
- 本月已经过去天
- 今年已经过去个月
YouTubeadd(youtubeadd,下载)
转:小窗播放视频的原理和实现(上)
转到, 在手机上看着方便
(使用浏览器扫码进入在线客服窗口)
复制联系方式
由于文章篇幅较长,将分为上、下两篇。上篇主要介绍小窗播放视频的原理,下篇主要介绍小窗播放视频的实现。
目前很多视频类App都有小窗播放功能,比如Youtube(如图1)、Facebook(如图2)等,不过它们的实现方式却不同。Youtube 是将视频播放View内嵌到应用内,优点是交互好;Facebook则是通过WindowManager添加视频播放View,同时支持应用内部和外部播放。
小窗播放视频功能在小窗和大屏之间切换时,视频类App通常一边执行交互动作一边播放视频。交互动作包括移动、缩放或者动画;这些App在播放时期望给用户平滑的过渡体验,流畅加载视频,不能有明显的卡顿。
figure
figcaption(图1 Youtube小窗播放视频)/figcaption
/figure
figure
figcaption(图2 Facebook小窗播放视频)/figcaption
/figure
二、SurfaceView 和 GLSurfaceView
Android 中使用 MediaPlayer 播放视频时,一般采用 SurfaceView 、 GLSurfaceView 和 TextureView 。Youtube、Facebook用不同技术方案实现了小窗播放视频功能,它们共同点是都可以使用 SurfaceView 、 GLSurfaceView 和 TextureView 来播放视频。接下来分析三个视图用于小窗播放视频的原理。
SurfaceView继承自类View,但与其他View的子类不同的是它有独立的Surface,如下源码可以看出它包含一个Surface属性,即它不与宿主窗口共享同一个绘图表面。因此SurfaceView的UI可以在一个独立的线程中进行绘制。由于不会占用主线程资源,因此SurfaceView可以实现复杂而高效的UI。GLSurfaceView继承SurfaceView,作为SurfaceView的补充,加入了EGL的管理,并自带了渲染线程。它用于小窗播放时效果和SurfaceView类似。本文以下内容以SurfaceView为例分析独立的Surface对小窗播放会有什么影响。
通过Surface的类注释可以知道,Surface处理一块由Screen compositor管理的Raw buffer。而Screen compositor其实就是SurfaceFlinger服务。Surface字面意思就是绘图表面,可以理解为是UI的画布。
Android应用程序窗口需要请求SurfaceFlinger服务创建绘图表面(也就是Surface对象),同时窗口还需要被WindowManagerService管理;所以实际上窗口的绘图表面是通过两个Surface对象来描述,一个是应用程序进程创建的,另一个是由WindowManagerService创建的,这两个Surface对象对应于SurfaceFlinger服务的同一个Layer对象。
在应用程序进程这一侧,每一个应用程序窗口,如Activity,都有一个Surface对象,就是在ViewRootImpl对象的mSurface属性,这个Surface用来绘制应用程序窗口的UI,如下ViewRootImpl源码所示。当界面需要刷新时,窗口调用draw方法,向Surface请求canvas,执行绘画操作后再次提交给Surface完成屏幕显示。
在WindowManagerService服务这一侧,每一个窗口,都有一个对应的WindowState对象。其有一个属性mSurface,它负责设置窗口的位置、大小属性。例如,一个窗口的Z轴坐标大小要考虑到它的窗口类型,以及它与系统中的其它窗口的关系[2]。
SurfaceView有独立的绘图表面,那么SurfaceView又是怎么绘制在宿主窗口的呢?
上面说到每一个窗口在SurfaceFlinger服务中都对应有一个Layer,用来描述它的绘图表面。同时每一个SurfaceView在SurfaceFlinger服务中还对应有一个独立的Layer或者LayerBuffer,用来单独描述它的绘图表面,以区别于它的宿主窗口的绘图表面[3]。
figure
/figure
(图3 SurfaceView的Surface的创建过程)
接下来了解Surface创建过程,如图3的时序图所示,每当一个窗口需要刷新UI时,就会调用ViewRootImpl类的performTraversals方法。如果当前窗口的Surface还没有创建,或者已经失效,SurfaceView就会请求WindowManagerService服务创建一个新的Surface,它最终会调用updateWindow来完成Surface的创建。
如SurfaceView源码所示,它有一个mSurface属性,相比之下TextView或者Button等普通View会共用ViewRootImpl的Surface。
SurfaceView类的属性mWindowType描述的是SurfaceView的窗口类型,它的默认值等于 TYPE_APPLICATION_MEDIA ,用来显示多媒体的,如视频。SurfaceView还有另外一个类型 TYPE_APPLICATION_MEDIA_OVERLAY ,它是在视频上面显示Overlay的,它可以显示视字幕等信息。宿主窗口会遮挡这两个类型的SurfaceView,如果窗口嵌入这两类SurfaceView,那么它们的Z轴位置会低于该窗口的Z轴位置,显示在该窗口下面。如果mWindow等于null的话,那么就说明该SurfaceView还没有添加到WindowManagerService服务中去,然后调用addWithoutInputChannel添加到WindowManagerService服务中。
mSession.relayout()请求WindowManagerService服务对SurfaceView的UI进行布局。如果宿主窗口的绘制表面还未创建,或者需要重新创建,那么就会请求SurfaceFlinger服务为它创建一个新的Surface。由于这一步可能会修改SurfaceView的Surface,所以添加了mSurfaceLock锁,避免其它线程同时修改该Surface的内容。
执行完成上述步骤之后,SurfaceView的Surface的创建完成了。但是mWindowType为 TYPE_APPLICATION_MEDIA 或 TYPE_APPLICATION_MEDIA_OVERLAY 的SurfaceView会被宿主窗口挡住,如何解决这个问题,这就要了解SurfaceView“挖洞”原理。
当SurfaceView附加宿主窗口时,它的onAttachedToWindow会被调用。这个方法调用requestTransparentRegion请求在宿主窗口上设置透明区域,即请求在宿主窗口上挖洞,其实就是设置ViewRootImpl中Surface的透明度。而每当其宿主窗口刷新自己的UI的时候,就会调用ViewGroup的gatherTransparentRegion将所有嵌入在它里面的SurfaceView所设置的透明区域收集起来。然后再通知WindowManagerService为SurfaceView的gatherTransparentRegion方法设置一个总的透明区域。这就是SurfaceViewd的“挖洞”原理,如图4时序图所示。
figure
/figure
(图4 SurfaceView“挖洞”原理)
接下来结合ViewRootImpl类的requestTransparentRegion源码,来分析请求在宿主窗口上设置透明区域的过程。
当mView等于子View时,将mPrivateFlags的 View.REQUEST_TRANSPARENT_REGIONS 位设置为1,表示该窗口被设置了一块透明区域。当一个窗口被请求设置了一块透明区域之后,它的窗口属性就发生了变化,这时候除了要将与它所关联的ViewRootImpl对象的mWindowAttributesChanged值设置为true之外,还要调用该ViewRootImpl对象的requestLayout方法对窗口的UI进行重新布局和绘制。requestLayout最终会调用到另外一个方法performTraversals来实际执行刷新窗口UI的操作。
ViewRootImpl类的方法performTraversals是用来收集嵌入在它里面的SurfaceView所设置的透明区域的。它处于窗口的UI布局完成之后,窗口的UI绘制之前。这是因为窗口的UI布局完成之后,各个子视图的大小和位置才能确定下来,进而才能确定SurfaceView的透明区域的位置和大小。从顶层视图开始,从上到下收集每一个子视图所要设置的区域,最终收集到的总透明区域并保存在ViewRootImpl类的成员变量mTransparentRegion中。其中host是DecorView,它的gatherTransparentRegion方法重载了父类ViewGroup的gatherTransparentRegion方法。
ViewGroup的gatherTransparentRegion方法中,检测到有透明区域时,调用父类View的方法gatherTransparentRegion来检查当前视图容器是否需要绘制。如果需要绘制,说明当前视图的前景需要绘制,就会将它所占据的区域从参数region所占据的区域移除,以便可以显示当前视图的前景。然后调用每一个子视图的成员函数gatherTransparentRegion来继续往下收集透明区域。
SurfaceView类的方法gatherTransparentRegion中,先检测是否用作窗口面板以及mPrivateFlags的SKIP_DRAW位是不是1。如果都是,将它所占据的区域从参数region所描述的区域移除,region中剩下的就是透明区域。最后判断Surface的像素格式是否设置有透明值。如果有,返回false给ViewRootImpl,然后ViewRootImpl调用 sWindowSession.setTransparentRegion(mWindow, mTransparentRegion); 设置窗口为透明。这样就能看到SurfaceView了。
SurfaceView虽然具有独立的Surface,不过它仍然是宿主窗口的视图结构中的一个结点,因此,它仍然是可以参与到宿主窗口的绘制流程中去的。
在SurfaceView的draw和dispatchDraw方法中,参数canvas是建立在宿主窗口的Surface上的画布,因此在这块画布上绘制任何UI都是出现在宿主窗口的Surface上的。但如果当前正在处理的SurfaceView不是用作宿主窗口面板的时候,即属性mWindowType的值不等于 TYPE_APPLICATION_PANEL 的时候,SurfaceView的这两个方法只是简单地将它所占据的区域绘制为黑色。另外dispatchDraw还会调用另外一个方法updateWindow更新的UI,绘制自己的Sueface。
通过了解SurfaceView的创建过程、“挖洞”原理和绘制过程,可以了解到Surface对小窗播放视频的影响如下:
1)SurfaceView在宿主窗口下面,通过“挖洞”原理显示Surface。SurfaceView在做旋转时,画面不会跟随SurfaceView旋转。
2)同理,设置透明度或者执行透明值动画时,SurfaceView显示有问题。
3)SurfaceView绘制时会先绘制黑边,所以在移动或者缩放过程,在更新不及时时会看到黑边。
4)SurfaceView具有独立的Surface,它的UI绘制可以在独立的线程中进行,可以进行复杂的UI绘制。
由于SurfaceView不在View hierarchy中,View的一些缩放,透明度变化等方法无法使用。要实现这些功能就得使用TextureView,但TextureView有个缺点就是性能低耗电高。Android N对SurfaceView进行了更改,它对SurfaceView自身和它的内容改变做了同步处理,播放视频时不会出现之前难看的黑色条。SurfaceView因这个新特性不会出现黑色条,但它旋转时画面仍然不会跟随旋转,仍然不支持透明度。
如下源码所示,TextureView继承于View,并重载了View的draw()方法,它与其它的View一样在View hierarchy中管理与绘制。draw()方法中主要把SurfaceTexture中收到的图像数据作为纹理更新到对应的HardwareLayer中。SurfaceTexture.OnFrameAvailableListener用于通知TextureView有新数据。
根据以上信息,可以知道TextureView不同于SurfaceView,没有单独创建Surface,而是作为View hierarchy中的一个普通View,来进行移动,旋转,缩放,动画等,没有SurfaceView执行旋转、缩放时的缺点。值得注意的是TextureView必须在硬件加速的窗口中,通过HardwareLayer更新视图。它需要硬件加速层,这使得TextureView比SurfaceView更耗性能。 Android N上SurfaceView新特性的说明上,官方也推荐在不执行旋转、透明度、缩放时使用SurfaceView。
SurfaceView有独立的Surface,通过“挖洞”原理显示它。以致它在执行旋转时,画面不会跟随旋转;同时设置透明度或者执行透明值动画时,显示有问题。Android N以上的SurfaceView在视频进行缩放旋转时会同步变化,不会看到黑色边,官方推荐使用SurfaceView。TextureView作为普通View在View hierarchy中管理与绘制,更适用于小窗播放视频功能。但TextureView需要硬件加速层,使得TextureView比SurfaceView和GLSurfaceView更耗性能。
[1]、Surface( )
[2]、Android应用程序窗口(Activity)的绘图表面(Surface)的创建过程分析 ( )
[3]、Android视图SurfaceView的实现原理分析( )
[4]、SurfaceView( )
小窗播放视频的原理和实现(下)
ytube 被封后 怎么下载他的视频 能用的话 追加 20分
首先 你要F墙 你会吧 不会的话用hot spot shield
然后
直接看这儿()
一般我们在线上看到喜欢的影片,却无法下载保存,现在有一个方法可以下载线上的影片,不但支援 YouTube、无名、Yahoo 甚至只要是任何线上观看的 FIV 档案,都可以任意下载!废话不多说,让我们开始安装吧!
一、安装火狐(FireFox)
首先你必须先安装 火狐(FireFox)浏览器,因为下载的软体是 FireFox 的外挂,你可以到 Mozilla Taiwan 正体中文 下载,现在的版本应该是 FireFox3.0,以下示范环境也是以 FireFox3.0 为主。
二、安装 Video DownloadHelper 外挂
安装好火狐之后,接著就要开始安装下载影音的外挂,点选以下连结 ,然后点选「安装到 FireFox」按钮,就可以开始安装,过程速度很快,安装好之后会在火狐的浏览器上面看到以下图示:一开始是黑白的,但如果侦测到影音页面就会变成彩色并旋转,表示可以下载。
DownloadHelper0.png
三、测试下载影音吧!
1. 首先先到无名影音试试
DownloadHelper1.png
2. 这里可以看到图示已经变彩色,按下后就可以下载
DownloadHelper2.png
3. 选择储存的地方,可以更改档名
DownloadHelper3.png
4. 下载完成,就可以用 FIV 播放软体观看,我这里用的是 Wimpy FLV Player,可以点我下载(免安装)。
DownloadHelper4.png
四、换 YouTube 试试吧!
1. 挑一个喜欢的页面吧!同样按下三色球图示,有时候会出现多个选项,不用管他,挑一个下载即可
DownloadHelper5.png
2. 下载中
DownloadHelper6.png
五、结论
这真是一个好用的外挂,几乎支援所有线上影音网站,而且他本身也有提供影音网站的列表可供浏览,可以去逛逛。
看不懂看这儿()
不可能用不了 你QQ多少 说出来 我加你 给你讲
sceptre电视机怎么连接youtobe
连接youtobe操作步骤:
1.在安卓手机、平板上安装好Youtube的APK应用,这很容易在应用市场上找到。
2.下载并安装基于电视屏幕操作的TV版
3.安装完成后打开YoutubeTVAPP,遥控选择左下角的设置,这时你可以看到右下角会弹出一个设置详情对话框,选择“Pairwithmobiledevice"后你会发现弹出页面生成了一个配对码,记住改Paircode。
4.打开手机或者平板上的youtubeapp,通过SettingsConnectedTVsAddaTV,调出连接页面,输入上面记下的Paircode,点击确定即可。
5.手机或者平板设备登录之后您就可以通过手机检索、选择需要观看的视频,跟家人一起在TV大屏幕上观看啦!


