7

私は6.0.2813(http://developer.longtailvideo.com/trac/)のJWPlayerソースコードを使用しています。ムービークリップがあり、jwplayerクラスを子として追加したにもかかわらず、jwplayerは自分自身を次のように作成しますメインステージの子であるため、フラッシュ内のムービークリップ (サイズ変更可能/ドラッグ可能なコンテナーにしたい) ではなく、ステージの境界まで拡張できます。

私はフォーラムに助けを求めましたが、彼らはこのように意図したことはなく、あまり役に立たなかったと言いました。ソースコードに詳しい人が正しい方向に向けてくれることを期待していました.

JWPlayer をムービークリップに含めるにはどうすればよいですか?

編集:

私は少し進歩しました。

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.stageHeightandRootReference.stage.stageWidthが使用されていたので、RootReference.stage.heightandに切り替えましたRootReference.stage.width。これでコンパイルが完了し、ビデオはコンテナー内にありますが、ビデオの左上が video_container の中心にあり、ビデオはコンテナーのサイズではなく、ビデオのサイズにサイズ変更されます。また、コントロールは完全にめちゃくちゃです。

しかし、ビデオのサイズを変更して移動することができました

4

3 に答える 3

2

JW Playerはアクセスできず、プレーヤーの外部の要素にアクセスせずに特殊JavaScript化されたものを使用するというあなたの書面によるコメントによると、最善の解決策はJW PlayerEnterpriseEditionを使用することです。Firefox Source3D Game/Chat Engine DOM

このソリューションにより、マーケティング&エンジニアリング部門と連絡を取り、JWPlayerを独自の製品に統合するためのターンキーソリューションを提供できます。

ライセンス情報も 含まれている下の画像をクリックしてください。 ここに画像の説明を入力してください

于 2012-12-22T06:03:18.637 に答える
2

フラッシュは私の得意分野ではないため、質問のjwPlayer部分に対処します。

ここでの問題は、 jwPlayerが単純なフラッシュ プレーヤーではなく、HTML5 マルチメディア プレーヤーでもあることです。


解決策 1: Flash オブジェクトに埋め込まれたSWFObject

jwPlayerは既にSWFObjectと互換性があるため、それ (つまり、swfobject.js) をメディエーターplayer.swfとして使用して、ファイル (別名 jwPlayer ) をフラッシュ ステージにロードします。確かに、jwPlayerを直接使用するのとは対照的に、 SWFObjectはコンテナとして機能し、ステージ内の「バインドされたアイテム」になります。

シンプルなフラッシュ ビデオ プレーヤーを使用していることを除いて、このソリューションを示すオンライン デモを次に示します。

SWFObject ロゴが埋め込まれた Flash Web サイト ミュージック ビデオの再生
Flash Web サイト swfObject に関するドキュメント

そのフラッシュ Web サイトのHTML ソース ページには、ブラウザのビューポート全体に表示されるファイルとしてRockOnFlashLogo.swfが示されていることに注意してください。よく見ると、AS3書かれています。

jwPlayer v4とは異なり、セキュリティが緩いため、そのバージョンを Flash Web サイトに埋め込むという多くのアイデアがインターネット上に浮かびましたが、現在のjwPlayerライセンス チェック、Web ページの Ready Event Listeners、および一般的なプラグインの統合に問題があると思います。ビデオ コンテンツのストリーミングから発生する可能性がある問題について言及します。

私見、新しいjwPlayer API および Player は、Web ページのインストールを介して使用することを目的としています。


解決策 2: Flash オブジェクトの上にSWFObjectを配置する

このメソッドは、jwPlayerを本来の使用方法で扱います。ウェブページのインストールとして。私の動機は、このGoogle Chrome Experimentのオンライン デモにありました。荒野のダウンタウン

このデモでは、戦略的に同期されたブラウザー ウィンドウをメインのブラウザー ウィンドウの上に配置しています。メインのブラウザー ウィンドウが担当しますが、すべてのウィンドウがエクスペリエンス全体を構成します。同じ方法ですが、フラッシュ フレーバーを使用して、現在のプロジェクトで優れた結果を得ることができます。

あなたの Flash オブジェクトが担当し、jwPlayer Web ページ コンポーネントに割り当てられたインタラクティブフレーム内に含まれます。確かに、jwPlayer のこのインタラクティブなフレーム再配置(たとえば、フレーム エッジのドラッグによる) とサイズ変更(たとえば、フレームの右下にサイズ変更アイコンがあります)を受け入れることができ、 SWFObject標準の埋め込みを介して Web ページ コンポーネント (すなわち) にリレーされます。テクニック (つまり、 で設定された場所サイズ)。player.swfjQuery

以下は、3 つの階層化されたアイテムの Web ページの基本的な断面図です。

ここに画像の説明を入力

黒いレイヤーはWeb ページのレイヤーですHTML赤いレイヤーは、aquaに示されている組み込みのインタラクティブ フレームも含むフラッシュ オブジェクトです。緑色の最上層は、jwPlayerのファイルの SWFObjectです。 player.swf

jwPlayer から Flash オブジェクトへの動作は次のとおりです。

1. Web ページjwPlayer APIには、アクティブなイベント リスナーがあり、JavaScript を受け入れることができます。
2.次に、jwPlayer APIがプレーヤーから「再生」ステータスを受け取り、プレーヤー イベント ステータスを更新します。
3. Player Event Status はPlay に対してtrueであるため、条件ステートメントをトリガーします。if
4.次に、そのifステートメントがJavaScriptを Flash オブジェクトに送信し、再生モードがtrue であることを示します。
5. Flash オブジェクトこの JavaScript のplayイベントを受け取り、ステージを暗くします。アクアフレームが少ない。

Flash オブジェクトから jwPlayer への動作は次のとおりです。

1.アクアフレームがステージの左側に移動すると、ユーザーインタラクションが発生します。
2. AS3コードは、その場所の JavaScriptを送信しながら、それに応じ水色のフレームを移動します。
3. Web ページは JavaScript を受け取り、jwPlayer プレーヤーを新しい場所に配置する関数を呼び出します。

ヒント:カスタムjwPlayer スキンを使用している場合は、そのスキン テーマを Flash オブジェクトに組み込み、外観を統一します。

このシナリオの利点は、jwPlayerが100% の整合性を維持する一方で、これらの両方の Flash オブジェクトが Web ページで連携して動作することです。ハッキングも、破損も、予期しない結果も、頭痛の種もありません... 標準のjwPlayer APIAS3マークアップが使用されています。

jwPlayer自体にカーソルを合わせると、 100% jwPlayerになりますが、Flash オブジェクトに間接的にバインドされます。

于 2012-12-16T10:14:07.697 に答える
2

私のテスト シナリオがユース ケースを代表するものであると仮定すると、回避策をうまくハックできたと思います。

RootReference.rootアプローチの要点は、 andRootReference.stageを自分が制御する偽のステージ オブジェクトに置き換えることです。ほとんどの jwPlayer クラスは、独自の変数rootstage変数ではなく静的変数を参照するため、ほとんどの場合、これでうまくいくようです。最終的に最も複雑な問題となったのStage.stageVideoは、ハードウェア アクセラレーション ビデオ オブジェクトであると思われるオブジェクトの操作でした。これらは常に にアタッチされているためstage、フェイク ステージ オブジェクトと互換性がありませんでした。これらの主な問題はポジショニングで、ほぼ解決しましたが、まだ 1 つの不具合があります。これについては後で説明しますが、今は問題ありません。

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) {}
    }
}

これは、Web ページを使用していないため、おそらく対処する必要がないものです。

偽のステージ クラスが呼び出され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: http://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, 0, 500, 500);
            
            var bmpData:BitmapData = new BitmapData(500, 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, 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, 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, 0, elmW, elmH);
        }
    }
}

残っている問題は、初期化時のビデオ インスタンスの配置に関係しています。適切なポイントで呼び出すだけStageInterceptor.singleton.updateStageVids();でうまくいくと思いますが、よくわかりません。以下の編集は、これがどのように対処されたかをカバーしています。

を使用していない場合、これがどれだけうまく機能するかわかりませんstageVideo。しかし、運が良ければ、これは物事を正しい方向に動かします。

編集:

クラスを更新してStageInterceptor、ビデオのスケーリングと配置を改善しました。

あと、動画の初期位置(せめてstageVideoならそれでいいのかな?)はcom.longtailvideo.jwplayer.media.VideoMediaProviderクラス内のちょっとした編集で直せそうです。上部の import ステートメントに追加import somePackage.StageInterceptor;してから、この行を置き換えます (ソースへのリンク):

_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, width, height, _config.stretching);
        if (_stage) {
            //_stage.viewPort = new Rectangle(_media.x,_media.y,_media.width,_media.height);
            StageInterceptor.singleton.updateStageVids();
        }
    }
}

これでうまくいくはずですが、ステージビデオ以外ではテストしていません。また、この更新では、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 のオープン ソース バージョンは、サイトに記載されているように、クリエイティブ コモンズ ライセンスの下で管理されていることにも言及したいと思います。

JW Player 6 — オープン ソース エディション JW Player オープン ソース エディションの使用は、クリエイティブ コモンズ ライセンスによって管理されます。要するに:

JW Player オープン ソース - 非営利目的である限り、このエディションを使用、変更、コピー、および配布することができます。帰属表示を提供し、同様のライセンスの下で共有してください。ライセンスの概要と全文は、次の場所にあります: CC BY-NC-SA 3.0

于 2012-12-22T15:14:36.087 に答える