RTSP-плееры могут широко использоваться в сценариях с относительно высокими требованиями к задержке, таких как совместное управление интеллектуальными роботами или дронами, видеонаблюдение в реальном времени, удаленные видеоконференции, интернет-телевидение и т. д. Дистанционное управление и управление передачей потоковых мультимедийных данных достигается посредством управляющей сигнализации.
В этой статье в качестве примера используется проигрыватель прямых трансляций RTSP на платформе Windows из Daniu Live SDK, чтобы кратко представить, как интегрировать возможности прямой трансляции RTSP.
Заголовочный файл C++:
Заголовочный файл С#:
Связанные библиотеки:
Шаги интеграции:
1. Скопируйте библиотеку отладки/выпуска из каталога lib в каталог отладки или выпуска, соответствующий проекту, который необходимо интегрировать (убедитесь, что каталоги отладки/выпуска 32-битной/64-битной библиотеки соответствуют один к одному);
Каталог lib выглядит следующим образом:
2. Соответствующие заголовочные файлы CS и добавление проектов, которые необходимо интегрировать;
3. В проектах, требующих интеграции,Щелкните правой кнопкой мыши->Properties->
Application->Assembly имя, Daniu Live SDK авторизован в соответствии с названием приложения. Для неавторизованных версий измените его на «SmartPlayer» здесь. Если вам нужна авторизация, вы можете связаться с компанией напрямую;
4. Для официально авторизованной версии вам необходимо добавить код для установки лицензии перед вызовом интерфейса Init() (заполните соответствующий ключ и CID в соответствии с инструкциями в электронном письме официальной авторизованной версии):
C# SDK, добавьте следующий код перед NT.NTSmartPlayerSDK.NT_SP_Init:
NT.NTSmartPlayerSDK.NT_SP_SetSDKClientKey("xxxxxxxxxx", "xxxxxxxxxx", 0, IntPtr.Zero);
UInt32 isInited = NT.NTSmartPlayerSDK.NT_SP_Init(0, IntPtr.Zero);
if (isInited != 0)
{
MessageBox.Show("Ошибка вызова NT_SP_Init..");
return;
}
C++ SDK, добавьте следующий код перед player_api_.Init:
NT_SP_SetSDKClientKey("xxxxxxxxxx", "xxxxxxxxxx", 0, nullptr);
if ( NT_ERC_OK != player_api_.Init(0, NULL) )
{
return FALSE;
}
Вам необходимо добавить следующий код перед player_api_.Init:
// Установите путь к журналу (убедитесь, что каталог существует)
String log_path = "D:\\playerlog";
NTSmartLog.NT_SL_SetPath(log_path);
Если каталог существует и у него есть разрешение на запись файлов, после закрытия приложения в соответствующей папке будет создан файл smart_sdk.log.
NT_SP_Init: инициализация SDK, воспроизведение нескольких экземпляров, этот интерфейс нужно вызывать только один раз.
Если система используется в конкретной модельной среде, особенно в сценариях многоканального воспроизведения, и требуется жесткое декодирование, вы можете использовать следующие два набора интерфейсов, чтобы проверить, поддерживает ли система жесткое декодирование.
Примечание. Если производительность программного решения соответствует системным требованиям, обычно рекомендуется отдавать приоритет программному решению.
/*
* Проверьте, поддерживается ли жесткое декодирование H264.
* Возвращает NT_ERC_OK, если поддерживается
*/
[DllImport(@"SmartPlayerSDK.dll")]
public static extern UInt32 NT_SP_IsSupportH264HardwareDecoder();
/*
* Проверьте, поддерживается ли жесткое декодирование H265.
* Возвращает NT_ERC_OK, если поддерживается
*/
[DllImport(@"SmartPlayerSDK.dll")]
public static extern UInt32 NT_SP_IsSupportH265HardwareDecoder();
Если вам нужно использовать жесткое декодирование, просто вызовите следующий интерфейс:
NTSmartPlayerSDK.NT_SP_SetH264HardwareDecoder(player_handle_, is_support_h264_hardware_decoder_ ? 1 : 0, 0);
NTSmartPlayerSDK.NT_SP_SetH265HardwareDecoder(player_handle_, is_support_h265_hardware_decoder_ ? 1 : 0, 0);
NT_SP_Open: каждый раз, когда вызывается интерфейс Open, он соответствует одному экземпляру воспроизведения. Если необходимо воспроизвести несколько экземпляров, это соответствует нескольким обработчикам проигрывателя.
if (player_handle_ == IntPtr.Zero)
{
player_handle_ = new IntPtr();
UInt32 ret_open = NTSmartPlayerSDK.NT_SP_Open(out player_handle_, IntPtr.Zero, 0, IntPtr.Zero);
if (ret_open != 0)
{
player_handle_ = IntPtr.Zero;
MessageBox.Show("Ошибка вызова NT_SP_Open..");
return;
}
}
/*Идентификатор события*/
public enum NT_SP_E_EVENT_ID : uint
{
NT_SP_E_EVENT_ID_BASE = NTBaseCodeDefine.NT_EVENT_ID_SMART_PLAYER_SDK,
NT_SP_E_EVENT_ID_CONNECTING = NT_SP_E_EVENT_ID_BASE | 0x2, /*Соединение*/
NT_SP_E_EVENT_ID_CONNECTION_FAILED = NT_SP_E_EVENT_ID_BASE | 0x3, /*Соединение не удалось*/
NT_SP_E_EVENT_ID_CONNECTED = NT_SP_E_EVENT_ID_BASE | 0x4, /*Подключено*/
NT_SP_E_EVENT_ID_DISCONNECTED = NT_SP_E_EVENT_ID_BASE | 0x5, /*Отключение*/
NT_SP_E_EVENT_ID_NO_MEDIADATA_RECEIVED = NT_SP_E_EVENT_ID_BASE | 0x8, /*данные RTMP не получены*/
NT_SP_E_EVENT_ID_RTSP_STATUS_CODE = NT_SP_E_EVENT_ID_BASE | 0xB, /*rtsp status отчетность по коду, В настоящее время сообщается только о 401, param1 представляет статус code*/
/* Далее начните с 0x81*/
NT_SP_E_EVENT_ID_START_BUFFERING = NT_SP_E_EVENT_ID_BASE | 0x81, /*Начать буферизацию*/
NT_SP_E_EVENT_ID_BUFFERING = NT_SP_E_EVENT_ID_BASE | 0x82, /*Буферизация, param1 Представляет прогресс в процентах*/
NT_SP_E_EVENT_ID_STOP_BUFFERING = NT_SP_E_EVENT_ID_BASE | 0x83, /*Остановить буферизацию*/
NT_SP_E_EVENT_ID_DOWNLOAD_SPEED = NT_SP_E_EVENT_ID_BASE | 0x91, /*Скорость загрузки, param1 представляет скорость загрузки, единица измерения: (байт/с)*/
NT_SP_E_EVENT_ID_PLAYBACK_REACH_EOS = NT_SP_E_EVENT_ID_BASE | 0xa1, /*Игра заканчивается, прямая в трансляционных потоках этого события нет, оно есть только в потоках по требованию*/
NT_SP_E_EVENT_ID_RECORDER_REACH_EOS = NT_SP_E_EVENT_ID_BASE | 0xa2, /*Видео заканчивается, прямая трансляцияStream не имеет этого события, Только потоковая передача по запросу*/
NT_SP_E_EVENT_ID_PULLSTREAM_REACH_EOS = NT_SP_E_EVENT_ID_BASE | 0xa3, /*Потоковая передача завершается, прямая в трансляционных потоках этого события нет, оно есть только в потоках по требованию*/
NT_SP_E_EVENT_ID_DURATION = NT_SP_E_EVENT_ID_BASE | 0xa8, /*Продолжительность видео, если оно прямое трансляция, об этом не будет сообщено, если это по запросу, Если продолжительность видео можно получить из источника видео, сообщите об этом. param1 представляет продолжительность видео, единица измерения — миллисекунды (мс)*/
}
//video resolution callback
video_size_call_back_ = new SP_SDKVideoSizeCallBack(SP_SDKVideoSizeHandle);
NTSmartPlayerSDK.NT_SP_SetVideoSizeCallBack(player_handle_, IntPtr.Zero, video_size_call_back_);
Уведомление:При увеличении ширины и высоты видео или изменении окна рисования,Не забудьте вызвать NT_SP_OnWindowSize() для обновления.,Если этого не сделать, видео может быть размытым.
private void PlaybackWindowResized(Int32 width,Int32 height)
{
width_=width;
height_=height;
int left=playWnd.Left;
int top=playWnd.Top;
textBox_resolution.Text=width+"*"+height;
if(player_handle_==IntPtr.Zero)
{
return;
}
NTSmartPlayerSDK.NT_SP_OnWindowSize(player_handle_,playWnd.Width,playWnd.Height);
}
/*Определение формата изображения видеокадра*/
public enum NT_SP_E_VIDEO_FRAME_FORMAT : uint
{
NT_SP_E_VIDEO_FRAME_FORMAT_RGB32 = 1, // 32-битный формат RGB, r, g, b на каждую приходится по 8, Еще один байт зарезервирован, Формат байта памяти: bb gg rr xx, В основном для соответствия растровому изображению Windows, В режиме прямого порядка байтов используйте тип DWORD, старший бит — xx, за которым следует рр, gg, bb
NT_SP_E_VIDEO_FRAME_FORMAT_ARGB = 2, // 32-битный формат argb, формат байтов памяти: bb gg rr aa Этот тип соответствует растровому изображению Windows
NT_SP_E_VIDEO_FRAME_FROMAT_I420 = 3, // формат ЮВ420, Три компонента хранятся на трех гранях
}
//video timestamp callback
video_frame_ts_callback_ = new SP_SDKRenderVideoFrameTimestampCallBack(SP_SDKRenderVideoFrameTimestampCallBack);
NTSmartPlayerSDK.NT_SP_SetRenderVideoFrameTimestampCallBack(player_handle_, IntPtr.Zero, video_frame_ts_callback_);
В настоящее время существует очень мало ситуаций, когда D3D-рендеринг не поддерживается. Учитывая универсальность системы, мы выполняем обнаружение перед игрой. Конкретный интерфейс вызова выглядит следующим образом:
/*
* handle: игровая ручка
* hwnd: Для этого необходимо передать дескриптор окна, фактически используемый для рисования.
* is_support: Если поддерживается *is_support 1, Если не поддерживается, будет 0
* Успешный вызов интерфейса возвращает NT_ERC_OK.
*/
[DllImport(@"SmartPlayerSDK.dll")]
public static extern UInt32 NT_SP_IsSupportD3DRender(IntPtr handle, IntPtr hwnd, ref Int32 is_support);
В ситуациях, когда рисование D3D не поддерживается, устанавливаются данные обратного вызова YUV, и верхний уровень рисуется непосредственно в режиме GDI. Примечание. Эффективность рисования GDI низкая.
Int32 in_support_d3d_render = 0;
if (NT.NTBaseCodeDefine.NT_ERC_OK == NTSmartPlayerSDK.NT_SP_IsSupportD3DRender(player_handle_, playWnd.Handle, ref in_support_d3d_render))
{
if (1 == in_support_d3d_render)
{
is_support_d3d_render = true;
}
}
if (is_support_d3d_render)
{
is_gdi_render_ = false;
// Если поддерживается рисование d3d, используйте рисование D3D.
NTSmartPlayerSDK.NT_SP_SetRenderWindow(player_handle_, playWnd.Handle);
if (btn_check_render_scale_mode.Checked)
{
NTSmartPlayerSDK.NT_SP_SetRenderScaleMode(player_handle_, 1);
}
else
{
NTSmartPlayerSDK.NT_SP_SetRenderScaleMode(player_handle_, 0);
}
}
else
{
is_gdi_render_ = true;
playWnd.Visible = false;
// Если D3D не поддерживается, просто позвольте игроку выдать данные и нарисовать их с помощью GDI.
//video frame callback (YUV/RGB)
//формат, см. NT_SP_E_VIDEO_FRAME_FORMAT, если вам нужно перезвонить YUV, установите для него значение NT_SP_E_VIDEO_FRAME_FROMAT_I420
video_frame_call_back_ = new SP_SDKVideoFrameCallBack(SetVideoFrameCallBack);
NTSmartPlayerSDK.NT_SP_SetVideoFrameCallBack(player_handle_, (Int32)NT.NTSmartPlayerDefine.NT_SP_E_VIDEO_FRAME_FORMAT.NT_SP_E_VIDEO_FRAME_FORMAT_RGB32, IntPtr.Zero, video_frame_call_back_);
}
NT_SP_SetURL: поддерживает файлы rtsp/rtmp/local FLV (полный путь).
Установить обратный вызов PCM
NT_SP_SetIsOutputAudioDevice: определяет, воспроизводить ли звук. Это отличается от интерфейса отключения звука. Основная цель этого интерфейса — использовать его, когда пользователь устанавливает внешний интерфейс обратного вызова PCM и не хочет, чтобы SDK воспроизводил звук.
Для получения подробной информации обратитесь к InitCommonSDKParam() в исходном коде демо-версии:
Дополнительный интерфейс настройки перед воспроизведением
* is_report: переключатель отчетности, 1: отчетность таблицы. 0: означает отсутствие отчетности. Другие значения недействительны.
* report_interval: интервал отчетов (частота отчетов), единица измерения — секунды, минимальное значение — один раз в секунду. Если он меньше 1 и отчетность установлена, вызов завершится неудачно.
* Примечание. Если настроена отчетность, установите SetEventCallBack, а затем обработайте это событие в функции обратного вызова.
* Сообщаемое событие: NT_SP_E_EVENT_ID_DOWNLOAD_SPEED.
Интерфейс, который можно вызывать в реальном времени до и после воспроизведения.
NT_SP_StartPlay
Начните воспроизводить потоковые данные RTMP или RTSP.
NT_SP_CaptureImage
Используется проигрывателем для захвата воспроизводимого в данный момент изображения в реальном времени и сохранения изображения локально в формате PNG.
String name = capture_image_path_ + "\\" + DateTime.Now.ToString("hh-mm-ss") + ".png";
byte[] buffer1 = Encoding.Default.GetBytes(name);
byte[] buffer2 = Encoding.Convert(Encoding.Default, Encoding.UTF8, buffer1, 0, buffer1.Length);
byte[] buffer3 = new byte[buffer2.Length + 1];
buffer3[buffer2.Length] = 0;
Array.Copy(buffer2, buffer3, buffer2.Length);
IntPtr file_name_ptr = Marshal.AllocHGlobal(buffer3.Length);
Marshal.Copy(buffer3, 0, file_name_ptr, buffer3.Length);
capture_image_call_back_ = new SP_SDKCaptureImageCallBack(SDKCaptureImageCallBack);
UInt32 ret = NTSmartPlayerSDK.NT_SP_CaptureImage(player_handle_, file_name_ptr, IntPtr.Zero, capture_image_call_back_);
Marshal.FreeHGlobal(file_name_ptr);
if (NT.NTBaseCodeDefine.NT_ERC_OK == ret)
{
// Запрос на снимок экрана успешно отправлен
}
else if ((UInt32)NT.NTSmartPlayerDefine.SP_E_ERROR_CODE.NT_ERC_SP_TOO_MANY_CAPTURE_IMAGE_REQUESTS == ret)
{
// Уведомить пользователя о задержке
MessageBox.Show("Too many capture image requests!");
}
else
{
// Другие неудачи
}
NT_SP_SwitchURL
Быстрое переключение URL-адресов,Используется без разрушения всего экземпляра проигрывателя.,Переключайте URL-адрес воспроизведения в режиме реального времени.
NT_SP_SetUserDataCallBack
настраивать Обратный вызов пользовательских данных,Используется для получения информации о пользовательских данных, отправленной расширенным модулем SEI.,Если вы не сотрудничаете с нами в расширении SEI, отправьте DK,Этот интерфейс не нужно вызывать.
NT_SP_SetSEIDataCallBack
Установить обратный вызов видеосейла для получения Обратного вызов данных SEI,Если в данных потока нет SEI или данные SEI не подготовлены к обработке,Этот интерфейс не нужно вызывать.
NT_SP_StopPlay
Хватит воспроизводить потоковые данные RTMP или RTSP.
NT_SP_Close
После вызова интерфейса Close обработчик проигрывателя остается пустым.
if ( player_handle_ != IntPtr.Zero)
{
NTSmartPlayerSDK.NT_SP_Close(player_handle_);
player_handle_ = IntPtr.Zero;
}
NT_SP_UnInit
UnInit() — это последний интерфейс, вызываемый SDK. В среде с несколькими экземплярами его нужно вызывать только один раз.