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 streams;
CComPtr stream;
CComPtr 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;
}
// set the stream path
hr = stream->put_Path(CComBSTR(path));
if(FAILED(hr))
goto error;
// setup to recompress, change this to VARIANT_TRUE if you want to use the device built-in compression
hr = stream->put_UseDeviceEncoding(VARIANT_FALSE);
if(FAILED(hr))
goto error;
// select video device
{
CComPtr 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 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 method of selection
if(index >= 0)
{
CComPtr 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 we can edit their properties
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 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 the audio is already encoded, the audio output settings are ignored
if(v != VARIANT_FALSE)
{
long count;
CComPtr 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 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 method of selection
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;
}