[DispIdAttribute(5)]
double AutoLiveTolerance {get; set;}
A double value indicating the tolerance value in seconds.
The AutoLiveTolerance is measured in seconds. Currently, all values > 0 for AutoLiveTolerance, instruct the network demux to prefer smooth video over live video. Future versions of demultiplexer will use this value to fine-tune the video playback latency.
The default is 0, which will force the network demux to favor live video. This can cause jerky playback on jittery networks with high latencies. VPNs and wireless networks are examples of jittery networks.
These jittery networks have occasional bottlenecks, which cause some packets to arrive with significant delays (could be several seconds). For these networks, the default behavior of choosing live video will cause the playback to freeze and then speed up when the interruptions occur, causing multiple packets to arrive at the same time. If this effect becomes undesirable, you can set the AutoLiveTolerance to a value greater than 0 (for example, set it to 3) to allow the to smooth the playback.
NOTE: You should keep in mind, however, that once you favor smooth playback, the playback stream will start to drift behind the live stream. As a result, there might be a delay of several seconds between what you see and what is captured at the other end.
using Leadtools.Multimedia;
using LeadtoolsMultimediaExamples.Fixtures;
public bool _result = false;
public CaptureAndPlayCtrlForm _serverAndClient = new CaptureAndPlayCtrlForm();
bool _msgSent = false;
CaptureCtrl _captureCtrl;
PlayCtrl _playCtrl;
LMNetMux _pMux;
LMNetDmx _pDemux;
const string _networkUrl = @"ltsf://127.0.0.1:27015"; // network stream url
const string _testMessage = "LEAD NETWORK";
string _recordedVideoFile = Path.Combine(LEAD_VARS.MediaDir, "DaDa_H264.mp4");
public void NetworkDemultiplexerExample()
{
// reference the capture control
_captureCtrl = _serverAndClient.CaptureCtrl;
// reference the play control
_playCtrl = _serverAndClient.PlayCtrl;
try
{
// try to find a video camera
if (_captureCtrl.VideoDevices["Logitech"] == null)
throw new Exception("No Logitech video device available");
_captureCtrl.VideoDevices["Logitech"].Selected = true;
// select a video compressor
_captureCtrl.VideoCompressors.Mpeg4.Selected = true;
// set the target output file
_captureCtrl.TargetFormat = TargetFormatType.NET;
_captureCtrl.TargetFile = _networkUrl;
if (_captureCtrl.IsModeAvailable(CaptureMode.Video))
{
// just 10 seconds of capture time
_captureCtrl.TimeLimit = 10;
_captureCtrl.UseTimeLimit = true;
_captureCtrl.FrameRate = 30;
_captureCtrl.UseFrameRate = true;
_captureCtrl.Preview = true;
// subscribe to the started and progress events for this example
// we will connect a client after the capture starts
// and send a test message after 5 seconds.
_captureCtrl.Started += new EventHandler(CaptureCtrl_Started);
_captureCtrl.Progress += new ProgressEventHandler(CaptureCtrl_Progress);
// ready the capture graph in order to get the LNMetMux instance
_captureCtrl.ReadyCapture(CaptureMode.Video);
// get the network multiplexer reference
_pMux = _captureCtrl.GetSubObject(CaptureObject.TargetFilter) as LMNetMux;
if (_pMux != null)
{
// set some mux settings
_pMux.LiveSource = true;
}
// start capture
_captureCtrl.StartCapture(CaptureMode.Video);
// we'll loop on the state and pump messages for this example.
// but you should not need to if running from a Windows Forms application.
while (_captureCtrl.State == CaptureState.Running
|| _playCtrl.State == PlayState.Running)
{
Application.DoEvents();
}
// verify we have a recording file too
_result &= File.Exists(_recordedVideoFile);
// release the mux and demux COM objects
if (_pMux != null)
Marshal.ReleaseComObject(_pMux);
if (_pDemux != null)
Marshal.ReleaseComObject(_pDemux);
}
}
catch (Exception)
{
_result = false;
}
}
void CaptureCtrl_Progress(object sender, ProgressEventArgs e)
{
// for this test we will send a message after
// 5 secs of capture time
if (e.time > 5000 && !_msgSent)
{
_pMux.WriteMessage(_testMessage);
Console.WriteLine("Server sent message");
_msgSent = true;
}
}
void CaptureCtrl_Started(object sender, EventArgs e)
{
StartClient();
}
private void StartClient()
{
try
{
LMNetSrc netSrc = new LMNetSrc();
netSrc.CheckConnection(_networkUrl, 0, 5000);
Marshal.ReleaseComObject(netSrc);
}
catch (COMException)
{
// could not connect
return;
}
_playCtrl.SourceFile = _networkUrl;
_pDemux = _playCtrl.GetSubObject(PlayObject.Splitter) as LMNetDmx;
if (_pDemux != null && _pDemux.AutoLiveTolerance < 5)
{
// reset the demux settings to defaults
_pDemux.ResetToDefaults();
// set the live tolerance setting to 5 seconds
// this will cause the playback to be smoother on jittery
// network connections -- although, the playback may lag
// behing the live stream when using a tolerance value > 0
_pDemux.AutoLiveTolerance = 5;
// set the output filename for recorded video
_pDemux.OutputFileName = _recordedVideoFile;
}
_serverAndClient.TestTimer.Interval = 100;
_serverAndClient.TestTimer.Tick += new EventHandler(PlayTimer_Tick);
_serverAndClient.TestTimer.Start();
}
void PlayTimer_Tick(object sender, EventArgs e)
{
_serverAndClient.TestTimer.Enabled = false;
if (_pDemux != null)
{
// read any messages here
string msg = _pDemux.ReadMessage();
// set the result to what we expect
if (msg == _testMessage)
{
_result = true;
Console.WriteLine("Client received message");
}
// get the bitrate
int bitRate = _pDemux.BitRate;
Console.WriteLine("Client bitrate = {0}", bitRate);
}
_serverAndClient.TestTimer.Enabled = true;
}
static class LEAD_VARS
{
public const string MediaDir = @"C:\LEADTOOLS23\Media";
}