Part of this has been solved, and part hasn't. The part that's been solved is how to allow a client to choose between two plugins which are both capable of handling the resource. The solution is the IMediaResourceHandlerResolver interface that a client can optionally pass to the MediaFactory. Whenever the factory determines that more than one plugin can handle the same resource, it will ask the resolver to choose one from the list. This is a case where the framework simply doesn't have enough info to make the decision, so we give the client a "hook" to make the decision.
The part that hasn't been solved is how we represent the metadata that a resolver can use to distinguish between two different plugins. (Recap: an IMediaResource has a metadata property which can hold any arbitrary metadata that describes the resource.) If Akamai defines their own metadata namespace to describe their plugin, and Limelight defines a completely different namespace and structure, then it becomes much harder for a player developer to implement what you describe. However, if OSMF defines the standard way to represent metadata for (e.g.) CDN plugins, then it becomes much simpler.
Anyhow, that's probably more info than you were looking for. Please file a bug on this, as I think we ought to define a metadata schema that covers the most common use cases (like this one).
Ah. I can see the difficulty here. I took a shot at implementing a IMediaResourceHandlerResolver with custom CDN metadata and the results were not ideal. The challenge I ran into was I could tag a resource with metadata that would help identify a specific plugin to use -- say akamai -- but for a resource without a tag I'd need to drop back to calling canHandleResource(). But akamai will answer that it can handle the resource, and speaking in general about a plugin -- there's no way to tell that what it will do will be compatible with the endpoint. This is somewhat of an edge case -- needing to support multiple CDNs -- so it seems like I should create my own elements rather than using the MediaFactory.
I would argue that it's not an edge case, it's a core use case which OSMF ought to address. However, I'm not quite sure what if anything we can do about the specific problem case you mention, namely where you have a resource with no metadata, and the resolver should be able to determine which plugin to pick. Is it a common case for you to not know which CDN the resource corresponds to (and thus not be able to tag it with the right metadata)? And if so, how would you expect the framework to work? Seems like in that case, the only thing we could do is try the connection with one of the plugins, and possibly fail-over to the other.
OK, I'll defer to you about whether it's core to OSMF. Most of our media assets are associated with a CDN profile but assets can also have no profile assigned. For metadata, I'd like to specify a media class (vdeo, audio, image, ...) and optionally target a specific plugin (in this case a CDN). If the media doesn't target a specific plugin then I'd like the MediaFactory to look at a default list of media handlers (rather than letting plugins like akamai have a shot at it -- there are cases where urls will play with the defaul handlers that will not with akamai). I looked into doing this using the current MediaFactory and in my initial try didn't find a clean way (though later I realized one way is to have each resource target a specific handler). It may have been an imperfect try but I also felt that it's possible my use case might be pushing what should be expected by the framework at this point.
Awesome work BTW. I'm amazed at the amount of work you've done between sprint 5 and 7.
I might be missunderstanding something, but I would recomend the following.
Have a few basic metadata properties like plugin name , plugin publisher, etc. Then also have a few constants (like an enumerated list) that describes the type of plugin it is. (e.gs CDN, Advertising, Beacon, Effect, ChromeElement, Interactive, Other)
It might also be interesting if the plugin had an list of traits that a mediaElement must have for the plugin to apply to it, as well as a list of traits that if the mediaElement does have it, don't apply the plugin. (For example, if video is streaming it could use the custom CDN seeking abilities, or an effects plugin might not work on videos that are streaming and will only want to work with progressive ones)
(Revisiting this old thread, if only to capture some additional thoughts for posterity.)
I realize now the problem you ran into, and why the resolver as it exists today may be insufficient to address this case. As you pointed out, the Akamai handler will indicate TRUE whether the resource has the CDN metadata or not (since it truly can handle both cases), but there's no way for you (via the resolver) to distinguish those cases without being aware of some aspects of how the Akamai plugin makes its canHandleResource decision. This was why I was proposing a standard metadata schema for various plugins, as you could then take that metadata into account when deciding which of the N handlers to use.
For example, let's say there's a metadata namespace (I'll make one up: "www.osmf.org/plugin/cdn/1.0") that maps to a KeyValueFacet which can hold a key called "cdnID". Expected values for the key are the domain name for the publisher ("com.akamai" for Akamai, "com.limelightnetworks" for LLNW). You could then create a MultiCDNResourceHandlerResolver which would inspect the resource for this facet, and extract the relevant metadata. If your resolver sees the facet has a "cdnID" with value "com.akamai", then it would know that it ought to select the handler for Akamai. (Similarly for LLNW.)
The problem here is that there's no way to correlate a handler with the plugin from which it came. All you have is an IMediaResourceHandler, there's no way to ask it anything other than whether it can handle the resource. So I think the enhancement we need is to add a way to learn more about the handler than is currently exposed. In reality, your handler is always going to be a MediaInfo, which exposes an id property. So you ought to be able to cast the handler to a MediaInfo and check to see if the id property matches that of Akamai or LLNW (e.g. pattern-match against "com.akamai.*" or "com.limelightnetworks.*"). However, it ought to be more obvious how to do this (and not require upcasting to a subclass).
Does this sound like it would work for your case?
That's pretty much what I found. And you did a much better job of detailing the problem that I did!
The original issue I ran into was that Akamai and Limelight use different schemes for authentication -- one on the connect and the other on the play. You don't want a limelight plugin handling a akamai uri, and vice versa. There could be metadata that specifies where the uri needs the query, but it would need to be added to the plugin also for matching. And I also felt there could be other gotchas out there that I hadn't thought of and it might just be better for me to target uri's to specific handlers to be safe.
What you're describing would work for what I'd like to do -- either specifically target a plugin or have enough information to decide which will correctly handle the resource.
Thanks for following up on this!
FYI - we've done some refactoring in public trunk which should hopefully get us closer to solving this. The MediaFactory now works with a MediaFactoryItemResolver. (MediaFactoryItem is the new name for MediaInfo.) So you could now create a MediaFactoryItemResolver that checks the id property of all MediaFactoryItems that can handle your resource, and select the one that you're looking for (presumably Akamai's IDs will have the string "akamai" in them, and Limelight's "llnw"). This might be enough to solve the problem, if not we can consider whether it makes sense to define that plugin metadata schema.
Awesome. I just updated to 0.9 -- I'll move to the TRUNK in the next few days and let you know. I'm doing what you describe now, but in the plugin resolver.