2

I'm using the Youtube AS3 Player API to load video's in a Flash Project. I get this really annoying Error when loading the Player swf:

SecurityError: Error #2047: Security sandbox violation: parent: http://www.degoudenglimlach.be/main.swf cannot access http://www.youtube.com/[[IMPORT]]/s.ytimg.com/yt/swf/watch_as3-vflbgr4dW.swf.

I tried adding the following to my code before loading the swf but it doesn't make any difference:

Security.allowDomain("*");
Security.allowDomain("www.youtube.com");
Security.allowDomain("youtube.com");
Security.allowDomain("s.ytimg.com");
Security.allowDomain("i.ytimg.com");

Any Help would be great.

Here's my full Wrapper class:

package be.zap.media 
{
    import flash.display.Loader;
    import flash.display.Sprite;
    import flash.events.Event;
    import flash.net.URLRequest;
    import flash.system.Security;
    import flash.system.System;

    /**
     * ...
     * @author Yens Resmann
     */
    public class ZapYoutubeVideo extends Sprite
    {
        private var ytPlayer : Object;
        private var ldr : Loader
        private static const YOUTUBE_EMBEDDED_PLAYER_URL : String = "http://www.youtube.com/v/VIDEO_ID?version=3";

        public static const PLAYER_READY : String = "playerReady";

        public static const QUALITY_SMALL : String = "small";
        public static const QUALITY_MEDIUM : String = "medium";
        public static const QUALITY_LARGE : String = "large";
        public static const QUALITY_HD720 : String = "hd720";
        public static const QUALITY_HD1080 : String = "hd1080";
        public static const QUALITY_HIGHRES : String = "highres";
        public static const QUALITY_DEFAULT : String = "default";

        public function ZapYoutubeVideo() 
        {
            Security.allowDomain("*");
            Security.allowDomain("www.youtube.com");
            Security.allowDomain("youtube.com");
            Security.allowDomain("s.ytimg.com");
            Security.allowDomain("i.ytimg.com");

            ldr = new Loader();
            ldr.contentLoaderInfo.addEventListener(Event.INIT, handleInitPlayer);
            addEventListener(Event.REMOVED_FROM_STAGE, handleRemovedFromStage);
        }

        public function initPlayer(vidId : String) 
        {
            var url : String = YOUTUBE_EMBEDDED_PLAYER_URL.split("VIDEO_ID").join(vidId);
            ldr.load(new URLRequest(url));
        }

        private function handleInitPlayer(e:Event):void 
        {
            addChild(ldr);
            ldr.contentLoaderInfo.removeEventListener(Event.INIT, handleInitPlayer);

            ldr.content.addEventListener("onReady", handlePlayerReady);
            ldr.content.addEventListener("onError", handlePlayerError);
            ldr.content.addEventListener("onStateChange", handlePlayerStageChange);
            ldr.content.addEventListener("onPlaybackQualityChange", handlePlayerQualityChange);
        }

        private function handlePlayerReady(e:Event):void 
        {
            ytPlayer = ldr.content;
            dispatchEvent(new Event(PLAYER_READY));
        }

        public function queueVideoById(videoID : String, quality : String = QUALITY_DEFAULT):void 
        {
            ytPlayer.cueVideoById(videoID, 0, quality);
        }

        public function loadVideoById(videoID : String, quality : String = QUALITY_DEFAULT):void 
        {
            ytPlayer.loadVideoById(videoID, 0, quality);
        }

        public function queueVideoByUrl(url : String, quality : String = QUALITY_DEFAULT):void 
        {
            ytPlayer.cueVideoByUrl(url, 0, quality);
        }

        public function loadVideoByUrl(url : String, quality : String = QUALITY_DEFAULT):void 
        {
            ytPlayer.loadVideoByUrl(url, 0, quality);
        }

        public function setSize(w:int, h:int):void 
        {
            ytPlayer.setSize(w, h);
        }

        private function handlePlayerError(e:Event):void 
        {

        }

        private function handlePlayerStageChange(e:Event):void 
        {

        }

        private function handlePlayerQualityChange(e:Event):void 
        {

        }

        private function handleRemovedFromStage(e:Event):void 
        {
            removeEventListener(Event.REMOVED_FROM_STAGE, handleRemovedFromStage);
            dispose();
        }

        public function dispose():void 
        {
            ytPlayer.destroy();
            if (ldr) {
                if (contains(ldr)) {
                    removeChild(ldr);
                }
                ldr = null;
            }
        }

        /**
         * parse out the Youtube Video ID from the video URL
         * @param   url
         * @return String
         */
        public static function getIdFromURL(url:String):String
        {
            var parts : Array = [];
            if (url.indexOf("watch?v=") != -1) {
                parts = url.split("watch?v=");
            } else if (url.indexOf("watch/v/") != -1) {
                parts = url.split("watch/v/");
            } else if (url.indexOf("youtu.be/") != -1) {
                parts = url.split("youtu.be/");
            }
            return String(parts[1]).split("/").join("");
        }

        /**
         * get the thumbnail of the video
         * @param String youtube Video ID
         * @return URLRequest
         */
        public static function getThumbnail(videoId : String):URLRequest
        {
            return new URLRequest("http://img.youtube.com/vi/" + videoId + "/0.jpg"); 
        }

    }

}
Yens
  • 915
  • 4
  • 12
  • 24

3 Answers3

1

I don't think it's possible , look at the error messages and you should see that they mainly have to deal with the fact that YouTube hasn't updated their crossdomain policy file and doesn't specify a meta policy. here's their policy file:

 <!-- http://www.youtube.com/crossdomain.xml --> 
 <!DOCTYPE cross-domain-policy 
  SYSTEM "http://www.macromedia.com/xml/dtds/cross-domain-policy.dtd"> 
 <cross-domain-policy> 
  <allow-access-from domain="*.youtube.com" /> 
  <allow-access-from domain="s.ytimg.com" /> 
 </cross-domain-policy> 

They need to add a line like this:

 <site-control permitted-cross-domain-policies="all"/>
PatrickS
  • 9,539
  • 2
  • 27
  • 31
  • So API is acutally pretty unless they update this policy file? – Yens Sep 24 '10 at 10:13
  • well, it's working actually , these errors are mostly warnings that the policy file should be updated. it's annoying but there isn't much one can do about it – PatrickS Sep 24 '10 at 16:43
  • Most of this Errors are warnings indeed. If this was the case, I wouldn't mind that much but the error I'm talking about makes Firefox + FP10.1 Crash for some reason. – Yens Sep 25 '10 at 08:13
  • I don't think a security error would provoke a crash, at the worst you wouldn't be able to access content. I'm actually developing with the YT AS3 API as we speak, I had a few crashes today and re-installing Flash Player solved the issue. – PatrickS Sep 25 '10 at 08:23
  • The crashes I have are caused by the new way of handeling plugin errors by Firefox 3.6.10 If you have installed Firefox 3.6.10 and the Flash Player 10.1 Debug player, every Runtime Error in Flash causes Firefox to crash. You can fix this by changing 2 values in the about:config file: http://nwebb.co.uk/blog/?p=538 – Yens Sep 27 '10 at 12:06
  • so it's not YouTube related, good to know either way...thanks for posting the info! – PatrickS Sep 27 '10 at 15:06
  • wasn't able to replicate the crashes. i have firefox 3.6.10 with flash player debug MAC 10,1,85,3 – PatrickS Sep 28 '10 at 04:28
  • 2
    hm then it's probably a Windows 7 issue. maybe I should consider using a mac :p – Yens Sep 28 '10 at 08:33
1

I am using this function

private function test():void 
{ 
    var ytLoader:SWFLoader = new SWFLoader();
    ytLoader.addEventListener(Event.INIT, playerLoaderInitHandler);
    ytLoader.loaderContext = new LoaderContext(true);
    ytLoader.load("http://www.youtube.com/v/TXrc6BwGCXE?version=3");
}
private function playerLoaderInitHandler(event:Event):void
{
    var loader:SWFLoader = event.currentTarget as SWFLoader;
    addChild(loader);
}

I am using SWFLoader instead of Loader.

samfromlv
  • 1,001
  • 1
  • 10
  • 17
  • Thanks, greensock's SWFLoader class worked without issues. The native flash's Loader class no longer seems to work, after youtube's changes. It used to work fine before. Not only it needs "https", but keeps giving out "security error", even after adding all types of system.security() functions in the script file. – Vishwas Oct 05 '16 at 13:23
0

I got same issue and spend a lot of time trying to fix without hiding the error. So i made a very crazy move. According to my error, further trace stack looks like that:

error before ....
 cannot access https://s.ytimg.com/yts/swfbin/player-vflzYgZmb/watch_as3.swf.
 at flash.display::DisplayObject/get parent()
 at fl.managers::FocusManager/isTabVisible()
 at fl.managers::FocusManager/tabEnabledChangeHandler()
 at flash.events::EventDispatcher/dispatchEventFunction()
 at flash.events::EventDispatcher/dispatchEvent()
 at com.google.youtube.ui::UIElement/onAddedToStage()

So what I noticed, that youtube player API is checking if tab childrens are enabled, so I just removed it adding in container MC , where player is placed:

this.tabChildren = false; 

and guess what - no more error! And also I needed to add to stage player after setting tabChildren to false and when player is ready.

celsyum
  • 1
  • 1