Wednesday, December 16, 2009

Making sense out of MVC in Flex

Now that the video project is nearly out of the way, I'm anxious to get back more to Flex and to do this MVC is a top priority. Looking around the web there are a lot of tutorials but most focus on using frameworks like Cairngorm and PureMVC and very light info on the concepts of MVC and how they are implemented in AS3. Fortunately I stumbled upon this one--from the writers of an OReilly book on the subject -- and it's so good I'm thinking about buying the book:

http://www.as3dp.com/category/design-patterns/mvc/

Tuesday, November 10, 2009

Subtitle issues in DVD Studio Pro

After a lot of experimenting, we have settled on the following subtitle settings for the NTSC and PAL versions of the DVD.

PAL: Helvetica Bold 34pt
NTSC: Arial Bold 29pt

We found that when we used Helvetica Bold for the NTSC version, the lower case "w" was a lot smaller than the other letters and looked very odd. Also the dot on the lower case "i" was not clear so it looked more like an "l".

We also liked that the top stem of the "t" was angled down a bit, making it a bit easier to read. Going back we might have used Arial for the PAL version too but we didn't have the time to test it.

For Persian text we found that the only good way of getting subtitles to look good was to do them in Photoshop -- one by one. We used a black font with a bold yellow outline, saved it as a png and imported into DVDSP. This will show up as a white letter and black outline. Make sure the outline is thick enough.

To do this for both NTSC and PAL:

1. Create the subtitle at 1024x576 (PAL 16:9). White background, black letter, yellow outline. Make sure to create guides for the title safe and keep the subtitle within this area.

2. Keep the subtitles in a separate folder and save backups--you'll use this set of subs to create the compressed NTSC and PAL subtitles.

3. Once you have all of the subs do a batch convert of them and resize them to 720x576. This will give you the PAL subtitles.

4. The do another batch conversion of the original set and resize them to 720x480. This is the required size for NTSC.

As far as our timing between the subtitles, we used a 4 frame gap -- but in retrospect we could have used 3 or 2 if necessary. It was also a happy accident that we did all of this on the PAL timeline (at 25 frames per second) and we were able to use the exact same stl file for NTSC. We didn't test this but I'm pretty sure that DVDSP would cough up an stl file for a PAL project that used the 29 frames per second timing.

Friday, October 16, 2009

Keylistener failing in Flex with creationComplete

Just a quick note. It appears that the stage does not get initialized in a Flex app until the applicationComplete event is fired (not creationComplete).

So if you have an init() function that sets up the listener like this:

private function init():void{
stage.addEventListener(KeyboardEvent.KEY_DOWN, myKeyDownHandler);
}

calling it from the application tag like this will fail:



but this will work:

AS3 writeUTF vs writeMultiByte with diacriticals, curly quotes and other special characters

I'm working on an Air app that allows a user to modify blocks of video subtitle timecodes. The user can open an stl file, splits the file into an arrayCollection and puts it into a datagrid. They can then select a block of timecodes and adjust them based on the modified start time. This will be a huge timesaver since the film we had completed required a re-edit and we have thousands of subtitles that will now need to be changed as a result.

In any event, when the work is done the user can save the file to the system. In the save process, I naturally used the writeUTF() method but found that although it's supposed to save using utf-8 encoding, things like diacritics, question marks, curly apostrophes and quotes were broken in the resulting file.

So what should have looked like this: “This is a quote”
Looked like this: “This was a quoteâ€o

However, if you use the writeMultiByte() method and set the encoding to utf-8 it works perfectly.

So instead of : fileStream.writeUTF(myText);
try: fileStream.writeMultiByte(myText,"utf-8");

Since Google came up empty for search for the answer to this problem I though I would post this. Maybe it will help someone else....

Wednesday, October 14, 2009

Great replaceAll in AS3

Simple and powerful. Found at:

http://snipplr.com/view/10998/replace-all/


var theContent:String = "Test String with lots of t's"
trace(replace(theContent, "t", "z"));

function replace(str:String, fnd:String, rpl:String):String{
return str.split(fnd).join(rpl);
}

Monday, September 28, 2009

"This PNG contains additional data for Adobe Fireworks, which will be discarded upon save."

This prompt appeared when I had modified a number of files with Fireworks and then tried to execute a batch command in Photoshop on the files:

"This PNG contains additional data for Adobe Fireworks, which will be discarded upon save."

And although I clicked ok for the first file, it appeared again for each one--rendering the batch process useless. I couldn't find a solution in Google, so it seems that the only logical way to solve the problem was to run the batch using a Fireworks command instead. And it is just as easy to create a "command" in FW than an "action" in PS:

1. Open a file in Fireworks
2. Open the History dialog box
3. Make sure the History list is clear
4. Go through whatever steps you wantto modify the image as needed
5. In the History panel, highlight the steps that you want to set as the command
6. In the History options drop down select "Save as Command"
7. Give your command a descriptive name
8. Select File>Batch Process
9. Select the files you want to run the command against
10. In the next step (Batch Process dialog) open the Commands list and select the command you made.
11. Run it
12. Done!

Sunday, September 27, 2009

NDF and DF problems in converting subtitles for use in Final Cut Pro and DVD Studio Pro

It has proven to be extremely complicated to do subtitles for this project using DVD Studio Pro and Final Cut Pro. The latest wrinkle was to export the STL file back into Final Cut pro using Subbits. The program works well--but is not well documented so a lot comes down to trial and error.

The subtitles STL file we created for DVD Studio pro worked out fine but when we took the exact same file and converted it to XML using Subbits, the subtitles slowly got out of synch as the film advanced. The solution required us to adjust the STL in Subbits using the "Recalculate NDF to DF" option (a completely undocumented feature in the Subbits manual). On top of that when you choose the option it prompts you with the alert: "This will shift all timecodes down from 30fps to 29.97 fps. Are you sure you want to continue?" but since we are using PAL this makes no sense.

However, chosing this option -- despite the erroneous warning -- solved the out of synch issue with FCP.

** Update: It appears that this solution only fixed one out of the 4 subtitle STLs that we were working with. The others simply needed to have the Subbits settings for the project set to PAL instead of NTSC. (Clcik Edit>Preferences>PAL). Don't have the time to figure out why the two STLs needed to be processed differently--could have been a FCP setting instead. All in all though I still say Subbits is the best -- and lowest cost -- solution to the problem. I hope Apple will just create a more logical work flow to work with subtitles in FCP and DVD Studio Pro in their next version!

Sunday, September 20, 2009

Use Nero to make an ISO image

We have a DVD that we are creating and want to make an ISO image of it that can be downloaded over the internet. However, Nero Essentials doesn't make it very clear how to do it (I suppose to limit piracy). However a thread at this forum <http://forum.my.nero.com/index.php?showtopic=658> gave instructions on how to do it which I've modified below to cover Nero 7 Essentials (this version has a different interface than the one in the forum post) :

1. Open Nero Express Essentials
2. Click the arrow button on the far left of the Nero window to expose the Advanced panel (I had never noticed this arrow button before)
3. Place your DVD in the DVD player
4. Select "Copy Audio CD Tracks"
5. It will list the DVD track as a single track with a start, length, mode listing and the "Total" field will indicate something like: "1 Track, 343:25:23(3019 MB)"
6. Change the Output file format to "ISO image file (*.iso)
7. Set the name and path where you want the .iso to save
8. Click "Go"

Thursday, September 17, 2009

Importing stl files into Final Cut Pro and DVD Studio Pro

Surprisingly, the workflow to import subtitles into DVD Studio Pro and Final Cut Pro are entirely different. After all, the programs are both from Apple so you would think that they would work well together.

In any event, we made hundreds of subtitles in .stl format -- because this is the preferred method to import subtitles into DVD Studio Pro. But Final Cut Pro requires an xml format for importing subtitles -- and DVD Studio Pro does not allow you to export their subtitles out!

So we had to find a way to convert the stl into the xml format for Final Cut Pro. Thank goodness for Subbits:

http://www.videotoolshed.com/?page=products&pID=12

For $200 it allows you to open various subtitle formats and then export them into other formats -- including Final Cut Pro, Avid and more -- including the xml format required for flash video subtitling. It's also a decent subtitler on its own. Great solution.
(Disclaimer--I am in no way related to the creator of Subbits -- as proven by the bugs listed below)

You can also use TitleExchange for conversions:

http://www.spherico.com/filmtools/TitleExchange/index.html


...and it even lets you convert 50 subtitles at a time for free. This can save you buying it for small projects, but can be very time consuming if you are in a large project and have iterations. TitleExchange is also a converter only--whereas Subbits includes a full featured subtitler.

A few more things (bugs) about Subbits. You'll find that it allows you to open files with other character sets--such as Persian-- but you can't view or edit the text in the interface --since the characters show up as rectangles. But it still does the conversion properly.

The Mac version also seemed a bit more buggy than the one for PC:

1. It converted diacriticals into HTML encoded entities.
2. It took the comma that separated the end time from the subtitle -- in the stl file -- and made it the first character in the subtitle. So all of the subtitles looked like this: ", We thought it would be best to..."

So make sure to test the free demo thoroughly before you buy it. I decided to buy the PC version since it seemed to read the stl files better than the Mac version.

Subtitling issues using stl files and DVD Studio Pro

We are working on a film project and are now in the process of doing the DVD authoring in DVD Studio Pro 4. There are a lot of subtitles so we decided to create an stl file using a spreadsheet. The structure is as follows:

Column 1: Start time <00:00:00:00>
Column 2: comma <,>
Column 3: End time <00:00:00:00>
Column 4: comma <,>
Column 5: Subtitle text

Once we are done with the file we copy and paste it into notepad and then save it as as .stl file using UTF-8 encoding.

Things generally have worked well with this process aside from one quite significant issue: If the subtitle starts with certain special characters -- in English this includes a quotation mark -- the character does not import into DVD Studio Pro -- it just disappears. In the case of Persian, the first character of every subtitle -- no matter what it was -- would not be imported.

Fortunately the fix is simple. Just make sure to add a space at the beginning of a subtitle that starts with an offending character. This seems to fool the importer into allowing the character to import.

Sunday, September 13, 2009

After effects video tutorials

Here is a GREAT site to learn After Effects!:

http://www.videocopilot.net/

Saturday, August 29, 2009

How to lock a layer in After Effects and still be able to edit it

I have been working with After Effects to modify a film clip that needed an animated mask to hide part of the image. However, every once in a while I would select the layer by accident and move it--which if you don't catch your mistake immediately, messes up your entire animation. Anyway, a bit of Googling and I found this brilliant (and simple solution here):

http://generalspecialist.com/2008/03/locking-after-effects-layers-so-they.asp

The short version is to select the layer in question, open the expressions panel for the "position" property and place the current position of the layer in brackets like this [123,23]. This simple script resets the position of the layer back to the original every time you mistakenly move it. BRILLIANT!

Saturday, August 15, 2009

inDesign pixelated photos while printing

I am working on an InDesign project that uses a lot of image. I kept having a problem where the images would look fine on screen but when I printed the file some of the photos were pixelated (but not all of them).

Fortunately I found a forum post with the answer:

Choose Print>Settings>Graphics
and then under Images set "Send Data" to "All"

Wednesday, June 17, 2009

Create MOV from Flash freezes - SOLUTION

I was trying to create a MOV file from Flash CS4 and the progress bar filled up and froze while doing "Recording Flash Content". Thanks to this post http://www.kirupa.com/forum/showthread.php?t=275007 it turns out that I had additional keyframes after a stop() action and had chosen to export until the end of the timeline was reached.

But since the stop action occurred before the end of the timeline was reached then of course it froze. There are two workaround. One is to remove the stop() action or just set the timeframe that you want to stop exporting. So in this case I just set to to only export 2 minutes.

Brilliant.. thanks Kirupa forum!

Monday, March 9, 2009

Saving filesize in a Flex app

I'm starting to use modules to try and get the filesize down in Baha'i Explorer. This has helped bring the initial load down from 380kb to 280kb. Although the separate modules add up to more than the original size, it does make it a quicker to load initially. Two other things to keep in mind to keep the file sie down are these compiler options:

-optimize=true;

If set to true, it enables the ActionScript optimizer. This optimizer reduces file size and increases performance by optimizing the SWF file's bytecode. The default value is false.

In my case setting it to true saved 50kb

Also, make sure to set the debug option to false when you are deploying :

-debug=false

This can save nearly 100kb.

For additional compiler options: click here >

Sunday, February 22, 2009

How to set focus on a Flex app (and how to reset it after losing it)

If you are running a Flex app and click on another app, you'll lose focus from the Flex app. In most programs in order to regain focus you just reclick the app and off you go. However Flash does not regain focus automatically unless the user clicks on some element that has an onClick event listener set up for it. This can be a problem especially if you have an app that is supposed to run using keyboard controls only (like a slideshow).

In order to regain focus, make sure that your main component on the stage -- like the canvas that holds your app -- has a click listener set up like this:

click="enableKeyListener(event)"

and then you can have a function that is called like this:

public function enableKeyListener(evt:Event):void{
application.addEventListener(KeyboardEvent.KEY_DOWN,keyUpListener);
world.setFocus();
}

You'll note that the enableKeyListener function is called by the application on creationComplete and explicity calls setFocus() on an element that exists on the stage. And it needs to do this again if you want to regain focus. AFAIK there is no setFocus() method in the stage object so you need to choose an element that is on the stage instead.

Saturday, February 21, 2009

Turn off labels on a Flex chart

If you don't want the labels along the side and bottom of a chart in Flex to show, set the "showLabels" property of the axis renderer to false like this:

<mx:horizontalAxisRenderer>

<mx:AxisRenderer showLabels="false"/>

</mx:horizontalAxisRenderer>

<mx:verticalAxisRenderer>

<mx:AxisRenderer showLabels="false"/>

</mx:verticalAxisRenderer>

Wednesday, February 18, 2009

Creating full screen Flex apps

I'm not sure why Adobe doesn't just add this as an option to FlexBuilder but in order to allow your Flex app to go fullscreen you need to follow these steps:

1. Go here to download html templates for fullscreen support: http://www.adobe.com/devnet/flashplayer/articles/full_screen_mode.html
2. Delete all of the files in the html-template folder in your Flex project and place the contents of either the "full-screen-support-with-history" or "full-screen-support" folders from the zip file
3. Add this to the application tag in your Flex project: preinitialize="systemManager.stage.scaleMode = 'showAll'"
4. Call this when you want the app to go fullscreen: systemManager.stage.displayState = StageDisplayState.FULL_SCREEN;

Tuesday, February 17, 2009

Embedding an swf into Flex will remove all of the timeline code

It appears that if you try to load an swf file into Flex using the SWFLoader you can access functions and variables inside the swf from Flex by using this syntax: mySWFLoader.content.myvariable.

However if you use the embed directive in the SWFLoader, all timeline code is lost, meaning that you can't access functions, use gotoAndStop(), etc...

Sunday, February 1, 2009

RSL error 1 of 1 / error #2048 and Vista

A user reported a problem using a Facebook Flex app that uses Runtime Shared Libraries. On Vista/IE they tried to load the app and got this error : RSL error 1 of 1 / Error #2048

In Googling the error, most everyone said that the server needs a cross domain file -- but that is in place and I'm not able to replicate the issue in WinXP(Firefox and IE) or Mac(Firefox).

One forum (http://www.adobeforums.com/webx/.59b6ed13) indicated that a MIME type was needed for the .swz file so I put this in the .htaccess file: AddType application/x-swz .swz

But that didn't fix it either.

Finally I was looking at the date stamp for the framework_3.0.0.477.swf and framework_3.0.0.477.swz files and found that the ones on the server were older than the ones in the bin-debug directory of Flex (the server ones were 4 months while the latest ones were 2 months old). Anyway, I pushed the newer ones to the server and the app loaded perfectly.

Odd that this would only appear with Vista/IE. I was not able to test it with Vista/Firefox...

Saturday, January 31, 2009

Using the Share-button to post multimedia (audio, video and flash) in FBML

I have been frustrated in trying to find out how to add multimedia using the share button. The FBML fb:share-button documentation (http://wiki.developers.facebook.com/index.php/Fb:share-button) provides an example of sharing video, but does not give all of the meta information that you can use if you want to share other media types -- they just link to another page which hides the info -- and it is only revealed if you click on the rather innocuous link: "How do I make sure the Share Preview works?". arghhh...

I had gone to that page numerous times and it was only in desperation I discovered it. Anyway, here is the "hidden" info:

Multimedia Tags

The ideal way for you to connect video and media files to the share link is to make the URL in the link point to an html page that contains the <meta>/<link> tags described above (title, description, image_src) along with some additional <meta>/<link> tags:

Audio (required)

<meta name="title" content="page_title">
<meta name="description" content="audio_description">
<link rel="image_src" href="audio_image_src_url">
<link rel="audio_src" href="audio_src_url">
<meta name="audio_type" content="Content-Type header field">

Audio (optional)

<meta name="audio_title" content="audio_title (eg. song name)">
<meta name="audio_artist" content="audio_artist_name">
<meta name="audio_album" content="audio_album_name">


Video* (required)

<meta name="title" content="video_title">
<meta name="description" content="video_description">
<link rel="image_src" href="video_screenshot_image_src_url">
<link rel="video_src" href="video_src_url">*
<meta name="video_height" content="video_height">
<meta name="video_width" content="video_width">
<meta name="video_type" content="Content-Type header field">

Video (example)

Here is an example Flash Video embed:

<embed src="http://www.example.com/player.swf" flashvars="video_id=123456789" type="application/x-shockwave-flash" width="300" height="200"></embed>

For that video, the appropriate metadata would look like this:

<link rel="video_src" href="http://www.example.com/player.swf?video_id=123456789">
<meta name="video_height" content="200">
<meta name="video_width" content="300">
<meta name="video_type" content="application/x-shockwave-flash"><meta name="video_type" content="application/x-shockwave-flash">

Friday, January 30, 2009

Beware of Facebook documentation and blogs

After working on a Facebook app for some time now I have finally come to the conclusion that you can't trust either the documentation or blog posts on how to make something work. It appears that Facebook changes the way things work on a regular basis -- and don't document them very well -- thus breaking your code or making those easy tutorials you found from last year completely useless. Perfect case in point is how to create infinite sessions :(

Tuesday, January 27, 2009

Facebook-updating a profile box using a cron and using an "infinite session"

I have a profile box that was created for a Facebook app -- one for a narrow page (when the box appears on the left side of your profile page) and the other for the boxes tab. The box displays the most recent blog post and a randomly selected video -- so it needs to be updated every day. The content is the same for everyone so there was no need to grab the users id and loop through a record set and update each one individually.

Anyway, I looked all over to find out how to do this and didn't seem to get any clear answers. The problem was how to run a cron when the server can't log you into Facebook to rebuild the profile pages. This required creating an infinite session -- but Facebook has changed how you do this in the past year and there are many blog posts that contradict each other on it.

After several failed attempts (the cron would work for a day and then fail), I found this recent blog post: http://www.emcro.com/blog/2009/01/facebook-infinite-session-keys-no-more/

I followed his instructions on getting an infinite session and now this is how it now looks:

$appapikey = 'app api key';
$appsecret = 'app secret key';
$infiniteSessionkey = 'app session key';
$facebook = new Facebook($appapikey, $appsecret);
$userid = your userid;

// log into facebook using the userid and infinite session key
$facebook->api_client->user = $userid;
$facebook->api_client->session_key = $facebook_infinite_session_key;
$facebook->api_client->expires = 0;

// how that you're logged in you can call fbml_refreshRefUrl() to reset the contents
$facebook->api_client->fbml_refreshRefUrl("http://www.youyrsite.com/facebook/profile-narrow.php");

You can then just run a cron on your server that calls the page periodically to refresh the profile box:
/usr/bin/wget -O - -q -t 1 http://www.mysiteurl.com/facebook/refresh-profile-apps.php

UPDATE (Feb 3, 2009): It appears that I made it work by pure accident. If you notice the code above (which I had copied and pasted) I set the session_key to be equal to a non-existent variable:

$facebook->api_client->session_key = $facebook_infinite_session_key;

So the session key was being set to nothing. When I changed it to use the infinite session key I went through all the trouble of getting, it said that the session had expired. In fact if you comment out the line entirely it still works. I'm thinking that the trick is the following line that sets the expires to 0:

$facebook->api_client->expires = 0;

I'll have to experiment a bit more with this since its likely Facebook will plug this hole up sooner or later.

Also, a recent comment from a Facebook employee to the blog mentioned above links to a number of docs that were posted to the Facebook Developer blog that deal with what used to be called "infinite sessions" but are now "offline access":

*************************

http://developers.facebook.com/news.php?blog=1&story=116
http://developers.facebook.com/news.php?blog=1&story=130
http://developers.facebook.com/news.php?blog=1&story=132
http://developers.facebook.com/news.php?blog=1&story=135

The initial doc for it (mentioned in those posts):
http://wiki.developers.facebook.com/index.php/New_Design_Platform_Changes#Changes_to_Session_Keys

A FAQ about changes to authentication:
http://wiki.developers.facebook.com/index.php/New_Design_User_Login
http://wiki.developers.facebook.com/index.php/Authorizing_Applications

The easy way to get an “infinite session” is to prompt your users for offline access, as described here (and again, announced in those blog posts):
http://wiki.developers.facebook.com/index.php/Extended_permissions

*************************

Unfortunately, no one updated the official docs when they made these changes, so searching for "infinite sessions" in the Wiki brings up none of this new info...

Saturday, January 24, 2009

Wednesday, January 14, 2009

Nice flex video player

Setting up a video display in Flex is easy but there is no prebuilt controller (not sure why that is...). Anyway, here was a good one for free:

http://www.fxcomponents.com/flex-video-player/

Update (jan 23 2009) this is not consistent scrubber -- as longer videos don't scrub properly...

Expand Flex tree by clicking row

This is cool, useful and easy. It allows the user to opne a tree branch by clicking anywhere in the parent row (not just the arrow icon):

import mx.events.ListEvent;

private function tree_itemClick(evt:ListEvent):void {
var item:Object = Tree(evt.currentTarget).selectedItem;
if (mytree.dataDescriptor.isBranch(item)) {
mytree.expandItem(item, !mytree.isItemOpen(item), true);
}
}

...
itemClick="tree_itemClick(event);" />