There’s one deployment scenario for using smoothing in OSMF that’s really easy. You create your video element using the default media factory and you set the smoothing property to true. Done and done. That’s super simple.
When you have a complex media element, involving proxy elements, sequences, and plug-in generated media elements, that simplicity gets stomped on with a big hobnailed boot. Let’s look at three plug-ins you might use. They’re all included in OSMF. The Captioning plug-in wraps the media in a proxy element. The MAST plugin takes your media element and puts it into a SerialElement with other media to display ads around your video. The Akamai Basic Streaming plug-in uses its own media factory items to generate its own media elements. Combine all these together, and the media element that comes out of that media factory is a complex structure you’d need to navigate to get to that VideoElement (or elements) at its center to turn that smoothing on. And through the power of OSMF there are infinite variations and complexities to the structure your media element can take. Proxies can wrap proxies which can wrap sequence and parallels and so on.
There’s no way to set smoothing before you generate your media element. Nor is there a way to set it on the player to make all videos smooth. After all, not all media elements use smoothing, so making the player or a resource have it doesn’t make sense. So, one way to do it would to build some devious, recursive function that burrows through complex, byzantine structures. But screw that. Screw recursion.
One solution I arrived at was to make a custom MediaFactory class. I can set the media creation function on my media factory items, so I can make them call a function that automatically sets smoothing on the generated VideoElement. Most plug-ins use the media factory’s default media factory items to generate their media elements and then wrap them in their proxy element. So, that works most of the time … but unfortunately, not all of the time.
The Akamai Basic Streaming plugin uses its own media factory items. There’s nothing wrong with it. However, it hoses my solution for using custom media creation functions to set smoothing. The element is created inside the plug-in and then returned to private methods in the MediaFactory class to be swaddled in proxy elements, sequences and that whole convoluted mess we had just sidestepped. Here we are again, staring at a recursive solution. But remember, we said screw recursion. And I meant it.
Brian Riggs from the OSMF team helped me out here and suggested overriding the media factory items to use my own media creation functions. Unfortunately, this doesn’t work right away, because the plug-in’s custom media creation functions inject special code into the media element, and those are classes I don’t want to have to try to import. I certainly don’t want to try to duplicate the functionality of the plug-in in my media factory.
Using Brian’s suggestion as a springboard, I found a way around this quandary. The resolveItems method of the MediaFactory class is protected, which means I can override it in my custom media factory. It decides which media factory item to use to generate the media element. In my override of resolveItems, I grab the media factory item it is about to return and check to see if it is a custom item. If it is, I create a duplicate media factory item, but insert my own media creation function. I also store a reference to the original creation function. In my media creation function, I call the original creation function and then intercept the media element it creates. I can set the smoothing on the element and then return it without anyone being the wiser.
override protected function resolveItems(resource:MediaResourceBase, items:Vector.):MediaFactoryItem
{
var mfi:MediaFactoryItem = super.resolveItems( resource, items );
/*If a custom MFI is being used, hijack it and intercept the media element it returns to set smoothing on it*/
if( mfi.id.indexOf( 'org.osmf' ) < 0 )
{
_highjackedMediaCreationFunction = mfi.mediaElementCreationFunction;
var hijacker:MediaFactoryItem = new MediaFactoryItem( mfi.id, mfi.canHandleResourceFunction, interceptMediaElement );
return hijacker;
}
return mfi;
}
protected function interceptMediaElement():MediaElement
{
var element:MediaElement = _highjackedMediaCreationFunction();
if( element is VideoElement )
{
VideoElement( element ).smoothing = useSmoothing;
}
return element;
}
In this way, I can sidestep the whole structure of the media element and get right to the core of the media element. And that means recursion can suck it.