YouTube Mixer
/**
* Copyright gupon ( http://wonderfl.net/user/gupon )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/6tsW
*/
package {
import flash.display.Sprite;
import flash.events.Event;
[SWF(width=465,height=465,frameRate=60)]
public class YouTubeSwitcher extends Sprite {
private static const MAX_PLAYER_NUM:int = 2;
// objects
private var box:SearchBox;
private var players:Array;
private var parentPlayer:ParentPlayer;
// containers
private var parentCont:Sprite;
private var playerCont:Sprite;
private var textsCont:Sprite;
private var boxCont:Sprite;
public function YouTubeSwitcher() {
makeContainers();
makePlayers();
setSearchBox();
addEventListener( Event.ADDED_TO_STAGE, function( event:Event ):void{
box.setFocus();
});
}
/**
* ---------------------------
* public methods
* ---------------------------
*/
public function changeVideo( event:PlayerEvent ):void{
if( playerCont.numChildren ) playerCont.removeChildAt(0);
var player:YouTubePlayer;
if( players.length > event.index ){
player = players[ event.index ];
if( player.available ){
playerCont.addChild( player );
}
}
}
/**
* ---------------------------
* private methods
* ---------------------------
*/
private function start( event:PlayerEvent ):void{
parentPlayer.removeEventListener( PlayerEvent.PLAY, start );
parentPlayer.start( 136/2, MAX_PLAYER_NUM );
parentPlayer.addEventListener( PlayerEvent.CHANGE_VIDEO, changeVideo );
}
private function setParent():void{
parentPlayer = new ParentPlayer();
parentPlayer.addEventListener( PlayerEvent.PLAYER_READY, function( event:PlayerEvent ):void{
parentPlayer.removeEventListener( PlayerEvent.PLAYER_READY, arguments.callee );
parentPlayer.search("scrumdiddlyumptious");
});
parentPlayer.addEventListener( PlayerEvent.VIDEO_CUED, function( event:PlayerEvent ):void{
parentPlayer.removeEventListener( PlayerEvent.VIDEO_CUED, arguments.callee );
parentPlayer.play();
});
parentPlayer.addEventListener( PlayerEvent.PLAY, start );
parentCont.addChild( parentPlayer );
}
private function makeContainers():void{
addChild( parentCont = new Sprite());
addChild( playerCont = new Sprite());
addChild( textsCont = new Sprite());
addChild( boxCont = new Sprite());
}
private function makePlayers():void{
players = [];
var count:int=0;
for( var i:int=0;i<MAX_PLAYER_NUM;i++){
var player:YouTubePlayer = new YouTubePlayer();
players.push( player );
player.addEventListener( PlayerEvent.PLAYER_READY, function( event:PlayerEvent ):void{
player.removeEventListener( PlayerEvent.PLAYER_READY, arguments.callee );
if( ++count == MAX_PLAYER_NUM ) setParent();
});
}
}
private function setSearchBox():void{
box = new SearchBox( this );
boxCont.addChild( box );
box.addEventListener( SearchBoxEvent.REQUEST, function( event:SearchBoxEvent ):void{
var player:YouTubePlayer;
var tmp:Array = players.slice(0);
while( tmp.length ){
player = tmp.splice( Math.floor( Math.random() * tmp.length ))[0];
if( !player.available ) break;
}
player.search( event.keyword );
player.addEventListener( PlayerEvent.VIDEO_CUED, function( event:PlayerEvent ):void{
player.removeEventListener( PlayerEvent.VIDEO_CUED, arguments.callee );
player.play();
});
});
}
}
}
import flash.display.Loader;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.IOErrorEvent;
import flash.net.URLLoader;
import flash.net.URLRequest;
import flash.system.Security;
import flash.utils.escapeMultiByte;
class YouTubePlayer extends Sprite{
private static const PLAYER_URL:String = "http://www.youtube.com/apiplayer?version=3";
private static const YOUTUBE_DOMAIN:String = "www.youtube.com";
private static const SEARCH_URL_BASE:String = "http://gdata.youtube.com/feeds/api/videos?vq=";
protected var player:Object;
protected var defaultVolume:Number = 80;
private var loader:Loader;
public var available:Boolean = false;
public function YouTubePlayer() {
setBlack();
setPlayer();
}
public function search( keyword:String ):void{
treasureHunt( escapeMultiByte( keyword ) );
}
public function play():void{
player.playVideo();
addEventListener( Event.ADDED, addedHandler );
addEventListener( Event.REMOVED, removedHandler );
}
public function addedHandler( event:Event ):void{
player.setVolume( defaultVolume );
}
public function removedHandler( event:Event ):void{
player.setVolume(0);
}
/**
* ---------------------------
* private methods
* ---------------------------
*/
private function setBlack():void{
graphics.beginFill(0);
graphics.drawRect( 0, 0, 465, 465 );
}
private function setPlayer():void{
Security.allowDomain(YOUTUBE_DOMAIN);
loader = new Loader();
loader.contentLoaderInfo.addEventListener( Event.INIT, loaderInitHandler );
loader.contentLoaderInfo.addEventListener( IOErrorEvent.IO_ERROR, function( event:IOErrorEvent ):void{
loader.load( new URLRequest(PLAYER_URL));
});
loader.load( new URLRequest(PLAYER_URL));
}
private function loaderInitHandler( event:Event ):void{
addChild( loader );
loader.content.addEventListener( "onReady", function( event:Event ):void{
player = loader.content;
player.setSize( 465, 465 );
player.setPlaybackQuality("small")
player.setVolume( defaultVolume );
player.addEventListener( "onStateChange", playerStateChangeHandler );
dispatchEvent( new PlayerEvent( PlayerEvent.PLAYER_READY ));
});
}
private function treasureHunt( keyword:String ):void{
var maxResults:String = "&max-results=" + 1;
var url:String = SEARCH_URL_BASE + keyword + maxResults + "&format=1";
var xmlLoader:URLLoader = new URLLoader();
xmlLoader.addEventListener( Event.COMPLETE, function( event:Event ):void{
default xml namespace = new Namespace("http://www.w3.org/2005/Atom");
var str:String = String( xmlLoader.data ).substr( 38 );
readXML( XML( str ));
});
xmlLoader.load( new URLRequest( url ));
}
private function readXML( xml:XML ):void{
var id:String = String( xml.entry.id ).split("/").pop();
player.cueVideoById(id);
}
private function playerStateChangeHandler( event:Event ):void{
var data:Object = Object( event ).data;
switch( int( data )){
case 1:
dispatchEvent( new PlayerEvent( PlayerEvent.PLAY ));
available = true;
break;
case 5:
dispatchEvent( new PlayerEvent( PlayerEvent.VIDEO_CUED ));
break;
}
}
}
import flash.events.Event;
class ParentPlayer extends YouTubePlayer {
private var videoNum:int;
private var secBPM:Number;
private var prevIndex:int;
public function ParentPlayer() {
super();
visible = true;
}
public override function addedHandler(event:Event):void{
}
public override function removedHandler(event:Event):void{
}
public function start( bpm:Number, videoNum:int ):void{
this.videoNum = videoNum;
this.secBPM = toSec( bpm );
player.setVolume(100);
addEventListener( Event.ENTER_FRAME, enterFrameHandler );
function toSec( bpm:Number ):Number{
return 60 / bpm;
}
}
private function enterFrameHandler( event:Event ):void{
var currentTime:Number = player.getCurrentTime() - .1;
var currentIndex:int = Math.floor( currentTime / secBPM ) % ( videoNum + 1 );
if( currentIndex != prevIndex ) {
dispatchEvent( new PlayerEvent( PlayerEvent.CHANGE_VIDEO, false, false, Math.abs( currentIndex )));
}
prevIndex = currentIndex;
}
}
import flash.events.Event;
class PlayerEvent extends Event {
public static const PLAYER_READY:String = "playerReady";
public static const PLAY:String = "play";
public static const VIDEO_CUED:String = "videoCued";
public static const CHANGE_VIDEO:String = "changeVideo";
public var index:int;
public function PlayerEvent(type:String, bubbles:Boolean=false, cancelable:Boolean=false, index:int=-1) {
super(type, bubbles, cancelable );
this.index = index;
}
}
import flash.events.Event;
class SearchBoxEvent extends Event {
public static const REQUEST:String = "request";
public var keyword:String;
public function SearchBoxEvent(type:String, bubbles:Boolean=false, cancelable:Boolean=false, keyword:String = "dummy") {
super(type, bubbles, cancelable);
this.keyword = keyword;
}
}
import flash.events.KeyboardEvent;
import flash.text.TextField;
import flash.text.TextFieldType;
import flash.text.TextFormat;
import flash.text.TextFormatAlign;
import flash.ui.Keyboard;
class SearchBox extends TextField {
private var switcher:YouTubeSwitcher;
public function SearchBox( switcher:YouTubeSwitcher ) {
this.switcher = switcher;
var format:TextFormat = new TextFormat("Century", 18, 0 );
format.align = TextFormatAlign.CENTER;
defaultTextFormat = format;
background = true;
backgroundColor = 0xFFFFFF;
type = TextFieldType.INPUT;
x = 100;
y = 465/2-10;
width = 265;
height = 20;
}
public function setFocus():void{
stage.focus = this;
text = "WORDS TO SEARCH FOR";
setSelection( 0, text.length );
stage.addEventListener( KeyboardEvent.KEY_DOWN, function( event:KeyboardEvent ):void{
if( event.keyCode == Keyboard.ENTER ){
dispatchEvent( new SearchBoxEvent( SearchBoxEvent.REQUEST, false, false, text ));
text = "";
}
});
}
}