Skip to Navigation | Skip to Content



YuTuplr - Getting Started. | May 28th, 2009

Lately in my spare time I have been quietly plugging away at building a simple YouTube uploader application in Air.  Nitobi encourages us to spend part of our time on our own pet projects, as well as community interaction and contributing to open source initiatives.  I have been working on this application ( YuTuplr - as in a short form of YouTube Uploader ) primarily by myself, so it has forced me to reach outside my comfort zone, and do some things that I usually take for granted.  I have approached this project as if it were a stand-alone product, so it has it’s own logo, branding, domain, and website.  All of my work, with the exception of some developer keys and fonts is open source and is available on google code.

I am posting the following as sort of a quick start guide for anyone who wants to add YouTube upload functionality to their own Air apps, or just learn some AS3. Â For the complete picture, please download and study the YuTuplr source.

The application is seperated into 2 seperate flex projects.

The AirYouTubeUploaderLib is a Flex/Air library project that contains all of the functionality related to YouTube.  The goal was to hide the low level stuff, and allow API users to build client application without the greasy YouTube API details.

YuTuplr is a somewhat full-blown example of a client, and can be used as a guide for building your own clients.  YuTuplr’s source code is in the project AirYouTubeUploaderSampleApp and contains a reference to the AirYouTubeUploaderLib project.

The YouTubeService class is the main point of interaction with your code.

To get started using the service, simply create an instance, and give it your YouTube developer credentials. You will need to get your credentials from YouTube.


import com.nitobi.webapis.youtube.YouTubeService;
ytService = new YouTubeService();
ytService.setCredentials(clientID,devKey);

Authentication

You can look at ytService.isAuthenticated to see if you are already logged in, and currentUserName to get the current user’s name.

To login, simply call :
ytService.login(userName:String,password:String,rememberMe:Boolean = true):void

If the rememberMe flag is true, the YouTubeService will store the username/password in a LocalSharedObject.

To retrieve the previously stored values, YouTubeService has public getters :Â
storedUsername():StringÂ
storedPassword():String

Both getters will return “” if the last login did not set rememberMe to true.

YuTuplr uses this information when it initializes the login window like the following:

usernameInput.text = ytService.storedUsername;
passwordInput.text = ytService.storedPassword;
cbRememberMe.selected = usernameInput.text.length > 0;

The service will dispatch the following YouTubeEvent(s) related to login:

YouTubeEvent.YT_LOGIN_STARTÂ - the service is attempting to log in, use this to display a spinner or disable a log in button

YouTubeEvent.YT_LOGIN_SUCCESSÂ - all systems go! The user has been authenticated.

YouTubeEvent.YT_LOGIN_ERRORÂ - there was an error logging in, bad username or password.

Getting the user’s Uploads

The service exposes several bindable ArrayCollections for data storage.

YouTubeService.userUploads - a collection of UserUpload objects, all in various states.  Some may be completed, but still in the list, others may be pending or failed.

Upload status is statically defined by the UserUpload class

UserUpload.STATUS_UPLOADINGÂ - the file is currently being uploaded

UserUpload.STATUS_COMPLETEDÂ - the upload has completed

UserUpload.STATUS_ERRORÂ - the upload failed

UserUpload.STATUS_QUEUEDÂ - file is in queue, and will be uploaded according to it’s order in the queue

UserUpload.STATUS_PENDINGÂ - this upload is being edited (meta) and should not be uploaded yet

- set the status to STATUS_PENDING to prevent the uploader from trying to upload a file while the user is editing the details.

In order to add to YouTubeService.userUploads, simply call YouTubeService’s addFile method passing it a file object.  If the file object is a directory, the service will locate all supported video files (by extension) within it and add them to the list.

public function addFile(file:File):Boolean;
public function addFiles(fileList:Array):Boolean;

The service also provides methods for cleaning up the list:

To remove all uploads that have a status of complete:

public function clearCompletedUploads():void

To retry all failed uploads:Â
public function retryFailedUploads():void

- Behind the scenes, this resets status to UserUpload.STATUS_QUEUED and they will be uploaded according to their order in the queue.

To remove failed uploads:
public function removeFailedUploads():void

To remove an individual UserUpload from the queue:
public function removeFileFromQueue(upld:UserUpload):void

Â
A key goal in the design of the architecture was to support binding throughout.

You can safely bind a list control to the UserVideos collection, and when updates are received from YouTube the same object instances are updated with the new values.  This makes the service pretty easy to interact with, as binding does most of the work.

YouTubeService.userVideos

The userVideos ArrayCollection is a list of all the users previously uploaded videos. Each item in the list is of type :UserVideo

UserVideo have the following properties:

id:String; // the unique id assigned by YouTube
thumbnail1:String;// URLs to video images.
// Note: the thumbnails are null until YouTube has processed the movie
thumbnail2:String;
thumbnail3:String;
durationSeconds:int;
viewCount:int;
commentsCount:int;
published:Date;
updated:Date;
status:String; // UserVideo. ( STATUS_PROCESSING | STATUS_ACTIVE | STATUS_REJECTED )
reason:String; // ie. Duplicate video ( this is only available if status == STATUS_REJECTED )
description:String;
keywords:String;
rating:Number = 0;

The UserVideo also has a getter for formatted duration, which returns a formatted time string MM:SS
get formattedDuration():String

YouTube events dispatched by the service

Your application will want to subscribe to events to know what is happening with the service.

YouTubeEvent statically defines all the events that the service will dispatch.

YouTubeEvent.YT_LOGIN_STARTÂ - the service is attempting to log in, use this to display a spinner or disable a log in button

YouTubeEvent.YT_LOGIN_SUCCESSÂ - all systems go!

YouTubeEvent.YT_LOGIN_ERRORÂ - there was an error logging in, bad username or password

YouTubeEvent.YT_GOT_USER_VIDEOSÂ - the authenticated user’s videos have been retrieved from YouTube

YouTubeEvent.YT_NO_CREDENTIALSÂ - an API call was attempted, but you have not set the developerKey and clientID.

YouTubeEvent.YT_UPLOAD_SUCCESSÂ - an upload has successfully completed

YouTubeEvent.YT_UPLOAD_ERRORÂ - there was an error uploading a file.

YouTubeEvent.YT_UPLOAD_COMPLETEÂ - an upload has completed, this is fired both on success and error conditions

YouTubeEvent.YT_UPLOAD_PROGRESSÂ - YouTubeEvent.data contains bytesLoaded and bytesTotal that you can use to bind directly to a progress bar.

YouTubeEvent.YT_PROCESSING_COUNT_CHANGE - when videos are uploaded to YouTube, they must be transcoded before they are available.  The YouTubeService keeps tracks of how many UserVideos are processing and fires this event whenever the count changes.

YouTubeEvent.YT_FILESIZE_EXCEEDEDÂ - the user has added a file that is over the YouTube defined 1 GB limit

Â

Hopefully that is enough to get you started playing with the YouTube Uploader Library. Â I welcome all comments, questions, suggestions and especially contributions if anyone wants to jump in and help push the app to the next level.

Jesse

Posted in Adobe Air, Air, Flex | 9 Comments » | Add to Delicious | Digg It

This entry was posted on Thursday, May 28th, 2009 at 10:32 am and is filed under Adobe Air, Air, Flex. You can follow any responses to this entry through the RSS 2.0 feed. You can leave a response, or trackback from your own site.

9 Responses to “YuTuplr - Getting Started.”

  1. chris dennett Says:

    Hello,

    This looks excellent - just what I’ve been looking for. I’m currently working a small AIR app allowing kids to make short films with their webcam. Uploading to youtube would be a great addition.

    I’m not a particularly good coder so even though you’ve done all the work I know it’ll take me ages to figure it all out. So before I roll up my sleeves and get stuck in I wondered if you could let me know if the actionscript you’ve used contains anything unique to Flex? I’m working just with Flash you see.

    Cheers

    Chris

  2. Jesse Says:

    Unfortunately the functionality is not available from Flash. This would be a cross-domain violation and would be prevented by the security sandbox in flash player.

    You could implement it on the server though, as the API was designed for, although this doesn’t seemed to meet your ‘just with flash’ requirement.

  3. Marc Says:

    Hi, thank you for this nice tool and the source!

    Right now I am trying to build my own upload tool but I fail when I try to upload a video.

    My code is very simple: I create an YouTubeService instance, pass credentials, login (successfuly) and then call ytService.addFile(myFile). Before that, I add EventListeners for Error, Success and Complete to the YouTubeService instance. But none of my listener functions is called. I only get HTTP code 200 (request succeeded) in the console.

    Does the upload begin automatically after addFile()? Or do I have to call another function?

    Thanks a lot,
    Marc

  4. Marc Says:

    Hi, I wrote a comment yesterday, but it doesn’t appear. Maybe it just got lost, but if it is still in moderation, I apologize for the double post :)
    I have a problem with my instance of YouTubeService. I set the credentials, I can login, but when I try to upload a file, nothing happens, not even a “complete” or “error” event gets fired.
    Do I have to do something else besides “myYouTubeServiceInstance.addFile(myFile)”? I thought after adding a file the upload would start automatically.

    Thanks a lot!
    Marc

  5. Jesse Says:

    Marc, you need to call myYouTubeServiceInstance.startUploading();

    This allows the upload queue to be started and stopped.

    If you have already called startUploading, and the there are files being uploaded already, you do not have to call it again, any new files added will be uploaded when the queue gets to them.

    You can also look at the public bindable var isUploading:Boolean ( on myYouTubeServiceInstance ) to see the current state of the uploader.

    The sample app I made allows the user to start and stop uploads, but if you want you can override this behavior by calling myYouTubeServiceInstance.startUploading();

    Hope this helps! Glad to see people using my code!!

  6. Marc Says:

    Hi Jesse,

    I was on vacation in the meantime, thus I’m responding a bit late.
    It works now, silly me! Thanks again for your neat code and the work you put into it.

    All the best,
    Marc

  7. Marc Says:

    Hi Jesse,

    I am sorry to bother you again, but I came across a problem that I just can not solve:

    I have a menu with a browse button. The button opens an “browse for file” dialog and creates a new File-instance “myFile” (a private var) which I add an “Event.Select” listener to.
    Then I have an upload button which calls myYouTubeServiceInstance.addFile(myFile) and myYouTubeServiceInstance.startUploading();
    The upload starts but doesnt progress.

    The weird thing is that when I start the upload directly in my listener function “onFileSelected(event:Event)”, it works.

    Do you have a clue what the problem could be?

    Thanks a million!

  8. Ram Says:

    Hi Jesse,

    I was using your code for the authentication part.I created an instance of YouTubeService and i call the login function when the user clicks on the login button.

    I tried to get the authToken, but it returns null,i did a trace and i got the same(null).

    But you have written the code for fetching authToken….but for some reason it does not show up…could you please help with that??

  9. Tai Tran Says:

    Hi,
    I have just downloaded your source code. When I make change, Flex/Flash builder can not compile your air application. It is said about the Java heap error in compiling. Could you help me or provide me any new updates about your cool application.

    Thanks.

Leave a Reply