Create or Replace Live Stream Example for C++
HRESULT CreateOrReplaceLiveStream(IltmsServer* server, LPCTSTR path, LPCTSTR videodevice, LPCTSTR audiodevice)
{
HRESULT hr;
long streamcount;
long streamindex;
CComPtr<IltmsLiveStreams> streams;
CComPtr<IltmsLiveStream> stream;
CComPtr<IltmsLiveStreamDevConfig> devconfig;
hr = server->GetLiveStreams(&streams);
if (FAILED(hr))
goto error;
// search for existing stream with same path
hr = streams->get_Count(&streamcount);
if (FAILED(hr))
goto error;
for (streamindex = 0; streamindex < streamcount; streamindex++)
{
CComBSTR v;
hr = streams->GetLiveStream(streamindex, &stream);
if (FAILED(hr))
goto error;
hr = stream->get_Path(&v);
if (FAILED(hr))
goto error;
if (CStringW(path).CompareNoCase(v) == 0)
break;
stream = NULL;
}
if (!stream)
{
// create a new stream
streamindex = -1;
hr = streams->CreateLiveStream(&stream);
if (FAILED(hr))
goto error;
}
// enable the stream
hr = stream->put_Enable(VARIANT_TRUE);
if (FAILED(hr))
goto error;
// enable hardware decoding
hr = stream->put_QSVDecoding(VARIANT_TRUE);
if (FAILED(hr))
goto error;
hr = stream->put_CUDADecoding(VARIANT_TRUE);
if (FAILED(hr))
goto error;
// set up activate-on-demand
hr = stream->put_ActivateOnDemand(VARIANT_TRUE);
if (FAILED(hr))
goto error;
// set activate-on-demand idle timeout to 5 minutes
hr = stream->put_IdleTimeOut(300000);
if (FAILED(hr))
goto error;
// set the stream's path
hr = stream->put_Path(CComBSTR(path));
if (FAILED(hr))
goto error;
// set up for recompressing. change this to VARIANT_TRUE to use the device's built-in compression
hr = stream->put_UseDeviceEncoding(VARIANT_FALSE);
if (FAILED(hr))
goto error;
// select video device
{
CComPtr<IltmsDevices> devices;
long index = -1;
stream->get_VideoDevices(&devices);
if (videodevice)
{
hr = devices->Find(CComBSTR(videodevice), &index);
if (FAILED(hr))
goto error;
}
hr = devices->put_Selection(index);
if (FAILED(hr))
goto error;
}
// select audio device
{
CComPtr<IltmsDevices> devices;
long index = -1;
stream->get_AudioDevices(&devices);
if (audiodevice)
{
hr = devices->Find(CComBSTR(audiodevice), &index);
if (FAILED(hr))
goto error;
}
#if 1
hr = devices->put_Selection(index);
if (FAILED(hr))
goto error;
#else
// alternative selection method
if (index >= 0)
{
CComPtr<IltmsDevice> device;
hr = devices->Item(index, &device);
if (FAILED(hr))
goto error;
hr = device->put_Selected(VARIANT_TRUE);
if (FAILED(hr))
goto error;
}
else
{
hr = devices->put_Selection(-1);
if (FAILED(hr))
goto error;
}
#endif
}
// lock the devices so their properties can be edited
hr = stream->get_DeviceConfig(&devconfig);
if (FAILED(hr))
goto error;
hr = devconfig->LockDevices();
if (FAILED(hr))
goto error;
// show the main video device property page, if available
// see ltms.h ltmsLiveStreamDlg enumeration for more property page options
{
VARIANT_BOOL v;
hr = devconfig->HasDialog(ltmsLiveStreamDlg_VideoDevice, &v);
if (FAILED(hr))
goto error;
if (v != VARIANT_FALSE)
{
hr = devconfig->ShowDialog(ltmsLiveStreamDlg_VideoDevice, NULL);
if (FAILED(hr))
goto error;
}
}
// show the main audio device property page, if available
// see ltms.h ltmsLiveStreamDlg enumeration for more property page options
{
VARIANT_BOOL v;
hr = devconfig->HasDialog(ltmsLiveStreamDlg_AudioDevice, &v);
if (FAILED(hr))
goto error;
if (v != VARIANT_FALSE)
{
hr = devconfig->ShowDialog(ltmsLiveStreamDlg_AudioDevice, NULL);
if (FAILED(hr))
goto error;
}
}
// set up output video
{
VARIANT_BOOL v;
hr = devconfig->get_IsVideoEncoded(&v);
if (FAILED(hr))
goto error;
// the video is already encoded, the video output settings are ignored
if (v != VARIANT_FALSE)
{
hr = stream->put_UseVideoInputSize(VARIANT_TRUE);
if (FAILED(hr))
goto error;
// if UseVideoInputSize is VARIANT_TRUE, then the width and height are ignored
hr = stream->put_VideoWidth(320);
if (FAILED(hr))
goto error;
hr = stream->put_VideoHeight(240);
if (FAILED(hr))
goto error;
hr = stream->put_UseVideoInputFrameRate(VARIANT_TRUE);
if (FAILED(hr))
goto error;
// if UseVideoInputFrameRate is VARIANT_TRUE, then the frame rate is ignored
hr = stream->put_VideoFrameRate(29.97);
if (FAILED(hr))
goto error;
hr = stream->put_VideoBitRate(700000);
if (FAILED(hr))
goto error;
hr = stream->put_QSVAcceleration(VARIANT_TRUE);
if (FAILED(hr))
goto error;
hr = stream->put_CUDAAcceleration(VARIANT_TRUE);
if (FAILED(hr))
goto error;
}
}
// set up output audio
{
VARIANT_BOOL v;
hr = devconfig->get_IsAudioEncoded(&v);
if (FAILED(hr))
goto error;
// the audio is already encoded, the audio output settings are ignored
if (v != VARIANT_FALSE)
{
long count;
CComPtr<IltmsAudioTypes> audiotypes;
hr = stream->get_AudioTypes(&audiotypes);
if (FAILED(hr))
goto error;
hr = audiotypes->get_Count(&count);
if (FAILED(hr))
goto error;
for (long index = 0; index < count; index++)
{
CComPtr<IltmsAudioType> audiotype;
long channels;
long bitrate;
long samplerate;
hr = audiotypes->Item(index, &audiotype);
if (FAILED(hr))
goto error;
hr = audiotype->get_Channels(&channels);
if (FAILED(hr))
goto error;
hr = audiotype->get_BitRate(&bitrate);
if (FAILED(hr))
goto error;
hr = audiotype->get_SampleRate(&samplerate);
if (FAILED(hr))
goto error;
if (channels == 2 && bitrate == 192000 && samplerate == 44100)
{
#if 1
audiotype->put_Selected(VARIANT_TRUE);
#else
// alternative selection method
audiotypes->put_Selection(index);
#endif
break;
}
}
}
}
// set up output fragment size
hr = stream->put_MinimumFragmentDuration(2.0);
if (FAILED(hr))
goto error;
// add or replace stream
if (streamindex < 0)
hr = streams->AddLiveStream(stream);
else
hr = streams->SetLiveStream(streamindex, stream);
if (FAILED(hr))
goto error;
hr = server->SetLiveStreams(streams);
if (FAILED(hr))
goto error;
error:
if (devconfig)
devconfig->UnlockDevices();
return hr;
}