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所述:
(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
