加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

actionscript-3 – JWPlayer:尝试将视频播放器绑定在我自己的容

发布时间:2020-12-15 07:31:35 所属栏目:百科 来源:网络整理
导读:我正在使用6.0.2813(http://developer.longtailvideo.com/trac/)的JWPlayer源代码.虽然我有一个movieclip并且我将jwplayer类作为一个孩子添加,但jwplayer创建自己为主舞台的一个孩子,因此允许它扩展到舞台的边界,而不是我的flashclip(我想成为一个可调整大小
我正在使用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视频移动和调整播放器大小,但仍然逐步加载,需要注释掉或删除com.longtailvideo.jwplayer.view.View.resizeMasker()方法的内容:

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所述:

JW Player 6 — Open Source Edition
The use of the JW Player Open Source edition is governed by a Creative Commons license. In short:

JW Player Open Source – You can use,modify,copy,and distribute this edition as long as it’s for non-commercial use,you provide attribution,and share under a similar license. The license summary and full text can be found here: 07003

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读