Blog Archives

Convert Video to and from Adobe Flash .FLV format

The first three tools are Windows specific, with the last being cross-platform and especially necessary for linux users.

Super11
Link: http://www.videohelp.com/tools/SUPER
Not well known, but very robust software with good features and overall good functionality.

Riva FLV Encoder
Link: http://rivavx.com/?encoder
Similar to Any Video Converter (listed below). Depending on your needs, compare with Any and/or combine for best results. If you’re expecting some loss in quality and the end user won’t be watching playback in large streamed content then this or Any Video should work good for you.

Any Video Converter
Link: http://www.any-video-converter.com/products/for_video_free/
Good free product which gets the job done. A little less robust than Super in my opinion, and very similar to Riva as I stated above, but easier to use and probably better for quick youtube edits and uploads.

Adobe Media Encoder
Link: http://www.adobe.com/devnet/flash/quickstart/video_encoder.html
This product does the job pretty well, and I have personally used it for managing some quicktime and .flv video conversions. Visually it is more impressive than the others, but I found overall speed to actually be a bit slower after various testing. There were also some issues on .flv’s that didn’t play audio or video properly after conversion which seemed to work in other editors/converters. Especially interesting in these cases is the videos were output from another Adobe product.. Overall very surprised that Adobe didn’t come out on top with regards to their own platform.

FFmpeg
Link: http://www.ffmpeg.org/
FFmpeg is really at the core of much video conversion on the web, including some of those listed above. If you can master utilizing this tool from command line, or if you’re natively on linux, this is for you. Searching for ffmpeg GUI or frontend will also return some good results if you’re rather not run the commands manually.

View PDF in Objective-C Cocoa on Mac OS X using PDFKit

The code below has been tested and works clean on the latest version of Mac OS X 10.5 Leopard.

Since it applies to native Mac OS X, and not iOS, porting this to work on iPhone/iPad is a bit different, however, it is overall very easy once you have the base concept and the main functionality below is the same.

Note: If you create this as a blank new project and are new to PDFKit, first make sure to add the Quartz framework to your project. (ref)

First, create a class (and corresponding header) to utilize the PDF. (CODE IS CASE SENSITIVE)

PDFImageView.h

#import <Cocoa/Cocoa.h>
#import <Quartz/Quartz.h>

@interface PDFImageView : NSImageView

- (void) loadFromPath: (NSString *) path;

@end

PDFImageView.m

#import "PDFImageView.h"
#import "DraggableScrollView.h"

@implementation PDFImageView

- (NSPDFImageRep *) pdfRep
{
return [[[self image] representations] lastObject];
}

- (void) loadFromPath: (NSString *)path
{
NSPDFImageRep *pdfRep;
NSImage *pdfImage;
NSRect frame;

pdfRep = [NSPDFImageRep imageRepWithContentsOfFile:path];
pdfImage = [[[NSImage alloc] init]autorelease];
[pdfImage addRepresentation: pdfRep];

frame = [pdfRep bounds];
frame.size.height *= [pdfRep pageCount];

[self setImage: pdfImage];

[super setFrame: frame];

if ([self isFlipped])
    [self scrollPoint: NSMakePoint(0,0)];
else {
    [self scrollPoint: NSMakePoint(0,frame.size.height)];
}
}

- (void) drawRect: (NSRect) rect
{
NSPDFImageRep *rep;
int pageCount, pageNumber;
NSRect onePageBounds;

[[NSColor whiteColor] set];
NSRectFill (rect);

rep = [self pdfRep];
pageCount = [rep pageCount];

for (pageNumber=0;pageNumber<pageCount;pageNumber++)
{
onePageBounds = [self rectForPage: (1+pageNumber)];
if (! NSIntersectsRect(rect, onePageBounds))
continue;

[rep setCurrentPage: pageNumber];
[rep drawInRect: onePageBounds];
}
}

- (void) mouseDown: (NSEvent *) theEvent
{
NSScrollView *scrollView;
scrollView=[self enclosingScrollView];
if ([scrollView respondsToSelector: @selector(dragDocumentWithMouseDown:)])
[(DraggableScrollView*)scrollView dragDocumentWithMouseDown: theEvent];
else {
[super mouseDown: theEvent];
}

- (void) setFrameSize: (NSSize) newSize
{
NSSize PDFsize;
float correctHeight;

PDFsize = [[self pdfRep] bounds].size;
correctHeight = [[self pdfRep] pageCount] * (PDfsize.height/PDFsize.width) * newSize.width;
correctHeight = ceil(correctHeight);

if (abs (correctHeight - newSize.height) > 3.0)
newSize.height = correctHeight;

[super setFrameSize: newSize];
}

- (BOOL) knowsPageRange: (NSRangePointer) range
{
range->location=1;
range->length=[[self pdfRep] pageCount];

return YES;
}

- (NSRect) rectForPage: (int) pageNumber
{
NSPDFImageRep *rep;
int pageCount;
NSRect result;

rep = [self pdfRep];
pageCount = [rep PageCount];

result = [rep bounds];
if (! [self isFlipped])
result = NSOffsetRect(result,0.0,(pageCount-1)*result.size.height);

if ([self isFlipped])
result = NSOffsetRect (result,0.0,(pageNumber-1)*result.size.height);
else {
result = NSOffsetRect (result,0.0,-(pageNumber-1)*result.size.height);

return result;
}
}
@end

This class is courtesy of Apple DC and used in the above PDFViewer class. You shouldn’t have to really do anything additional in this one, just plug and play. Allows user to scroll with mouse. I removed alot of comments for brevity to minimize code lines. See Apple reference at bottom for full source and additional info.

DraggableScrollView.h

#import <Cocoa/Cocoa.h>
 
@interface DraggableScrollView : NSScrollView
 
- (BOOL) dragDocumentWithMouseDown:
    (NSEvent *) theEvent;
 
@end

DraggableScrollView.m

#import "DraggableScrollView.h"
 
@implementation DraggableScrollView
 
#pragma mark PRIVATE CLASS METHODS
 
+ (NSCursor *) dragCursor
{
    static NSCursor *openHandCursor = nil;
 
    if (openHandCursor == nil)
    {
        NSImage     *image;
 
        image = [NSImage imageNamed: @"fingerCursor"];
        openHandCursor = [[NSCursor alloc] initWithImage: image
            hotSpot: NSMakePoint (8, 8)]; // guess that the center is good
    }
 
    return openHandCursor;
}
 
 
#pragma mark PRIVATE INSTANCE METHODS
 
- (BOOL) canScroll
{
    if ([[self documentView] frame].size.height > [self documentVisibleRect].size.height)
        return YES;
    if ([[self documentView] frame].size.width > [self documentVisibleRect].size.width)
        return YES;
 
    return NO;
}
 
 
#pragma mark PUBLIC INSTANCE METHODS -- OVERRIDES FROM NSScrolLView
 
- (void) tile
{
    [super tile];
 
    //  If the user can scroll right now, make our document cursor reflect that.
    if ([self canScroll])
        [self setDocumentCursor: [[self class] dragCursor]];
    else
        [self setDocumentCursor: [NSCursor arrowCursor]];
}
 
 
#pragma mark PUBLIC INSTANCE METHODS
 
//  dragDocumentWithMouseDown: -- Given a mousedown event, which should be in
//  our document view, track the mouse to let the user drag the document.
- (BOOL) dragDocumentWithMouseDown: (NSEvent *) theEvent // RETURN: YES => user dragged (not clicked)
{
    NSPoint         initialLocation;
    NSRect          visibleRect;
    BOOL            keepGoing;
    BOOL            result = NO;
 
    initialLocation = [theEvent locationInWindow];
    visibleRect = [[self documentView] visibleRect];
    keepGoing = YES;
 
    while (keepGoing)
    {
        theEvent = [[self window] nextEventMatchingMask: NSLeftMouseUpMask | NSLeftMouseDraggedMask];
        switch ([theEvent type])
        {
            case NSLeftMouseDragged:
            {
                NSPoint newLocation;
                NSRect  newVisibleRect;
                float   xDelta, yDelta;
 
                newLocation = [theEvent locationInWindow];
                xDelta = initialLocation.x - newLocation.x;
                yDelta = initialLocation.y - newLocation.y;
 
                //  This was an amusing bug: without checking for flipped,
                //  you could drag up, and the document would sometimes move down!
                if ([[self documentView] isFlipped])
                    yDelta = -yDelta;
 
                //  If they drag MORE than one pixel, consider it a drag
                if ( (abs (xDelta) > 1) || (abs (yDelta) > 1) )
                    result = YES;
 
                newVisibleRect = NSOffsetRect (visibleRect, xDelta, yDelta);
                [[self documentView] scrollRectToVisible: newVisibleRect];
            }
            break;
 
            case NSLeftMouseUp:
                keepGoing = NO;
                break;
 
            default:
                /* Ignore any other kind of event. */
                break;
        }                               // end of switch (event type)
    }                                   // end of mouse-tracking loop
 
    return result;
}
 
@end

And now for the main class of our application which will use the above PDFImageView class and bind/map to our interface.

MainView.h

#import <Cocoa/Cocoa.h>
#import <Quartz/Quartz.h>

@interface MainView : NSDocument {
IBOutlet PDFView *_pdfView;
}

@end

MainView.m

#import "MainView.h"

@implementation MainView

//will load PDF from local filesystem in current path as .app is launched from
-(void)awakeFromNib{
NSFileManager *filemgr;
filemgr = [[NsFileManager alloc]init];

NSString *currentpath = [[[[NSBundle mainBundle] bundlePath] stringByDeletingPathExtension] stringByDeletingLastPathcomponent];

//[Util MessageBox:@"currentpath":currentpath]; //SEE MY REFERENCE BELOW FOR DEBUG UTILITY CLASS

NSString *fileName = [NSString stringWithFormat:@"%@/%@/",currentpath,@"filename.pdf"];
PDFDocument *pdfDoc = [[PDFDocument alloc] initWithURL:[NSURL fileURLWithPath:fileName]];
[_pdfView setDocument: pdfDoc];
}

@end

References
Apple DC, http://developer.apple.com/library/mac/#samplecode/PDFView/Introduction/Intro.html
“Show Dialog Message Box in Objective-C Cocoa”, https://ronniediaz.com/2011/06/13/show-dialog-message-box-in-objective-c-cocoa/
Google CodeSearch (“_pdfView”), http://www.google.com/codesearch#search&q=_pdfView+lang:objectivec

Download Recordings from Adobe Connect Pro

Thanks goes to Guillaume Privat on Adobe Learning Center (see references below for links):

(And a shout out to Matt Chambers for providing the links :D)

1) You need to ensure you are an account administrator of have full right on the recording.

2) Find the URL of the recording you want to extract.

3) Add /output/recording.zip?download=zip at the end of the recording URL.

4) Save the zip file on your desktop

Example download link:
http://aquo.adobe.acrobat.com/p14313281/output/recording.zip?download=zip

Open the zip, and verify contents. It should contain .flv and xml files. mainstream.flv is to playback all and the actual audio/video content is denoted by filenames with underscores.

The alternative is offline recording, which results in a couple flat .flv’s, but in this format, once downloaded… the fun begins.

Both richflv and Moyea seem to have trouble with the Sorenson Sparks / On2 VP6 / Nellymoser / Speex codec mishmash Adobe mashed up with their flv “pods” and XML.. “keyframes” (cue points) spot the video in random intervals, and cause issues with edited output playback and seek/fast forward/rewind.

Good luck. 😉

References:
Recordings Deep Dive part 1 and 2, http://connectusers.com/tutorials/2009/08/recordings_deep_dive_part1/index.php, http://connectusers.com/tutorials/2009/09/recordings_deep_dive_part2/index.php
RichFLV, http://richapps.de/?page_id=120
Moyea FLV Editor (PRO), http://www.moyea.com/flv-converter/
Nellymoser, http://en.wikipedia.org/wiki/Nellymoser_Asao_Codec
Sorenson (Sparks), http://en.wikipedia.org/wiki/Sorenson_codec
On2 VP6, http://en.wikipedia.org/wiki/VP6
Speex, http://www.speex.org/

Flash and Silverlight Coverflows

After reviewing a few different flash coverflows, stumbled across the following:

Flash gallery:
http://flash-gallery.com/?c=104&gclid=CPTvuPDCj6cCFUHt7QodfwQFbw

Weber Design Labs:
http://www.weberdesignlabs.com/blog/2007/09/flash-itunes-cover-flow-version-2/

Flash XML:
http://www.flashxml.net/cover-flow.html

Flash Components.Net:
http://www.flashcomponents.net/components/flash_galleries_and_slide_shows/flash_stack_and_coverflows.html

If you’re not opposed to silverlight however, I encourage you to check this one out by Telerik:
http://www.telerik.com/products/silverlight/coverflow.aspx

Load External HTML file in CS5

Upon initial google search for the above title phrase, I came across no results! Only after resorting to my second search avenue (Google Books :)), did I then stumble across “The CS5 bible“.

Thanks to the brilliance of Google Books, I was able to read through only the chapters I needed (you rock Google!) and discover the solution I was actually looking for was – Adobe Air.

Adobe Air allows you to embed HTML as well as other content within the html, such as JS and additional flash files all within a flash framework allowing you to utilize actionscript and other traditional elements. The end result is now an extremely portable flash file which acts as a wrapper or window to your web application. This is also now very easy to port into a standalone out of browser application using the “projector” functionality of CS5.

The code:

var container:Sprite;
var html:HTMLLoader = new HTMLLoader;
html.width = 400;
html.height = 600;
var urlReq:URLRequest = new URLRequest("http://www.adobe.com/&quot;);
html.load(urlReq);
container.addChild(html);

References
Google Books, http://books.google.com/
Amazon, http://www.amazon.com/Photoshop-Bible-Lisa-DaNae-Dayley/dp/0470584742
Adobe Air, http://www.adobe.com/products/air/
Adobe LiveDocs, http://livedocs.adobe.com/flex/3/html/help.html?content=ProgrammingHTMLAndJavaScript_02.html

Run SWF Files from an EXE

SWF/Flash files may be embedded into an executable a number of ways, using:

Adobe Flash Platform
Adobe Air
MDM Zinc
Northcode SWF Studio

Adobe Flash and Air refer to the published executable as projectors, and both can be packaged using the Adobe Flash Platform or Air.

Zinc and SWF Studio are both 3rd party products which offer similar functionality. In my opinion, Zinc is the greater of the two products, as it offers support for Windows, Mac and Linux! It also has an API/framework for utilizing WinForms functionality such as launching modal form windows using actionscript. The API is packaged into the executable, so a clean standalone file is still all that is needed for deployment.

SWF Studio is more of an “out of the box” product, which functions as is for what it is needed for. Some may favor it due to its simplicity and ease of user interface, which on the surface seems to have a bit more features.

Ultimately, I went with Adobe Air in my particular scenario, which was definitely the most complex of the solutions, but provided the best compatibility by far (obviously) and the best one to get to work with SWF files that wrapped other SWF files multiple layers deep.

Brief addendum:
Initially I developed a custom .Net solution which loaded the SWF file inside of a form, (webbrowser object in winforms or frame in wcf) but the dependency on .Net and furthermore, Mono, in Mac/Linux systems posed as a problem since the delivery of the player needed to fit on CD/DVD alongside the videos, with very little space to spare for adding in additonal frameworks.

References
Adobe Flash Platform, http://www.adobe.com/flashplatform/
Adobe Air, http://www.adobe.com/products/air/
MDM Zinc, http://www.multidmedia.com/software/zinc/
Northcode SWF Studio, http://www.northcode.com/
Mono-Project, http://www.mono-project.com/Main_Page

Load SWF from Fla file CS5

The title of this blog was my initial search in google upon looking for a way to load and play an external SWF file inside a new FLA project file.

In AS2, I recalled this was easily achieved using MovieClip, however, Adobe has deprecated this functionality in favor of the newer AS3 concept of “loader” objects.

See syntax below and references for helpful links:

var myLoader:Loader = new Loader(); 
addChild(myLoader); 
var url:URLRequest = new URLRequest("filename.swf"); 
myLoader.load(url); 

Slightly less orthodox, but code below works also. Note URLRequest can point to a local file or a remote SWF file on the web.

swfLoader = new Loader();
swfLoader.load(new URLRequest("filename.swf);
addchild(swfLoader); 

Can also be done using UI Loader:

import fl.containers.UILoader;

var myUILoader:UILoader = new UILoader();
myUILoader.source = "Rich Investor.swf";
myUILoader.move(0, 0);
myUILoader.scaleContent = false;

addChild(myUILoader);

Using Adobe Air in publish settings:

   package {

   import flash.display.Sprite;
    import flash.html.HTMLLoader;
    import flash.net.URLRequest;

    public class HTMLLoaderExample extends Sprite
    {
        public function HTMLLoaderExample()
        {
            var html:HTMLLoader = new HTMLLoader();
            var urlReq:URLRequest = new URLRequest("Rich Investor.htm");
            html.width = stage.stageWidth;
            html.height = stage.stageHeight;
            html.load(urlReq); 
            addChild(html);
        }
    }
   }

References
Load external SWF files into Flash Player, http://kb2.adobe.com/cps/141/tn_14190.html
Creating new MovieClips in ActionScript 3.0, http://blogs.adobe.com/pdehaan/2006/07/creating_new_movieclips_in_act.html
Loader vs MovieClip http://forums.adobe.com/thread/434686?tstart=1
Loader vs. UILoader, http://www.kirupa.com/forum/showthread.php?t=283920
Getting Started with AS3 and Flash CS3, http://www.actionscript.org/resources/articles/636/2/Getting-Started-With-AS3-and-Flash-CS3/Page2.html
UI Loader, http://www.gotoandlearnforum.com/viewtopic.php?t=17761
MovieClip (object) http://www.adobe.com/support/flash/action_scripts/actionscript_dictionary/actionscript_dictionary505.html
Loading a .swf file into a .fla file, http://www.flashmove.com/forum/showthread.php?t=9318
Add video to Flash, http://help.adobe.com/en_US/flash/cs/using/WSb03e830bd6f770ee-70a39d612436d472f4-7ff8.html
Externally loading SWF into movie clip, http://www.actionscript.org/forums/showthread.php3?t=156851