Auto-reconnect feature
MPlatform and MFormats SDKs have a feature to automatically reconnect common RTMP, RTSP and UDP streams. Once a stream goes down, you have an "Open network stream" message on a video preview:
By default, the feature is enabled. But you can manage it through the system registry:
MFormats SDK
HKEY_CURRENT_USER\Software\Medialooks\MFormats\MFReader network.reconnect = true
MPlatform SDK
HKEY_CURRENT_USER\Software\Medialooks\MPlatform\MFile\MFileFFM network.reconnect = true
Once the stream is again online, the decoding takes some time for initial buffering and restores playback.
But this feature has some disadvantages: it doesn't work for some specific streams and multicast UDP streams.
Manual reconnect feature
You can make the reconnect faster and reliable using a manual way. For this, you should check for statistics of your MFReader or MFile objects. In case of MPlatform SDK, it is possible to use MPlaylist's object statistics because its items are not available for monitoring.
In MPlatform SDK you should get "stat::added" value with the PropsGet method:
string value; myReader.PropsGet("stat::added", out value);
Once a stream goes down, the object starts producing copy frames marked with the "Added" flag (eMFF_AddedFrame).
Here is a screenshot of external statistics utility:
In MFormats SDK you should get "AddedFrame" flag from the frame's M_TIME props:
M_TIME time;
pFrame.MFTimeGet(out time);
bool isAdded = time.eFFlags == eMFrameFlags.eMFF_AddedFrame;
You should create a timer to check this value and keep a value in a variable. The moment the value of added frames is different from the previous one means that something is wrong with the stream.
At this moment you should start to reopen the stream with either FileNameSet method (for MPlatform SDK) or ReaderOpen method (for MFormats SDK).
It is better to do this in a separated thread in a while loop until any timeout or the stream has been reopened correctly. The body should be similar to this:
while (true) { try { myFile.FileNameSet(myURL, myProps); // for MFormats, please use ReaderOpen method break; } catch (Exception) {} }
Once the file is re-opened, you can continue playback. Don't forget to keep the last value of the "stat::added" to continue monitoring of the stream stability.
Seeking after a stream reconnect
If a stream is used in a playlist, or you have a schedule for the stream (so it should be played for, let's say, 30 seconds), it is required to make a seeking after the stream has been reconnected.
The reconnect with the above FileNameSet method will restart the stream from the 0 position.
To make it get back on the correct position you should do the following:
1. Disable auto-opening the stream once it is back online:
HKEY_CURRENT_USER\Software\Medialooks\MPlatform\MFile\MFileFFM network.reconnect_open = false
In this mode, the added frames are still generated, but even the stream is available again, it doesn't start the playback.
So, in general, "stat::added" value grows until the stream isn't back again. And once it is back, the value stops growing and "stat::elapsed" starts to increase. The value of "elapsed" means how long the object waits for a proper frame.
To resume the stream from the required position, you should get the previous position with FilePosGet method. After the reconnect, you should add the value of elapsed time to the position and use the result for FilePosSet method..
In code it looks like:
while (true) { try { double position; myFile.FilePosGet(out position); string elapsedTime; myFile.PropsGet("stat::elapsed", out elapsedTime); myFile.FileNameSet(myURL, myProps); // for MFormats, please use ReaderOpen method myFile.FilePosSet(position + Convert.ToDouble(elapsedTime, CultureInfo.InvariantCulture, 0); break; } catch (Exception) {} }