Working with Vimeo Moogaloop API in Flash
The last weeks I dealt with the vimeo Moogaloop API. The documentation on the JavaScript and Flash API was not so well. But fortunately a couple days ago they updated the documentation for the JavaScript API and then for the Flash API. So now I am able to give an introduction how you can use the Moogaloop API in Flash. The guys from vimeo published a Videowrapper Class which handles the very very basic stuff of the vimeo video player. So you can easily import the vimeo video player in your Flash Projects and you are able to do basic functionality like play(), pause() and loading a new video. But if you wanted to create your own video player, this wrapper class doesnot go too far. So I did some analysis on the moogaloop.swf File and found some interesting functions, that solves some of the problems, which Robert Abramski described in his Blog post Vimeo Player and the Secret API.
In my blog post I will describe how you can use my extended version of the VimeoWrapper class. For a deeper inside of the analysis I will write another blog post. So here you can see the my “ugly vimeo Custom Player” as an example application.
A short explanation of the control buttons. Beginning with the left button :
- Play Button -> Play the vimeo video
- Pause Button -> Pause the vimeo video
- Blue Seek Button -> jump to a defined position at the video
- “C” Button -> Change the color of the vimeo video controls
- “V” Button -> Loading a new Video
- “F” Button -> Resize the vimeo video and the player (Fullscreen Mode)
- “M” Button -> Mute the video sound
- “U” Button -> Unload the vimeo video and stop the loading process
- “Q” Button -> destroy the VimeoPlayer Wrapper Class
Between the video and the controls you can see the duration and the currentTime of the Video and the VideoStatus of the File.
Working with the extended VimeoPlayer Class
And now some coding stuff. You can use my extended VimeoPlayer Class very easily, just create an instance of the player. Have a look here:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
// This is important for the use of the VimeoWrapper Class var exampleVideoClipID:int = 3369107; var player_width:int = 400; var player_height:int = 300; // Create the instance vimeo_player = new VimeoPlayer(exampleVideoClipID, player_width, player_height); vimeo_player.x = vimeo_player.y = 0; // set the position // Listen to the available Events vimeo_player.addEventListener(VimeoEvent.PLAYER_LOADED, handlePlayerLoaded); vimeo_player.addEventListener(VimeoEvent.DURATION, handleDuration); vimeo_player.addEventListener(VimeoEvent.STATUS, handleVimeoStatus); // add the Player to the DisplayList addChild(vimeo_player); |
After that you can work with the VimeoPlayer instance. I created an own VimeoEvent Class, because it is more intuitiv to handle. The first Event VimeoEvent.PLAYER_LOADED is dispatched when the vimeo moogaloop.swf is completely loaded and whole vimeo moogaloop API is available.
The Event VimeoEvent.DURATION is dispatched when the duration of video is changed. This happens when the VimeoPlayer loads a new Video (clipID).
One of the most important changes in my VimeoPlayer Class is the Event VimeoEvent.STATUS. It is always dispatched when something happens in the video control. So it supports 7 different Modes, which you can see at the VimeoPlayingState Class:
VimeoPlayingState Class:
1 2 3 4 5 6 7 |
VimeoPlayingState.PLAYING:String; // will be dispatched when the video is playing VimeoPlayingState.PAUSE:String; // will be dispatched when the video is paused VimeoPlayingState.STOP:String; // will be dispatched when the video is stopped VimeoPlayingState.NEW_VIDEO:String ; // will be dispatched when a new clip is loaded VimeoPlayingState.UNLOAD:String; // will be dispatched when the video is unloaded and removed from the cach VimeoPlayingState.VIDEO_COMPLETE:String; // will be dispatched when the playhead reach the end of the video VimeoPlayingState.BUFFERING:String; // will be dispatched when the playhead reach the end of the video |
VimeoEvent Class:
Every of these Events contains 3 properties, which contains mostly important data for you. Have a look in the VimeoEvent Class:
1 2 3 |
public var currentTime:Number; // of the current video public var duration:Number; // of the currentVideo public var info:String;// mode String of the current VimeoPlayingState |
You can have look how I handled the Events in my "ugly vimeo Video Player":
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
private function handlePlayerLoaded(e:VimeoEvent):void { trace("Player Loaded"); durationView.text = "Duration " + String(vimeo_player.getDuration()); } private function handleDuration(e:VimeoEvent):void { durationView.text = "Duration " + String(vimeo_player.getDuration()); } private function handleVimeoStatus(e:VimeoEvent):void { currentTimeView.text = "" + String(e.currentTime ); currentTimeView.text += (" " + e.info) ; if (e.info == VimeoPlayingState.VIDEO_COMPLETE) { // If the video finished play the nex video from the playlist if (counterPlayList < playlist.length -1) { vimeo_playNewVideo(playlist[counterPlayList]); vimeo_play(); counterPlayList++; } } } |
For dispatching the events I had to implement a little ugly workaround. So a Timer instance is running in the background of the wrapper class. If you are not interested to receive video-based Events from the wrapper class you can turn them off via:
1 2 3 4 |
// when set this to false, the wrapper class will stop dispatching Events - (Perfomance) vimeo_player.enableCompleteEvent = false; // when set this to false, the wrapper class will stop dispatching Playing Status Events (Perfomance) vimeo_player.enablePlayheadEvent= false; |
Control the vimeo video player
Now we will controll our player with our own User Interface. My example app used just a few of them. I think the code is self-explaining.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
public function vimeo_play():void { vimeo_player.play(); } public function vimeo_pause():void { vimeo_player.pause(); } // Value must be in seconds, and the video have to be loaded until this time value public function vimeo_seekTo(time:int):void { vimeo_player.seekTo(time); } // For instance a string value: "FFAAFF" public function vimeo_player_color(colorHexValueString:String):void { vimeo_player.changeColor(colorHexValueString); } // You got the videoID from the vimeo video url public function vimeo_playNewVideo(videoID:int):void { vimeo_player.loadVideo(videoID); } // change the size of the vimeo video public function vimeo_player_size(w:int, h:int):void { vimeo_player.setSize(w,h); } // Value between 0 - 100 public function vimeo_set_volume(value:Number):void { vimeo_player.setVolume(value); } public function vimeo_unload_video():void { vimeo_player.unloadVideo(); } |
There are still further functions and properties. Here a short List or visit the VimeoPlayer Class
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 |
//-------------------------------------------------------------------------- // // Additional getters and setters // //-------------------------------------------------------------------------- /** * return if the video is playing or not * @return */ public function isVideoPlaying():Boolean {} /** * Returns the current video playhead time in milli seconds */ public function getCurrentVideoTime():Number {} /** * returns duration of video in seconds */ public function getDuration():Number {} public function getPlayerColor():String {} public function getVolume():Number {} //-------------------------------------------------------------------------- // // API // //-------------------------------------------------------------------------- public function stop():void {} /** * Completely destroys the instance and frees all objects for the garbage * collector by setting their references to null. */ public function destroy():void{} /** * Toggle loop for the video */ public function toggleLoop():void {} /** * enable HD for the player, but it seems that it is not working?! */ public function hd_on():void {} /** * I think this function will be changed in the future ---> it seems that is not working?! */ public function hd_off():void{} /////////////////// Screen Management //////////////////// public function showLikeScreen():void public function showEmbedScreen():void public function showHDScreen():void public function showShareScreen():void public function showVimeoScreenControlls():void |
Possible problems when working the VimeoWrapper class
I tried my best with the vimeo API, but it seems that the vimeo staff sometimes changed the API. It seems like a work in progress API. So It is very possible that you will run in some issues: I ran in these issues:
- HD Video Functions seemed not working in the embed-mode...
- toogleLoop() Function is not really tested by myself
- toogleFullscreen() Methods throws always an error. Use the setSize() Method instead
- When you are working with the Flash IDE, you will get a Security Sandbox Error because of the missing cossdomain.xml.... But the compiled SWF works fine outside the Flash IDE and on a webserver
- I tried to get some Events about the Video Loading process, but i could not find any solution for this issue. So, sorry!
- It is impossible to create more than one instance of the VimeoPlayer Class, because it is impossible to load the moogaloop.swf file multiple-times into the Flash Player. Or is there a way to do this with depth-copying (via ByteArray operations) the moogaloop file. Has anyone an idea?
- You can not use the VimeoPlayer Class in Adobe Air, because Adobe Air doesnot support the Security.allowDomain() command, which is vital for loading the Vimeo Moogaloop API
So you can see. A lot of stuff you have to know before you use the API. I hope I could answer some questions. The next Time I will continue writing some stuff about the Vimeo API with focus on Flex and AIR, maybe JavaScript, too. If you have problems with my code or examples, please write a comment 🙂
Download the VimeoPlayer Class and the example Application
It looks like Vimeo added some functions since I last documented their secret API.
http://url.robertabramski.com/p
I didn’t see the api_getDuration() function or the api_getCurrentTime() function before, but now they are available. Having those functions makes it possible to build a class that can send all kinds of events out like you did here. I had to use api_setOnFinishCallback to get the end of the video. It’s crazy because you have to ping pong between the HTML and the SWF file using ExternalInterface to get it to work. This solution is much more elegant and now that Vimeo has some better functions geared towards Flash development I will definitely incorporate this less convoluted method of handling events.
Hey thanks Robert for your comment. Your blog post gave me the motivation to do more research on the moogaloop.swf File. So thanks a lot for your work!! Next time I hope to find a solution for getting the loading values, too.
Hi,
Great Post! Thanks for sharing.
Full screen doesnt seem to work. Do you know why?
Thanks,
Joao
@Joao
Yeah Joao, how I described it at the end of my article. The vimeo API throws an error, so I can’t do anything against it. The only recommendation I can give: use the setSize() Function…
Hey guys – did you ever figure out how to disable the space bar play/pause? It seems to work outside of the API so messes up everything if user touches it.
thanks
Hey Roger,
I did some research on your topic. I found a configure variable before you load the moogaloop API
new URLRequest(“http://bitcast.vimeo.com/vimeo/swf/moogaloop.swf?clip_id=” + clip_id + “&width=” + w + “&height=” + h + “&fullscreen=0&disable_keyboard=”+ disable_keyboard);
The last one disabled_keyboard is the variable.
1 (for true) for turn off the keyboard
0 (for false) for turn it on the keyboad
Unfortunately, you can it only use before the API is loaded. The vimeo staff registered a keyListener to the stage object and there is now way to remove it manually, because all the functions are private…
I updated my VimeoPlayer Class with this disableKeyboard function. So feel free to use it! Here is the code
http://code.google.com/p/derhess/source/browse/trunk/AS3/de/derhess/video/vimeo/VimeoPlayer.as
Thank you much! That’s great. How did you ever find that one. This has helped me tons!!
have you noticed that when you add an instantiated vimeoPlayer object to an array, some crazy bugginess happens with the player? this thing is an enigma at times…
FYI, your example and classes no longer work. It throws security errors because the .swf on Vimeo’s server is trying to call “http://vimeo.com/moogaloop/load”
@Chris Wallace
Hi Chris, thanks for your hint. I will have look in the next day and try to fix it. It should not be so difficult to solve this issue. Thx!
@Jon
Hi Jon, indeed this issue sounds strange. But I can’t imagine that the array is the problem… Because adding a variable or an instance to an array change nothing on the variable itself. Maybe it is not possible to for the vimeo Api to create more Vimeo Player in one SWF?! Anyway, I will also check your issue in the next days. Thx for your comment!
Here’s why the example may not be working
http://vimeo.com/forums/topic:21967
Hello & thanks for this post. When you click your custom play button, does the video buffer until the Vimeo bar is fully loaded, and then play? For me it seems it won’t play until the file is fully downloaded (not the case for if I click the actual Vimeo play button).
Hey @Chris, @Dave A and @Chocky
Luckily, my code is working again. So I won’t change it until it stops working again. I hope it works for you, too. Otherwise please leave a comment and then I cange my code. Thx! 🙂
does anyone know why doesn’t the moogaloop vimeo player work in a
nested swf? i saved a functional swf with a working video streamed from
vimeo using the posted code, and some other pieces of code from
various sites, everything working perfectly.
but when i try to load that swf in another swf, nothing happens.
been trying this with different scripts and everytime its the same.
i cant figure out what exactly prevents the player from loading this way.
does anyone have any ideas?
keeps giving this error: *** Security Sandbox Violation ***
SecurityDomain ‘http://bitcast.vimeo.com/vimeo/swf/moogaloop.swf?clip_id=10028993&server=vimeo.com&width=650&height=486&show_title=0&show_byline=0&show_portrait=0&color=ffffff&fullscreen=1’ tried to access incompatible context ‘file:///D|/Download/vimeo/test.swf’
solved…for anyone having that particular problem,
adding a Security.allowDomain(“your swf or bitcast.vimeo.com”); solves the sandbox problem.
Hi dear Readers,
@Dave A is right this forum post http://vimeo.com/forums/topic:21967 figures out why my example and my classes are not working in the moment!! You have to change the Sercurity.loadPolicy() function, the Security.allowDomain() URL and the loadURL Path at the Constructor Function of my VimeoPlayer class:
http://code.google.com/p/derhess/source/browse/trunk/AS3/de/derhess/video/vimeo/VimeoPlayer.as
Unfortunately, I have to say that I am not very happy with the update process of the moogaloop API. It seems that the vimeo staff is working on a new version of their API without any notification… I am going to update my classes if a real long term solution of the moogaloop API is available! Sorry, but at the moment I have no time to deal with these short changing intervals…
Is the source file corrupted? When I download the .zip and try to open the .fla (in CS3) I get “Unexpected file format”
I tested it and it worked for me. Has someone else the same problems? I moved the server last month, but it should work normally?!
nice!
how can i make loop the video between 2 points? please let me know.
thanks!
Hi Tom,
what do you mean between two points? Between two time points?! you can use the function vimeo_seekTo(time:int):void and jump to a certain time point in the video. Afterwards you check the status event object. It contains a property currentTime. You should use this property for checking the time and after reaching the second time point, jump back to the first time point via vimeo_seekTo().
Happy coding!
These classes work wonderfully! Thanks so much! Hopefully Vimeo institutes an API notification policy so your life gets easier. Thanks again!
-joeshock
Hello,
Thank you for the component, it’s exactly what i needed. I’m new to flex and I would like to include this component into my project. The problem i have is positioning and styling to go along with my flash catalyst project. I would greatly appreciate if you can point me in the right direction.
-D.Lee
Hey Derrick,
Unfortunately I have no clue about Flash Catalyst. I don’t know exactly what your problem is. Can you describe more accurate what happens in Flash Catalyst. Usually, the positioning of the component should work without any problems. The only thing which is really buggy and shitty is the Full Screen Mode.
Flo
http://www.derhess.de
The vimeo Moogaloop API changed several months ago. Please check their new documentation:
http://api.vimeo.com/api/docs/player
http://api.vimeo.com/api/docs/moogaloop-as
Happy coding!
So you have stopped working on this..?
the example seems to have stopped working when i first got here.
The moogaloop player works fine for me (probably updated since you wrote this)
the only problem i have with it is that it supplies the player controls as well and i can’t make my own. also now the fullscreen button works.. except not as it should. it makes my browser window go fullscreen but not the video..
and there’s no event to listen to , to know when that button is clicked , or i could just set the size of the player when that happened.
I’m embedding several videos in the stage so i can’t just listen for FullScreenEvent.FULSCREEN
I would really appreciate any kind of input…
Hi, i’ve discovered your player and works great but i have a problem. I was using AS2 and now I have to deal with As3 and i’m not a programmer. After many readings i’ve learn that the levels as used in As2 has gone and that we cannot replace a swf movie with another. So i’m suing these lines to load the player in another movie:
var loader:Loader = new Loader();
loader.load(new URLRequest(“vimeo_player.swf”));
addChild(loader);
var loader1:Loader = new Loader();
loader1.load(new URLRequest(“test1.swf”));
addChild(loader1);
And gives me “Sandbox error”. When I run the video_player.swf, the video loads fine without that error but, when trying to load in another movies, sandbox appears
Question is that i don’t know the way, as we do in As2, to replace the leven o and I need to load the player called from a button.
Thanks for help
Hi Jauanjo,
this problem is related to the Cross Domain Policy. The vimeo Player SWF is located on a server with a different domain name than you have. This causes the sandbox error. More information is available here:
http://help.adobe.com/en_US/AS2LCR/Flash_10.0/help.html?content=00000469.html
By the way, I am very suprised that my code stills works after such long time.
All the best,
Flo