actionscript-3 – JWPlayer:尝试将视频播放器绑定在我自己的容
我正在使用6.0.2813(http://developer.longtailvideo.com/trac/)的JWPlayer源代码.虽然我有一个movieclip并且我将jwplayer类作为一个孩子添加,但jwplayer创建自己为主舞台的一个孩子,因此允许它扩展到舞台的边界,而不是我的flashclip(我想成为一个可调整大小/可拖动的容器).
我向论坛寻求帮助,但是他们说他们从来没有这样做,并没有多大帮助.我希望有人熟悉源代码可以指出我正确的方向. 如何将JWPlayer包含在movieclip中? 编辑: 我取得了一些进展. 我在com / longtailvideo / jwplayer / utils / RootReference.as中找到了RootReference类 public function RootReference(displayObj:DisplayObject) { if (!RootReference.root) { RootReference.root = displayObj.root; RootReference.stage = displayObj.stage; try { Security.allowDomain("*"); } catch(e:Error) { // This may not work in the AIR testing suite } } } 并注意到RootReference.stage是作为孩子添加内容的地方. RootReference.stage = displayObj.stage;将播放器类对象作为displayObj发送的地方我将其更改为RootReference.stage = MovieClip(root).gui.video_container; 然后在整个代码中使用了RootReference.stage.stageHeight和RootReference.stage.stageWidth,因此我将其切换为RootReference.stage.height和RootReference.stage.width.这得到它编译,现在视频在容器内,但视频的左上角是我的video_container中心的中心,视频没有调整到我的容器的大小,而是视频的大小.控件也完全搞砸了. 但我能够调整大小并移动视频 解决方法
假设我的测试场景代表了你的用例,我想我设法破解了一个解决方案.
该方法的要点是将RootReference.root和RootReference.stage替换为您控制的伪阶段对象.因为大多数jwPlayer类引用那些静态变量而不是它们自己的根和阶段变量,所以这似乎在大多数情况下都有效.最复杂的问题是使用Stage.stageVideo对象,我认为这些对象是硬件加速视频对象.它们总是附着在舞台上,因此与假舞台物体不兼容.这些问题的主要问题是定位,而且我已经解决了这个问题,但是我仍然会有一个故障,我稍后会介绍,但现在应该没问题了. jwPlayer嵌入脚本导致了很多问题,所以为了开始我切换到正常的基于SWFObject的嵌入,并向名为getFlashvars()的页面添加了一个javascript函数,返回配置设置.然后,我将com.longtailvideo.jwplayer.utils.Configger.loadExternal()方法更改为以下内容: private function loadExternal():void { if (ExternalInterface.available) { try { //var flashvars:Object = ExternalInterface.call("jwplayer.embed.flash.getVars",ExternalInterface.objectID); var flashvars:Object = ExternalInterface.call("getFlashvars"); if (flashvars !== null) { // TODO: add ability to pass in JSON directly instead of going to/from a string for (var param:String in flashvars) { setConfigParam(param,flashvars[param]); } dispatchEvent(new Event(Event.COMPLETE)); return; } } catch (e:Error) {} } } 这可能是您不必使用网页时无需处理的事情. 伪阶段类称为StageInterceptor,是一个单例.要应用它,RootReference类中有一些小的更改: package com.longtailvideo.jwplayer.utils { import flash.display.DisplayObject; import flash.display.Stage; import flash.system.Security; // added -------- import somePackage.StageInterceptor; /** * Maintains a static reference to the stage and root of the application. * * @author Pablo Schklowsky */ /* Modified for a stackoverflow question: https://stackoverflow.com/questions/13325318/jwplayer-trying-to-bound-the-video-player-inside-my-own-container */ public class RootReference { /** The root DisplayObject of the application. **/ public static var root:DisplayObject; // altered -------- /** A reference to the stage. **/ private static var _stage:StageInterceptor; // altered -------- public static function get stage():StageInterceptor { return _stage; } public function RootReference(displayObj:DisplayObject) { if (!RootReference.root) { // altered -------- RootReference.root = StageInterceptor.singleton; RootReference._stage = StageInterceptor.singleton; try { Security.allowDomain("*"); } catch(e:Error) { // This may not work in the AIR testing suite } } } } } 另外,我从类中删除了set stage()setter方法. 在文档类中,我有以下代码. MouseEvent.CLICK处理程序用于测试定位和重新调整影片大小.你唯一真正需要的是前几行: // add StageInterceptor to the display tree addChild(StageInterceptor.singleton); // add the jwPlayer: var p:Player = new Player(); StageInterceptor.singleton.addChild(p); // for testing only: stage.addEventListener(MouseEvent.CLICK,function(e:MouseEvent):void { var stg:StageInterceptor = StageInterceptor.singleton; if (e.altKey) { // click + alt: ignored (so can play,etc) return; } else if (e.shiftKey) { // click + shift: resizes stg.width = e.stageX - stg.x; stg.height = e.stageY - stg.y; } else { // click: moves video stg.x = e.stageX; stg.y = e.stageY; } }); 我把StageInterceptor放在somePackage包中.它看起来像这样: package somePackage { import flash.display.Bitmap; import flash.display.BitmapData; import flash.display.InteractiveObject; import flash.display.Shape; import flash.display.Sprite; import flash.events.Event; import flash.geom.Point; import flash.geom.Rectangle; import flash.media.StageVideo; public class StageInterceptor extends Sprite { private static var _singleton:StageInterceptor = new StageInterceptor(); public static function get singleton():StageInterceptor { return _singleton; } private var _bg:Bitmap; public function StageInterceptor() { super(); scrollRect = new Rectangle(0,500,500); var bmpData:BitmapData = new BitmapData(500,false,0); _bg = new Bitmap(bmpData); _bg.alpha = 0.1; _bg.cacheAsBitmap = true; addChild(_bg); if (stage) { initOnStage(); } else { addEventListener(Event.ADDED_TO_STAGE,initOnStage); } } private function initOnStage(e:Event = null):void { if (e) { removeEventListener(Event.ADDED_TO_STAGE,initOnStage); } stage.addEventListener(Event.RESIZE,onStageResized); } private function onStageResized(e:Event):void { e.stopImmediatePropagation(); dispatchEvent(new Event(Event.RESIZE)); updateStageVids(); } public function updateStageVids():void { if (stage.stageVideos.length > 0) { for each (var sv:StageVideo in stage.stageVideos) { if (!sv.videoWidth || !sv.videoHeight) { continue; } var rect:Rectangle = stretch(sv.videoWidth,sv.videoHeight,width,height); rect.x = Math.max(0,x + 0.5 * (width - rect.width)) rect.y = Math.max(0,y + 0.5 * (height - rect.height)); sv.viewPort = rect; } } } override public function get width():Number { return scrollRect.width; } override public function set width(value:Number):void { if (value != width) { _bg.width = value; scrollRect = new Rectangle(0,value,scrollRect.height); dispatchEvent(new Event(Event.RESIZE)); updateStageVids(); } } override public function set height(value:Number):void { if (value != height) { _bg.height = value; scrollRect = new Rectangle(0,scrollRect.width,value); dispatchEvent(new Event(Event.RESIZE)); updateStageVids(); } } override public function get height():Number { return scrollRect.height; } public function get stageWidth():Number { return scrollRect.width; } public function get stageHeight():Number { return scrollRect.height; } public function get scaleMode():String { return stage.scaleMode; } public function set scaleMode(value:String):void { stage.scaleMode = value; } public function get displayState():String { return stage.displayState; } public function set displayState(value:String):void { stage.displayState = value; } public function get focus():InteractiveObject { return stage.focus; } public function set focus(value:InteractiveObject):void { stage.focus = value; } public function get stageVideos():* { return stage.stageVideos; } override public function set x(value:Number):void { if (value != x) { super.x = value; updateStageVids(); } } override public function set y(value:Number):void { if (value != y) { super.y = value; updateStageVids(); } } /** * Copied from com.longtailvideo.jwplayer.utils.Stretcher,modified to only * do 'uniform' stretch and to return a Rectangle class. **/ public static function stretch(elmW:Number,elmH:Number,availW:Number,availH:Number):Rectangle { var scale:Number = Math.min(availW / elmW,availH / elmH); elmW = Math.round(elmW * scale); elmH = Math.round(elmH * scale); return new Rectangle(0,elmW,elmH); } } } 剩下的问题与视频实例初始化时的定位有关.我想简单地调用StageInterceptor.singleton.updateStageVids();在正确的点上会做到这一点,但我不确定.下面的编辑涵盖了如何解决这个问题. 如果你不使用stageVideo,我不确定这会有多好用.但是,运气好的话,这会把事情朝着正确的方向发展. 编辑: 我已经更新了StageInterceptor类,以便更好地缩放和定位视频. 此外,它看起来像视频的初始位置(至少当它是舞台视频时,你正在使用的是什么?)可以通过com.longtailvideo.jwplayer.media.VideoMediaProvider类中的小编辑来纠正.添加import somePackage.StageInterceptor;到顶部的import语句然后替换this line (link to source): _stage.viewPort = new Rectangle(_media.x,_media.y,_ media.width,_ media.height); 至: StageInterceptor.singleton.updateStageVids(); 所以方法看起来像: /** Resize the video or stage.**/ override public function resize(width:Number,height:Number):void { if(_media) { Stretcher.stretch(_media,height,_config.stretching); if (_stage) { //_stage.viewPort = new Rectangle(_media.x,_media.width,_media.height); StageInterceptor.singleton.updateStageVids(); } } } 这应该可以解决问题,但我还没有测试过非stageVideos.而且,此更新还假设您正在逐步播放视频,而不是使用RTMP媒体. 编辑: 要使用非StageVideo视频移动和调整播放器大小,但仍然逐步加载,需要注释掉或删除 protected function resizeMasker():void { /* if (_displayMasker == null) setupDisplayMask(); _displayMasker.graphics.clear(); _displayMasker.graphics.beginFill(0,1); _displayMasker.graphics.drawRect(_components.display.x,_components.display.y,_player.config.width,_player.config.height); _displayMasker.graphics.endFill(); */ } 我还想提一下jwPlayer的开源版本受Creative Commons许可管辖,如on their site所述:
(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |