Archive by Author

Tech Tuesday: Posting to TwitPic from Adobe AIR

TwitPic is a service that lets you share photos on Twitter by generating a tiny url to the image being uploaded. The flash.filesystem.File class allows Adobe AIR to post an image to TwitPic. By specifying the username, password and posting method it is possible to submit a query to the TwitPic API.

Actionscript:
  1. package com.cb.twitpic
  2. {
  3.       import flash.events.DataEvent;
  4.       import flash.events.Event;
  5.       import flash.filesystem.File;
  6.       import flash.net.FileFilter;
  7.       import flash.net.URLRequest;
  8.       import flash.net.URLRequestMethod;
  9.       import flash.net.URLVariables;
  10.    
  11.       public class TwitPic
  12.       {
  13.          private var _file:File;     
  14.          
  15.          public function TwitPic()
  16.           {
  17.              _file = new File();
  18.              _file.addEventListener(DataEvent.UPLOAD_COMPLETE_DATA,uploadCompleteDataHandler);
  19.              browse();
  20.           }
  21.           private function browse():void {
  22.             _file.addEventListener(Event.SELECT, fileSelected);
  23.             _file.browse( new Array( new FileFilter( "Images (*.jpg, *.jpeg, *.gif, *.png)", "*.jpg;*.jpeg;*.gif;*.png" ) ) );
  24.           }
  25.            
  26.           private function fileSelected(event:Event):void {
  27.                var urlRequest:URLRequest = new URLRequest("http://twitpic.com/api/upload");
  28.              
  29.                // The API requires the request be sent via POST
  30.                urlRequest.method = URLRequestMethod.POST;
  31.                    
  32.                // Enter a valid Twitter username / password combination
  33.                var urlVars:URLVariables = new URLVariables();
  34.                urlVars.username = TWITTER_USERNAME;
  35.                urlVars.password = TWITTER_PASSWORD;
  36.                urlRequest.data = urlVars;
  37.                    
  38.                // The API requires the file be labeled as 'media'
  39.                _file.upload(urlRequest, 'media');
  40.           }
  41.  
  42.           private function uploadCompleteDataHandler(event:DataEvent):void
  43.          {
  44.                var resultXML:XML = new XML(event.text);
  45.                  
  46.                // Trace the path to the resulting image tiny url (mediaurl)
  47.                trace(resultXML.child("mediaurl")[0]);
  48.          }
  49.     }
  50. }

This can be used within an AIR application by importing TwitPic and initializing the class. An example can be supplied upon request.

This was originally posted on blackcj.com, Chris Black's personal blog. Chris is a Senior Developer at Sierra Bravo.

Filed under Technology

Tech Tuesday: Resources for integrating SQLite in AIR

When doing research on integrating a SQLite Database into AIR I came across the following useful resources:
Learn what SQLite is About:
Introduction to the SQLite Database - David Tucker

Getting Started:
Introduction to SQLite in Adobe AIR

Tool for Creating and Modifying SQLite Databases:
SQLite Firefox Extension

By using a SQLite database it will be easy to filter data returned by services based on tags. A demo application that uses SQLite will be coming soon. Feel free to comment with any additional resources or cool demo applications that use SQLite.

This was originally posted on blackcj.com, Chris Black's personal blog. Chris is a Senior Developer at Sierra Bravo.

Filed under Technology

Tech Tuesday — YouTube in AIR

The YouTube video player is currently written in ActionScript 2.0 and integrating it into an AIR application requires a few additional steps. There are many solutions available that reverse engineer the URL to get access to the source video FLV, however, this breaks the terms of service and is not officially supported by YouTube or the API.

By taking advantage of the HTMLLoader class we are able to load the YouTube Chromeless video player into AIR without breaking the terms of service. It essentially loads up a web page within the AIR application and uses JavaScript to control the video.

Lets start by creating the JavaScript / HTML portion of the application that the HTMLLoader will consume. Resources for this can be found here; YouTube Chromeless Player Example page.

Simplified JavaScript functions for this example (includes Play, Pause and Load):

JavaScript:
  1. <script src="js/swfobject.js" type="text/javascript" />
  2. <script type="text/javascript">
  3.  
  4.       function onYouTubePlayerReady(playerId) {
  5.         ytplayer = document.getElementById("myytplayer");
  6.       }
  7.    
  8.       // functions for the api calls
  9.       function loadNewVideo(id, startSeconds) {
  10.        if (ytplayer) {
  11.          ytplayer.loadVideoById(id, startSeconds);
  12.         }
  13.        }
  14.      
  15.        function play() {
  16.           if (ytplayer) {
  17.             ytplayer.playVideo();
  18.           }
  19.         }
  20.  
  21.        function pause() {
  22.          if (ytplayer) {
  23.            ytplayer.pauseVideo();
  24.          }
  25.         }
  26.  
  27.   </script>

Next we will use the SWFObject to load in the YouTube Chromeless video player. Notice the use of wmode: "opaque" in this example. Without this you will not be able to place any display objects above your videos.

JavaScript:
  1. <script type="text/javascript">
  2.  
  3.        // allowScriptAccess must be set to allow the Javascript from one
  4.        // domain to access the swf on the youtube domain
  5.        var params = { allowScriptAccess: "always", bgcolor: "#cccccc", wmode: "opaque" };
  6.        // this sets the id of the object or embed tag to 'myytplayer'.
  7.        // You then use this id to access the swf and make calls to the player's API
  8.        var atts = { id: "myytplayer" };
  9.        swfobject.embedSWF("http://www.youtube.com/apiplayer?enablejsapi=1&playerapiid=ytplayer",
  10.                            "ytapiplayer", "400", "300", "8", null, null, params, atts);
  11.  
  12. </script>

ActionScript Used to Load and Control the Video:

Actionscript:
  1. package com.sb.util
  2. {
  3.    import flash.display.Sprite;
  4.    import flash.events.Event;
  5.    import flash.html.HTMLLoader;
  6.    import flash.net.URLRequest;
  7.          
  8.    public class JSVideoPlayer extends Sprite
  9.    {
  10.  
  11.          private var _html:HTMLLoader;
  12.          private var _ready:Boolean = false;         
  13.        
  14.          public function JSVideoPlayer()
  15.            {
  16.              _html = new HTMLLoader();
  17.              _html.paintsDefaultBackground = false;
  18.              _html.width = 400;
  19.              _html.height = 300;
  20.              _html.addEventListener(Event.COMPLETE,
  21.                                     onComplete);
  22.                
  23.              loadHTMLcontent() 
  24.  
  25.              this.addChild( _html );
  26.          }
  27.          public function loadNewVideo(videoID:String):void
  28.          {
  29.               if(_ready){
  30.                  _html.window.loadNewVideo(videoID);
  31.               }
  32.          }
  33.          
  34.          public function playVideo():void
  35.          {
  36.                if(_ready){
  37.                   _html.window.play();
  38.                }
  39.          }
  40.    
  41.          public function pauseVideo():void
  42.         {
  43.              if(_ready){
  44.                 _html.window.pause();
  45.              }
  46.         }
  47.            
  48.         private function onComplete (e:Event):void
  49.         {
  50.              _ready = true;
  51.         }
  52.              
  53.         public function loadHTMLcontent():void
  54.         {
  55.              _html.load(new URLRequest('test.html'));
  56.         }
  57.  
  58.    }
  59. }

One of the limitations of using the HTMLLoader class is the inability to set the opacity of the video. For example you if wanted to fade the video out you would have to capture the current state of the video and replace it with a bitmap image that would then be faded out (download the zip file to see an example of this).

Source Files (ZIP)

Sources

PS: This example is only for AIR and may not work for Flex applications deployed on websites. Please visit 'YouTube in Flex applications' (On The Other Hand) for an example of how to do this in Flex.

This was originally posted on blackcj.com, Chris Black's personal blog. Chris is a Senior Developer at Sierra Bravo.

Filed under Technology

Tech Tuesday: FlexFeed — Twitter RSS Feeds in Flex

[a note from Jodi: This is the inaugural Tech Tuesday post, which is going to be a regular feature where our nerds wow you with their technical prowess. First up, we have Chris Black, who does amazing things with Flex and ActionScript]

Using Flex and PHP it is possible to integrate Twitter RSS feeds into a Flex web page. Twitters cross domain policy (which is used by Flash) does not allow external resources to access feeds. Using PHP as a medium to the data, Flex can access the feed and display all contents. This technique can be used to access any xml data that Flex may not have access to.

Let's start by creating an HTTPService:

HTML:
  1. <mx:HTTPService
  2.         id="rssParse"
  3.         url="http://twitter.com/statuses/user_timeline/16584421.rss"
  4.         result="processResult(event)"
  5.         resultFormat="e4x" />

Next we will create the function to process the results:

Actionscript:
  1. import mx.collections.ArrayCollection;
  2. import mx.rpc.events.ResultEvent;
  3.              
  4. [Bindable]
  5. private var _rssResults:ArrayCollection;
  6.            
  7.  // Define and use atom namespace.
  8. private namespace atom = "http://www.w3.org/2005/Atom";
  9. use namespace atom;
  10.            
  11. private function processResult(event:ResultEvent):void
  12. {
  13. var xmlList:XMLList = event.result.channel.item as XMLList;
  14. for each(var item:XML in xmlList){
  15. var myDate:String = item.pubDate;
  16. myDate = myDate.slice(0,22);
  17.  _rssResults.addItem({title: item.title, date: myDate});
  18. }
  19. }
  20.            
  21. private function init():void
  22. {
  23. _rssResults = new ArrayCollection();
  24. rssParse.send();
  25. }

Now lets add the mxml to display the content:

HTML:
  1. <mx:VBox width="400" height="600" horizontalAlign="center">   
  2.     <mx:Label styleName="subTitleText" text="Twitter Feed:" fontWeight="bold" fontSize="16"/>
  3.     <mx:VBox height="500" width="400" verticalScrollPolicy="auto" horizontalScrollPolicy="off" horizontalAlign="center">
  4.         <mx:Repeater id="twitter" dataProvider="{_rssResults}">
  5.             <mx:Text textAlign="center" width="300" text="{twitter.currentItem.date}"/>
  6.             <mx:Text textAlign="center" width="300" text="{twitter.currentItem.title}"/>
  7.         </mx:Repeater>           
  8.     </mx:VBox>   
  9. </mx:VBox>

After testing the application locally everything works great! But wait... what about the PHP code? Well first export a release build of the application and upload it to a web server for testing.

Here is the error that you should receive:
[RPC Fault faultString="Security error accessing url" faultCode="Channel.Security.Error" faultDetail="Destination: DefaultHTTP"]

To get around this let's create a php file that collects the twitter data:

PHP:
  1. $twitter_feed = 'http://twitter.com/statuses/user_timeline/16584421.rss';
  2. $rawfeed = @file_get_contents($twitter_feed);
  3. print $rawfeed;

Now we need to update our HTTPService request to pull from the new php file:

HTML:
  1. <mx:HTTPService
  2.    id="rssParse"
  3.    url="php/twitter.php"
  4.    result="processResult(event)"
  5.    resultFormat="e4x" />

Now everything works great!

Check out this link to view a functional example.
And the source files.

Please leave a comment if you have any questions, comments, or suggestions. Thanks!

This was originally posted on blackcj.com, Chris Black's personal blog. Chris is a Senior Developer at Sierra Bravo.

Filed under Technology