EDIT If someone can at least tell me how to receive an event when the streams disconnects that would be great.
The documentation for this control is simply horrible. I have an application that will have a live video stream and I'm looking for a way to make the VideoDisplay control restore its connection in case of the occurrence of any of these specific scenarios:
I'm using Wowza Media Server and Wirecast to test this. 1 and 3 don't work, I'm not sure number 2 does. I made number 1 work by adding this very questionable piece of code:
protected function onMediaPlayerStateChange(event:MediaPlayerStateChangeEvent):void
{
if (event.state == MediaPlayerState.PLAYBACK_ERROR)
{
var videoSource:DynamicStreamingVideoSource = this.videoDisplay.source as DynamicStreamingVideoSource;
try
{
this.videoDisplay.source = null;
this.videoDisplay.source = videoSource;
}
catch (any:*) {}
}
}
As you can see I need a try/catch block since both calls to source cause exceptions, yet whatever happens before those exceptions seems to fix problem #1. This doesn't fix problem #3 because a media state change event apparently doesn't occur when you stop the video server.
This is my control declaration:
<s:VideoDisplay id="videoDisplay" click="onVideoStreamClick(event)" mediaPlayerStateChange="onMediaPlayerStateChange(event)" muted="{this.videoMuted}" top="10" width="280" height="220" autoPlay="true" horizontalCenter="0">
<s:source>
<s:DynamicStreamingVideoSource id="videoSource" streamType="live" host="{FlexGlobals.topLevelApplication.parameters.videoStreamURL}">
<s:DynamicStreamingVideoItem id="videoItemLow" streamName="{FlexGlobals.topLevelApplication.parameters.videoLow}" bitrate="{FlexGlobals.topLevelApplication.parameters.videoLowBitrate}" />
<s:DynamicStreamingVideoItem id="videoItemMedium" streamName="{FlexGlobals.topLevelApplication.parameters.videoMedium}" bitrate="{FlexGlobals.topLevelApplication.parameters.videoMediumBitrate}" />
<s:DynamicStreamingVideoItem id="videoItemHigh" streamName="{FlexGlobals.topLevelApplication.parameters.videoHigh}" bitrate="{FlexGlobals.topLevelApplication.parameters.videoHighBitrate}" />
</s:DynamicStreamingVideoSource>
</s:source>
</s:VideoDisplay>
Does anyone know how to make the VideoDisplay recover from these issues? Any help is appreciated, thanks.
If anyone has this problem, this is how I solved it. You need to set the video source to a blank image in order to stop the streaming, otherwise it will never, ever stop. This solution works for all scenarios described above:
private function resetVideo():void
{
//save current source object
this.videoEventsDisabled = true;
var videoSource:DynamicStreamingVideoSource = this.videoDisplay.source as DynamicStreamingVideoSource;
try //switch to blank image, only this will stop the video stream
{
this.videoDisplay.source = "assets/images/video_offline.png";
}
catch (any:*) {}
//wait a few seconds and reset video source
setTimeout(resetVideoSource, 2000, videoSource);
}
private function resetVideoSource(videoSource:DynamicStreamingVideoSource):void
{
this.videoEventsDisabled = false;
this.videoDisplay.source = videoSource;
}
protected function onMediaPlayerStateChange(event:MediaPlayerStateChangeEvent):void
{
if (this.videoEventsDisabled)
{
return;
}
//something went wrong
if (event.state == MediaPlayerState.PLAYBACK_ERROR)
{
resetVideo();
}
}
protected function onCurrentTimeChange(event:TimeEvent):void
{
if (this.videoEventsDisabled)
{
return;
}
//if there was a number before, and its suddendly NaN, video is offline
if (isNaN(event.time) && !isNaN(this.previousVideoTime))
{
resetVideo();
}
else //store event time for future comparisons
{
this.previousVideoTime = event.time;
}
}
MXML:
<s:VideoDisplay id="videoDisplay" click="onVideoStreamClick(event)" mediaPlayerStateChange="onMediaPlayerStateChange(event)" currentTimeChange="onCurrentTimeChange(event)" muted="{this.videoMuted}" top="10" width="280" height="220" autoPlay="true" horizontalCenter="0">
<s:source>
<s:DynamicStreamingVideoSource id="videoSource" streamType="live" host="{FlexGlobals.topLevelApplication.parameters.videoStreamURL}">
<s:DynamicStreamingVideoItem id="videoItemLow" streamName="{FlexGlobals.topLevelApplication.parameters.videoLow}" bitrate="{FlexGlobals.topLevelApplication.parameters.videoLowBitrate}" />
<s:DynamicStreamingVideoItem id="videoItemMedium" streamName="{FlexGlobals.topLevelApplication.parameters.videoMedium}" bitrate="{FlexGlobals.topLevelApplication.parameters.videoMediumBitrate}" />
<s:DynamicStreamingVideoItem id="videoItemHigh" streamName="{FlexGlobals.topLevelApplication.parameters.videoHigh}" bitrate="{FlexGlobals.topLevelApplication.parameters.videoHighBitrate}" />
</s:DynamicStreamingVideoSource>
</s:source>
</s:VideoDisplay>