Flash的视频神奇StageVideo

在过去的几年里,视频已经成为web网页上最主流的趋势之一,这主要是由Adobe Flash Player来推动的。2007年Flash Player 9中引入了H.264和全屏支持技术,通过在web页面上的沉浸式高清视频体验,实实在在地改变了局面。最近,在移动设备上实现的Flash Player已经为Adobe公司的Flash Player项目组带来了新的思路,这些新的思路将帮助项目组解决如何在Flash中播放视频以及如何持续增强用户体验等问题。Stage video便是这些投入所得的成果。

Flash Player中渲染视频的传统方法是使用Video对象。 Video对象被视为与stage中的其它对象一样,这给了开发者一个前所未有的用来发挥创意的机会。 例如,视频可以渲染在旋转立方体的每一面,或者多个视频可以彼此融合在一起。 Video对象被等同为其它任何的DisplayObject。 图1阐明了这一点。

图1. 可以使用Video对象将多个视频融合在一起。

为了支持这一创意的发挥,Flash Player必须为每个视频帧进行大量的处理。 依靠底层基础设备的性能,这种增加的处理过程可能会降低视频的帧速率,或者还可能会增加Flash Player在CPU中的负载。

渲染视频的一种新方式

为了减少在Video对象中渲染视频对性能所造成的影响,Adobe引入了stage video作为渲染视频的新途径。 这种方法充分利用了底层的视频硬件设施。 而结果是大大地降低了CPU的负载,这便意味着在低性能设备中能表现出更高的帧率以及更少的内存使用率。 使用stage video的话,StageVideo对象并不会位于Flash Player的显示列表中,而是隐藏在stage的背后。 图2说明了这种设计方法。

图2. 隐藏在Flash stage背后的StageVideo对象。

对于电视、机顶盒以及移动设备来说,stage video的性能优势尤为明显。 这些设备没有如台式电脑那般强大的CPU,但是却具有非常强大的视频解码功能,能利用少量的CPU使用率来渲染高品质视频。 然而,即使是在台式电脑上,stage video也将显著地改变Flash Player中的视频性能。

作为一名开发人员,您必须知道,stage video在Flash Player中只是与视频GPU加速相关的第二步增强方式。第一步在于视频编码,以便充分利用目标平台上可用的硬件加速设备。因此,要获得可能的最优视频体验,您需要从这两个步骤下手。H.264视频编解码器是stage video最佳伴侣;使用H.264视频编解码器将确保您从视频解码到视频渲染这段过程中得到全面的GPU加速。通过这种方法,将再也不需要通过 read-back(从GPU传送数据到CPU)在显示列表中合成视频帧了。YUV 4:2:0格式的视频帧通过一个GPU流处理器(DirectX9或OpenGL) ,会被转换为RGB图像,并传送到屏幕上。因此,您将会看到更高的像素保真度,并能降低CPU和内存的使用率。

限制

应用stage video,视频会被渲染于一个flash.media.StageVideo对象,而不是Video对象。 该StageVideo对象始终显示在屏幕上一个对齐窗口的矩形区域内。 其他图层可能会位于StageVideo对象的上方,但是却不可能将这些图层对象置于视频的背后。 由于StageVideo并不是位于传统的显示列表中,而是通过GPU被合成,所以在使用StageVideo对象的时候,下述功能将不可用:

  • StageVideo对象不能被旋转。 只可能做到正交旋转(以90度的增量旋转)。
  • StageVideo对象可能不能适用colorTransform或3D转换变形。 它没有一个适用的矩阵变换功能来对视频进行倾斜处理。
  • StageVideo对象无法适用alpha 通道、混合模式、滤光器、蒙版或者scale9Grid这些功能。
  • 其视频数据不能被复制到BitmapData对象(BitmapData.draw)中。
  • 视频不能以位图格式缓存。
  • 视频数据不能嵌入在SWF文件中。 StageVideo只能应用于源自NetStream对象的影片。
  • 依赖于底层硬件设备,一些色彩空间可能不被支持。 在这种情况下,Flash Player将选择一个替代的色彩空间。 新的StageVideo ActionScript API提供了一种方式用来查询正在使用的色彩空间。
  • 依赖于平台,在视频平面中允许显示的视频数量是有限的。 在大多数移动系统中,在全局范围任何时间内只允许播放一个视频。 这意味着,如果您有几个SWF文件的实例同时显示的话,只有第一个SWF文件能以硬件加速的方式显示。
  • 为了保证台式电脑和TV设备中Flash Player的一致性,请将wmode设置为direct。
  • 请避免让wmode="transparent"的SWF文件彼此相互层叠。 某些平台不支持wmode="transparent"模式,如Google TV。 这意味着当wmode ="window"时,无论<embed> 标签参数是何值,所有的SWF实例都能被平台支持。

在实际情况下,上述任何限制都不会影响到最常用的用例,便是其作为视频播放器应用程序的用例。 在可以接受这些限制条件的情况下,强烈鼓励开发者使用StageVideo对象。 Google TV平台以及为TV平台开发的所有AIR程序都支持Stage video,而且它即将包含在所有支持Flash的平台中。

如果您想了解更多关于TV平台和Google TV平台上AIR程序使用StageVideo的相关知识,请查阅下面的文章:ring videoDelive and content for the Flash Platform on TV

要求

为了确保stage video可用,任何时候您均须设置wmode="direct"。 这是极力推荐的视频播放模式。 该模式在Windows上使用Direct3D,而在Mac OS和Linux系统中使用OpenGL,以此直接通过GPU进行视频帧的合成处理。这种模式下的限制是,Flash Player运行在它自己的上下文环境中,而不可能在player的顶部有重叠的HTML内容。 如果您要使用任何其它的模式,如wmode="window"、wmode="opaque",或者wmode="transparent",这将大大降低stage video的可用机会(请查看注解)。 因此,为了保持一致性,强烈建议在任何时候都使用wmode="direct"。

注意: 某些浏览器,比如Safari 4(或更高版本)或Internet Explorer 9,即使用如CoreAnimation(MacOS 10.6)或IE9 GPU APIs(Windows Vista/7)等类库的浏览器,允许Flash Player通过浏览器上下文环境中的GPU进行合成处理,就像使用wmode="direct"模式那样。因此,这使得在不考虑wmode参数值的情况下允许使用stage video。但是再一次强调,为了跨浏览器的一致性,请尽量尝试使用wmode="direct"。

现在,您已经学会了stage video的相关概念及其使用限制,那么就来看看以ActionScript方式实现的话会是什么样子。

Stage Video API

以Flash Player 10.2开始,有一个名为StageVideo的新类,它代表硬件视频平面中的一个视频显示实例。StageVideo对象由Flash Player创建,并且它无法自行实例化。 可以从Stage对象中可用的stageVideos数组中访问StageVideo对象:

var v:Vector.<StageVideo> = stage.stageVideos;
var sv:StageVideo;
if ( v.length >= 1 )
{
    sv = v[0];
}

  

当stageVideos属性被访问的时候,根据可用的平台和硬件设备的不同,stage.stageVideos数组的长度会有所不同。StageVideo对象的最大数量是8。 因此,如果您想在应用程序中使用多个StageVideo对象,这在台式电脑上是完全有可行的。 而在移动平台上,只可以使用一个StageVideo对象,因此您必须考虑到这一点。 此外,数组的长度有时会是零。 如果要正确地实现stage video,您就应当时刻监听StageVideoAvailabilityEvent.STAGE_VIDEO_AVAILABILITY事件,而不是手动地探询stageVideos对象数组的长度。 这将告知您关于stage video的性能。

任何时候,您都可以监听这样的事件,并且等待事件的分派以做出合适的反应:

stage.addEventListener(StageVideoAvailabilityEvent.STAGE_VIDEO_AVAILABILITY, onStageVideoState);

不管stage video的可用性随时间发生了怎样的变化,当注册了事件处理器之后,它将被分派一次。如果您想了解有关此操作的更多细节,请查阅"Gaining or losing stage video"章节。

onStageVideoHandler中,依赖于StageVideoAvailability事件对象中可得到的状态属性:

private function onStageVideoState(event:StageVideoAvailabilityEvent):void
{
    var available:Boolean = (event.availability == StageVideoAvailability.AVAILABLE);
}

该状态属性可以具有以下的值:

  1. StageVideoAbility.AVAILABLE:Stage video可用;在stageVideos对象数组中至少有一个StageVideo处于等待状态。
  2. StageVideoEvent.UNAVAILABLE:Stage video不可用;stageVideos对象数组为空。

通常情况下,一旦被告知了可用性的信息,您就可以决定该做些什么事情了。 如果stageVideos是可用的,那么便可从stage.stageVideos对象数组中获取到一个StageVideo对象。 如果stageVideos不可用,您将依赖于一个已经创建的传统的Video对象,并将它用作退却:

private function toggleStageVideo(on:Boolean):void
{
    // if StageVideo is available, attach the NetStream to StageVideo
    if (on)
    {
        if ( sv == null )
        {
            // retrieve the first StageVideo object
            sv = stage.stageVideos[0];
            sv.addEventListener(StageVideoEvent.RENDER_STATE, stageVideoStateChange);
        }
        sv.attachNetStream(ns);
    } else
    {
        video.attachNetStream(ns);
        stage.addChildAt(video, 0);
    }
    ns.play(FILE_NAME);
}

您可能已经注意到,我们在StageVideo对象上还监听了一个名为StageVideoEvent.RENDER_STATE的新事件。 请注意,通过VideoEvent.RENDER_STATE的相似事件,这个新事件在传统Video对象上也同样适用的,并且它告知我们视频是如何渲染的:

private function stageVideoStateChange(event:StageVideoEvent):void
{
    var status:String = event.status;
    resize();
}

在Flash Player 10.1中,我们没有办法知道视频帧是否通过GPU来进行解码或合成。 但是加入到StageVideo和Video对象中的这个新事件修复了这一局限性,这在Flash Player 10.2中开始启用。 状态属性可以有以下值,这些值可作为StageVideoEventVideoEvent类中的常量:

  1. StageVideoEvent.RENDER_STATUS_ACCELERATED:视频将通过GPU进行译码和合成。
  2. StageVideoEvent.RENDER_STATUS_SOFTWARE:视频通过软件进行解码,并通过GPU(如果由StageVideo分派)或者是软件(如果由Video进行分派)进行合成。
  3. StageVideoEvent.RENDER_STATUS_UNAVAILABLE:视频硬件已停止解码和合成视频。

当NetStream连接到StageVideo对象时,StageVideoEvent就会被分派,或者是Video对象的VideoEvent被分派。 例如,如果被分派的是StageVideoEvent.RENDER_STATUS_SOFTWARE,即通知您该视频正通过软件进行解码,您可以尝试切换到另一个视频流——比如H.264或者不同尺寸的视频流——来让该视频在GPU上更好地解码。如果硬件解码突然无法使用,您可以选择一个非GPU加速的编码解码器来强制通过软件进行解码。 这样的事件同样可用在调试或记录日志中跟踪用户体验。

正如您所看到的,您也可以使用这个事件来改变视频的大小,因为该事件也会告知什么时候可以从Video或StageVideo对象中获取视频的尺寸,并根据约束条件计算得到视频的最终宽度和高度。

private function resize ():void
{
    rc = computeVideoRect(sv.videoWidth, sv.videoHeight);
    sv.viewPort = rc;
}

请记住,StageVideo不是一个DisplayObject,因此它并不会实现您在Flash中用来定位和缩放DisplayObject的所有预期属性。 上面的代码使用了viewPort属性来指定屏幕中视频的尺寸,而不是使用那些预期的如宽度和高度的属性。

StageVideo对象公开了下列属性:

  1. colorSpaces:Vector.:在底层硬件设备上可用的颜色空间。
  2. depth:int:StageVideo对象的深度。这个属性允许您在多个StageVideo对象之间处理z-ordering。
  3. pan:Point:平移(类似于X和Y);必须指定一个Point对象。 默认情况下,pan的值为(0,0)。
  4. videoHeight:int: 视频流的原始高度;为只读属性。
  5. videoWidth int:视频流的原始宽度;为只读属性。
  6. viewport:Rectangle:可见的表面(类似于宽度和高度);必须指定一个Rectangle对象。
  7. zoom:Point:缩放因子;必须指定一个Point对象。 默认情况下,zoom的值是(1,1)。

请注意,StageVideo实例是按顺序渲染的。stageVideos数组中的第一个StageVideo对象会最先渲染;下一个对象将渲染在前一个的上方。 要改变这一点,您可以使用depth属性来手动地改变顺序:

sv.depth = 0;
sv2.depth = 1;

您可能已经注意到,StageVideo对象公开了一个colorSpaces属性,该属性返回由当前硬件进行处理的色彩空间的相关信息。 现在您会发现这将是多么地有用。

使用色彩空间

colorSpaces属性能够在StageVideo对象中被访问,并返回一个字符串数组:

var colorSpace:Vector.<String> = stageVideo.colorSpaces;

色彩空间名称列举在flash.media.VideoColorSpace类中:

VideoColorSpace.BT601 = "BT.601";
VideoColorSpace.UNKNOWN = "unknown";
VideoColorSpace.BT709 = "BT.709";
VideoColorSpace.SMPTE_240M = "SMPTE-240M";
VideoColorSpace.USFCC:String = "USFCC";

请注意,播放器会尝试将StageVideo的色彩空间与视频流的色彩空间相匹配。 在某些机器的配置中,如果这一匹配不能满足,Flash Player就会尝试查找最接近的匹配。

请记住,有些视频容器可能嵌入了与视频流的原始色彩空间相关的信息。 因此,Flash Player必须考虑到这一点。 一种常见的情况是H.264,其中的视频流通常被编码成"BT.709"——而色彩空间属性可能返回"BT.601",其意思是说底层的 OS/graphics硬件设备没有能力在"BT.709"色彩空间中渲染视频平面。 如果发生这种情况,您可以重新使用软件合成(通过使用一个传统Video对象),或者是接受颜色的不匹配。 如果返回"unknown"时,平台将不能查询当前实际使用的色彩空间。

获取或释放stage video

当SWF文件被实例化的时候,Stage video可能无法使用,但它可能会在一段时间之后变得可用。 您可能会问,这是为什么呢? 正如我前面解释过的,当整合SWF文件时,您选择的wmode值会决定stage video跨浏览器的一致性。 在某些情况下,您可能无法设置wmode="direct"-——比如这可能是在HTML页面中的整合问题所导致的。 此外,在全屏模式下,由于Flash Player并不会在浏览器上下文中运行,因此stage video可以不考虑wmode的值而始终可用。 但是请注意,当离开全屏模式时,stage video可能又会变得不可用,然后将您的SWF文件重新放置于浏览器上下文环境中,此时stage video受到wmode参数的影响。

注意: 由于该问题的存在,在利用StageVideo API的视频播放器中,您应当始终使有一个传统Video对象作为备用。

因此,您需要通过某种方式来构造视频播放器,以作出合适的反应。 幸运的是,这是相当容易的事情。 如果stage video变得可用,只需将NetStream对象附加到刚刚获取的St通常,您需要按照如下方式来修改toggleStageVideo函数:

private function toggleStageVideo(on:Boolean):void
{
    // if StageVideo is available, attach the NetStream to StageVideo
    if (on)
    {
        stageVideoInUse = true;
        if ( sv == null )
        {
            sv = stage.stageVideos[0];
            sv.addEventListener(StageVideoEvent.RENDER_STATE, stageVideoStateChange);
        }
        sv.attachNetStream(ns);
        if (classicVideoInUse)
        {
            // If using StageVideo, just remove the Video object from
            // the display list to avoid covering the StageVideo object
            // (always in the background)
            stage.removeChild ( video );
            classicVideoInUse = false;
        }
    } else
    {
        // Otherwise attach it to a Video object
        if (stageVideoInUse)
            stageVideoInUse = false;
        classicVideoInUse = true;
        video.attachNetStream(ns);
        stage.addChildAt(video, 0);
    }
    if ( !played )
    {
        played = true;
        ns.play(FILE_NAME);
    }
}  

这段代码可以妥善地处理当stage video变得可用或不可用时退却到一个传统Video对象的情况。 当把NetStream重新附加到StageVideo对象时,由于此时必须分配硬件资源,所以在附加NetStream和在屏幕上看到像素这两个时刻之间,您可能会看到一点延迟。

如果您想了解更多关于如何利用StageVideo API的信息,请参阅本文的附件。 附件中包含了一个简单的视频播放器,用来对各种不同场景进行说明。

场景

正如您在整篇文章中看到的,在Flash Player中播放视频时,可能会遇到不同的场景。 下面列出了您在使用Video或StageVideo对象来播放视频时可能遇到的不同场景路径

  • Video对象发挥着非加速编解码器的作用:将会使用CPU来进行解码和合成。
  • Video对象发挥着GPU加速编解码器(H.264)的作用:将使用GPU来解码,但CPU仍可用于合成。
  • StageVideo对象发挥着非加速编解码器的作用:CPU将用于解码,但GPU将用于合成。
  • StageVideo对象发挥着GPU加速编解码器(H.264)的作用:GPU将用于解码和合成。CPU在整个流水线中将不会使用到。这就是您所希望达到的最佳性能的"direct path"场景。

延伸与意义

请务必尝试用面向开发者的Adobe Flash Player 10.2 beta版本,在介绍新特征和增强功能的Adobe Labs中,现在包含了一个新的视频硬件加速模型,该模型使得视频播放性能得到了显著的增强。

为了充分体验这一新推出的StageVideo API,Adobe已经引入了两处深受关注的小改进:

  • 支持多个显示器的全屏模式:全屏内容在第二台显示器上将保持全屏模式,从而允许用户在另一台显示器上工作的同时观看全屏内容。
  • 全屏检测能力:新的allowFullScreen属性现在已经适用于Stage对象,它使得开发人员能够检测当前容器/托管网页是否允许播放器全屏显示。

StageVideo API毫无疑问将会改变视频播放的性能。 在某些场景下,stage video可以将处理器的使用率降低高达85个百分点。 即便对stage video的使用有些要求,但还请务必尽可能地使用它。 这将允许开发者充分利用视频渲染流水线的全面硬件加速,而这将带来一流的视频播放性能。

Flash的视频神奇StageVideo,布布扣,bubuko.com

时间: 2024-11-08 18:52:10

Flash的视频神奇StageVideo的相关文章

MVC应用程序显示Flash(swf)视频

前段时间, Insus.NET有实现<MVC使用Flash来显示图片>http://www.cnblogs.com/insus/p/3598941.html 在演示中,它也可以显示Flash的swf媒体文件.不过你得下载那个swfobject.js组件. 本次,Insus.NET想给大家演示另外的方法,MVC与jQuery结合.你无需要下载任何第三方falsh组件. 你需要在MVC应用程序下, 根据上图中的#87代码,我们以Action方法SwfVideoDemo()创建一个视图: #1步,添

html5结合flash实现视频文件在所有主流浏览器兼容播放

由于html5的出现,让网页中的视频.音频有了更加便捷的实现方式.但是video.audio标签只在IE 9+.Safari 3+.FireFox 4+.Opera 10+.Chrome 3+的浏览器版本得到了支持,并且各浏览器对于视频编码格式的支持不一致,这就需要我们考虑一个综合的实现方案,使得视频在不同浏览器中都能顺利播放,而且在老版本的浏览器中也能得到支持. 以下是结合项目经验,总结出的几种方案,与大家分享. 方案1.使用VideoJS插件实现兼容 插件下载http://videojs.c

无需Flash录视频——HTML5中级进阶

视频采集 本篇介绍的栗子 都是在chrome 47 版本以上的,低版本的可能会出现白屏和错误. 1.安全环境 随着Chrome版本的升高,安全性问题也越来越被重视,较新版本的Chrome浏览器在调用一些API时需要页面处在安全环境中.本篇文章所介绍的API函数,都需要在安全环境中执行.如果处在非安全环境下 ( http页面 ) 这些API就会有意想不到的问题. 比如 getUserMedia()就会报出警告,并执行出错. 而在设备枚举enumerateDevices()时,虽然不会报错,但是他隐

Chrome强制更新Flash导致视频广告屏蔽扩展失效的解决办法

本文章仅对旧版本的Chrome浏览器有效.(本人环境 Chrome V31) 最近Chrome强制更新Flash至18.0.0.209,是因为Flash爆出重大漏洞,会导致运行Flash的木马网页可以入侵用户系统. 不过新版本的Flash会导致大部分的视频广告屏蔽扩展失效,而无法播放视频.那如何解决呢? 我们可以通过利用旧版本的Flash文件来覆盖新版本,让Chrome运行旧版本的Flash插件. 不过这样会让你的电脑暴露在漏洞的危险之下,本人强烈推荐你安装一款屏蔽网页Flash的插件,仅在常用

如何下载某些 flash 在线视频 并使用ffmpeg下载分段并加密的m3u8视频流

有些网站使用 flash 在线播放视频,不方便进行下载. 可以使用 Chrome 的 Developer Tools 模拟成 iOS 设备(通过修改 User Agent),然后取得 h.264 视频流的地址. 取得 h.264 视频流的地址 1. 在页面上打开 Developer Tools (开发者工具),点击坐上的"手机"按钮(如下图). 2. 在左边 "Device" 选择 "Apple iPhone" 或 "Apple iPa

HTML嵌套Flash播放视频

1. 视频内容来源于本地,通过本地播放器播放 代码: <!-- 此段视频源文件在本地,通过本地Flash播放器播放,不需要连接网络 --> <EMBED style=" margin: 5px auto; width:900px; height: 400px"; src="video\shipin.swf" quality= "high" wmode="transparent" pluginspage=&qu

Flash视频传送架构

Flash 可以提供三种完全不同的视频传送机制:渐进式下载(progressive download).流式传输(streaming)和HTTP流式传输(HTTP streaming). 我将利用少许代码片段简单地说明所有上述三种传送机制.如果你使用视频播放器应用程序,则这些底层的细节将是不可见的. 渐进式下载 渐进式下载是Flash提供的最简单的.因此也是使用最广泛的视频播放机制. 相应的视频文件存储于 HTTP 服务器,你需要做的所有操作是指定视频的 URL. Flash将视频下载到浏览器的

如何解决div层被flash遮盖的问题

页面构建中的Flash层会遮挡Div的问题,一般通过设置wmode="transparent" 或wmode="window"就可以解决.不过对于Flash视频这个貌似不太凑效. 对于Flash遮挡的问题,首先来了解一些wmode的一些属性值. wmode的5种取值 Window模式 默认情况下的显示模式,在这种模式下 flash player 有自己的窗口句柄,这就意味着 flash 影片是存在于 Windows 中的一个显示实例,并且是在浏览器核心显示窗口之上的

基于Adobe Flash平台的3D技术剖析

写在前面 从黑暗之光,佛本是道,大战神的有插件3D页游.再到如今的魔龙之戒. 足以证明,3D无插件正在引领页游技术的潮流. 目前,要做到3D引擎,有以下几个选择. 说到这里,我们发现.这些都不重要. 因为本文目的就是从头到尾分析一下Adobe Flash平台目前对3D游戏的支持情况. 言归正转 本来是想写一些关于Stage3D.FlasCC以及基于Flash的3D页游引擎方面的文章. 也做了几天的准备工作,希望把这些事情能够给大家(主要是公司项目组内的成员)分享,并理清头绪. 然而就在周末准备资