...and another use case I wanted to add is the more obvious one that you probably already know about, that is the case where you simply want to get to the NetStream object the framework created for you. You can get to this via the ILoadable trait on the media element *after* the media element has been loaded.
// somewhere in your code:
var loadable:ILoadable = mediaElement.getTrait(MediaTraitType.LOADABLE) as ILoadable;
// in your load state change listener:
var loadedContext:NetLoadedContext = event.loadable.loadedContext as NetLoadedContext;
var netStream:NetStream = loadedContext.stream;
I'm trying to detect when a video is complete using the addHandler method off of the client property from VideoElement:
var videoOne:VideoElement = new VideoElement ( new NetLoader, new URLResource(new URL("rtmp://4vl5ylx6.rtmphost.com/stream_test/quantumofsolace_8_hd")));
As you can see this is indeed a streaming video. But as soon as I add the listener I get nothing. If I comment it out, the video plays but I obviously can't detect for the completion event.
Any thoughts or insights or "you did it wrong!" would be greatly appreciated!
There are a couple of problems with your code. First, the client property on the VideoElement is going to return null until the NetLoader is asked to load the media. So you need to wait until the media is loaded before trying to access the client property.
Second, "NetStream.Play.Complete" is an info object passed to the "onPlayStatus" method, so you can't add a callback for an info object.
I've pasted some sample code below. Also note: before folks do things like this, I recommend looking at the internal traits in OSMF and see if there is one that fits your needs, it could save you time and lines of code. For example, there is a "durationReached" event on the ITemporal trait.
As you probably know, there are two different ways to detect the end of a video: for streaming, you can simply use the onPlayStatus and the NetStream.Play.Complete. But for progressive files, the best way to do it is to read the duration from the metadata and in your NetStatusEvent.NET_STATUS event handler, you can check if the NetStream time is within a delta of duration say, within 1 sec.
OSMF should be doing this for you, if not, it should and you should file a bug.
Here is a working example of your code, but I would recommend playing with the ITemporal trait and see if it is behaving properly for you.
public class osmf_test_client_addhandler extends Sprite
private static const TEST_STREAM:String = "rtmp://cp67126.edgefcs.net/ondemand/mp4:mediapm/osmf/content/test/sample1_700kbps.f4v";
private var videoOne:VideoElement;
public function osmf_test_client_addhandler()
// Create the Sprite class that holds our MediaPlayer.
var sprite:MediaPlayerSprite = new MediaPlayerSprite();
videoOne = new VideoElement(new NetLoader, new URLResource(new URL(TEST_STREAM)));
var loadable:ILoadable = videoOne.getTrait(MediaTraitType.LOADABLE) as ILoadable;
var serialElement:SerialElement = new SerialElement();
sprite.element = serialElement;
private function onLoaded(e:LoadableStateChangeEvent):void
if (e.newState == LoadState.LOADED)
private function onPlayStatus(info:Object):void
Thanks, Charles. Works great.
To be honest, although I understand conceptually the idea of the
traits, I'm having a difficult time finding examples of how to use
them, access them, when to use them, etc.
For example, I wouldn't have thought I would have had to use ILoadable
on a streaming video. I instinctively thought that meta-data would be
accessible as soon as the video connected and listening for a
"complete" event would then be viable.
If there is some documentation I've overlooked with specifics or
tutorials you could suggest specific to traits that would be very
I know traits are the core component of OSMF and understanding them is
integral to moving forward with any of my experiments.
I'll chime in with a few points. First, in 99% of the cases you don't need to worry about traits at all. Instead, you should be using the MediaPlayer class (perhaps wrapped in MediaPlayerSprite), which exposes the full API of all traits in a "flattened" form. Of course, if you're trying to define your own media, or create compositions (i.e. anything where you have to work with a MediaElement rather than a MediaPlayer), then you do need to be aware of traits.
The main idea behind MediaElement and the traits API is that we want OSMF clients to be able to write their code independent of the media type they're presenting. If your player works for video, then it ought to work for audio, images, SWFs, or even compositions containing all of the above. But for this to work, we need an abstraction that works for all media types. This abstraction is going to be less efficient than working with the native API, and in some cases more confusing (you point out that "loadable" isn't something that should apply to a streaming video), but the benefit is that you don't have to change your player when you bring in new media types. And once you've internalized what each trait is intended to represent (e.g. ILoadable will transition your media from its initial state, to the point where it is ready for playback -- which might mean calling NetConnection.connect, or Loader.load, or some other sequence of methods), then you can stop thinking about how the underlying media actually works, and just code to the traits.
So with that in mind, any time you find yourself needing to access the underlying media implementation (e.g. NetStream's client property), there should be an alarm bell going off in your head that something is wrong. Either you've overlooked a MediaElement/trait API that does what you're looking for, or we've missed something that ought to be abstracted and incorporated into the MediaElement/trait API (and we especially want to know about the latter).
In terms of documentation/tutorials on traits, the best I can recommend is to look closely at the implementations of specific traits for different media (e.g. NetStreamPlayableTrait vs. AudioPlayableTrait). Sometimes the best way to get your head around an abstraction like this is to see multiple examples of what it represents. I'd also recommend looking at the ExamplePlayer app, as that's a good demonstration of a player which makes no assumptions about media types. Based on your feedback so far, I think you're getting pretty deep into the core of OSMF, so I'd love to hear any other thoughts you have on what kind of resources we should provide to help others (i.e. what has been helpful for you so far).
Thanks so much for this great overview, Brian. You should include this
on the front page of the forum!
My first experiments with OSMF were approached exactly as you
suggested, using the MediaPlayer class wrapped in MediaPlayerSprite.
It's when I started to pick apart some of the media classes/elements
that I lost my way a bit.
I guess the part I didn't know was how to work with/access the actual
traits. The fact that you "assign" the traits to the media element and
then use that to listen for events had alluded me. I thought each
media class/element would have been able to listen for events itself.
And yes I know, traits are the beauty and power of OSMF and yet
through all of the documentation and examples I didn't pick up on this.
And I consider myself a relatively smart person... relatively.
So I guess more explicit examples in the code documentation of how to
use the traits would be great. With real-live examples tied to
different media types/elements.
I know your team lives and breathes this framework everyday. But for
folks just diving in (or maybe dove in months ago but is only floating
on their back instead of doing the breast stroke... weird analogy),
more concrete examples of using traits to listen for events would be
great. And also, cracking open the provided example source files in
Flex without having to track down all the packages and fixing errors
would be nice, too.
Overall, I'm a fan so far - no question. But inundating the user-group
with tons of examples and use-cases is very much a welcome thing.
Brian, I hope this helps. And if there are specific documents I missed
that do address the specifics I mentioned about traits please point me
to them. I'm sure there will be others in the community who may have
overlooked them, as well.