views:

492

answers:

0

Hi,

I've tried to use the YoutTube API within a Flex project. But i got this error:

*** Security Sandbox Violation ***
SecurityDomain 'http://www.youtube.com/apiplayer?version=3' tried to access incompatible context 'file:///Users/YouTubePlayer/bin-debug/YouTubePlayer.html'

Here are the two files:

<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
      xmlns:s="library://ns.adobe.com/flex/spark" 
      xmlns:mx="library://ns.adobe.com/flex/halo" minWidth="1024" minHeight="768" xmlns:youtube="youtube.*"
      creationComplete="init();">
 <fx:Script>
  <![CDATA[
   [Bindable]
   private var ready:Boolean = true;

   private function init():void {
    Security.allowInsecureDomain("*");
    Security.allowDomain("*");
    Security.allowDomain('www.youtube.com');
    Security.allowDomain('youtube.com');
    Security.allowDomain('s.ytimg.com');
    Security.allowDomain('i.ytimg.com');
   }

   private function changing():void {
    /*     trace("currentTime: " + player.getCurrentTime());
    trace("startTime: " + player.startTime);
    trace("stopTime: " + player.stopTime);
    timeSlider.value = player.getCurrentTime() */
   }

   private function startPlaying():void {
    player.play();
   }

   private function checkStartSlider():void {
    if(startSlider.value > stopSlider.value)
     stopSlider.value = startSlider.value + 1;
   }
   private function checkStopSlider():void {
    if(stopSlider.value < startSlider.value)
     startSlider.value = stopSlider.value - 1;
   }
  ]]>
 </fx:Script>
 <s:VGroup>
  <youtube:Player id="player" videoID="DVFvcVuWyfE" change="changing();" ready="ready=true"/>
  <s:HGroup>
   <s:Button label="play" click="startPlaying();" />
  </s:HGroup>

  <s:HGroup> 
   <s:HSlider id="timeSlider" width="250" 
        minimum="0" maximum="{player.stopTime}" snapInterval=".01"
        enabled="{ready}"/>
   <s:Label id="currentTimeLbl" text="current time: 0" />
  </s:HGroup>

  <s:HGroup>
   <s:HSlider id="startSlider" width="250" 
        minimum="0" maximum="{player.stopTime}" snapInterval=".01"
        change="checkStartSlider();"
        enabled="{ready}"
        value="0"/>
   <s:Label id="startTimeLbl" text="start time: {player.startTime}" />
  </s:HGroup>

  <s:HGroup>
   <s:HSlider id="stopSlider" width="250" 
        minimum="0" maximum="{player.stopTime}" snapInterval=".01"
        change="checkStopSlider();"
        enabled="{ready}"
        value="{player.stopTime}"/>
   <s:Label id="stopTimeLbl" text="stop time: {player.stopTime}" />
  </s:HGroup>
 </s:VGroup>
</s:Application>

Here is the player

package youtube
{
 import flash.display.Loader;
 import flash.events.Event;
 import flash.events.TimerEvent;
 import flash.net.URLRequest;
 import flash.system.Security;
 import flash.utils.Timer;

 import mx.core.UIComponent;

 [Event(name="change", type="flash.events.Event")]
 [Event(name="ready", type="flash.events.Event")]

 public class Player extends UIComponent
 {
  private var player:Object;
  private var loader:Loader;

  private var _startTime:Number = 0;
  private var _stopTime:Number = 0;
  private var _videoID:String;
  private var metadataTimer:Timer = new Timer(200);
  private var playTimer:Timer = new Timer(200);

  public function Player()
  {
   // The player SWF file on www.youtube.com needs to communicate with your host
   // SWF file. Your code must call Security.allowDomain() to allow this
   // communication.
   Security.allowInsecureDomain("*");
   Security.allowDomain("*");

   // This will hold the API player instance once it is initialized.

   loader = new Loader();
   loader.contentLoaderInfo.addEventListener(Event.INIT, onLoaderInit);
   loader.load(new URLRequest("http://www.youtube.com/apiplayer?version=3"));
  }


  private function onLoaderInit(event:Event):void {
   addChild(loader);
   loader.content.addEventListener("onReady", onPlayerReady);
   loader.content.addEventListener("onError", onPlayerError);
   loader.content.addEventListener("onStateChange", onPlayerStateChange);
   loader.content.addEventListener("onPlaybackQualityChange", onVideoPlaybackQualityChange);
  }

  private function onPlayerReady(event:Event):void {
   // Event.data contains the event parameter, which is the Player API ID 
   trace("player ready:", Object(event).data);

   // Once this event has been dispatched by the player, we can use
   // cueVideoById, loadVideoById, cueVideoByUrl and loadVideoByUrl
   // to load a particular YouTube video.
   player = loader.content;
   // Set appropriate player dimensions for your application
   player.setSize(0, 0);
  }

  private function onPlayerError(event:Event):void {
   // Event.data contains the event parameter, which is the error code
   trace("player error:", Object(event).data);
  }

  private function onPlayerStateChange(event:Event):void {
   // Event.data contains the event parameter, which is the new player state
   trace("player state:", Object(event).data);
  }

  private function onVideoPlaybackQualityChange(event:Event):void {
   // Event.data contains the event parameter, which is the new video quality
   trace("video quality:", Object(event).data);
  }

  [Bindable]
  public function get videoID():String
  {
   return _videoID;
  }

  public function set videoID(value:String):void
  {
   _videoID = value;
  }

  [Bindable]
  public function get stopTime():Number
  {
   return _stopTime;
  }

  public function set stopTime(value:Number):void
  {
   _stopTime = value;
  }

  [Bindable]
  public function get startTime():Number
  {
   return _startTime;
  }

  public function set startTime(value:Number):void
  {
   _startTime = value;
  }

  public function play():void {
   if(_videoID!="") {
    player.loadVideoById(_videoID, 0);

    // add the event listener, so that all 200 milliseconds is an event dispatched
    metadataTimer.addEventListener(TimerEvent.TIMER, metadataTimeHandler);
    // if the timer is running, stop and reset it
    if(metadataTimer.running)
     metadataTimer.reset();
    else
     metadataTimer.start();
   }
  }

  private function metadataTimeHandler(e:TimerEvent):void {
   if(player.getDuration() > 0) {
    startTime = 0;
    stopTime = player.getDuration();

    metadataTimer.reset();
    metadataTimer.stop();
    metadataTimer.removeEventListener(TimerEvent.TIMER, metadataTimeHandler);

    player.playVideo();
    playTimer.addEventListener(TimerEvent.TIMER, playTimerHandler);
    dispatchEvent(new Event("ready"));
   }
  }

  private function playTimerHandler(e:TimerEvent):void {
   if(getCurrentTime() > _stopTime) {
    seekTo(startTime);
   }
   dispatchEvent(new Event(Event.CHANGE));
  }

  public function getCurrentTime():Number {
   if(!player.getCurrentTime())
    return 0;
   else
    return player.getCurrentTime();
  }

  public function seekTo(time:uint):void {
   player.seekTo(time);
  }
 }
}

Hope someone can help.

thx, tux