Linux SmartPlayerSDK背景
Linux(含x86_64架构和aarch64架构)的RTSP|RTMP直播播放SDK,是大牛直播SDK发布的一款用于Linux平台的视频播放器开发库,支持多种视频流协议,旨在提供低延时的流媒体播放和高质量的渲染。通过集成此SDK,开发者可以方便地在应用中实现视频播放功能。
功能设计如下:
- [支持播放协议]高稳定、超低延迟、业内首屈一指的RTSP直播播放器SDK;
- [多实例播放]支持多实例播放;
- [事件回调]支持网络状态、buffer状态等回调;
- [视频格式]支持H.265、H.264,此外,还支持RTSP MJPEG播放;
- [音频格式]支持AAC/PCMA/PCMU;
- [H.264/H.265软解码]支持H.264/H.265软解;
- [RTSP模式设置]支持RTSP TCP/UDP模式设置;
- [RTSP TCP/UDP自动切换]支持RTSP TCP、UDP模式自动切换;
- [RTSP超时设置]支持RTSP超时时间设置,单位:秒;
- [RTSP 401认证处理]支持上报RTSP 401事件,如URL携带鉴权信息,会自动处理;
- [缓冲时间设置]支持buffer time设置;
- [首屏秒开]支持首屏秒开模式;
- [复杂网络处理]支持断网重连等各种网络环境自动适配;
- [实时静音]支持播放过程中,实时静音/取消静音;
- [实时音量调节]支持播放过程中实时调节音量;
- [实时快照]支持播放过程中截取当前播放画面;
- [渲染角度]支持0°,90°,180°和270°四个视频画面渲染角度设置;
- [渲染镜像]支持水平反转、垂直反转模式设置;
- [等比例缩放]支持图像等比例缩放绘制;
- [实时下载速度更新]支持当前下载速度实时回调(支持设置回调时间间隔);
- [解码前视频数据回调]支持H.264/H.265数据回调;
- [解码后视频数据回调]支持解码后YUV/RGB数据回调;
- [解码前音频数据回调]支持AAC/PCMA/PCMU数据回调;
- [扩展录像功能]支持和录像SDK组合使用;
- 支持x64_64架构、aarch64架构(需要glibc-2.21及以上版本的Linux系统, 需要libX11.so.6, 需要GLib–2.0, 需安装 libstdc++.so.6.0.21、GLIBCXX_3.4.21、 CXXABI_1.3.9);
准备工作
首先,我们需要确保我们的开发环境已经具备了运行NT Linux Smart Player SDK所需的依赖。通常,你需要安装X11开发库(用于窗口管理和视频渲染),并确保你的Linux环境配置支持编译C++代码。
集成流程概述
在Linux平台上使用大牛直播SDK的RTSP|RTMP直播播放SDK模块,通常包括以下几个步骤:
-
SDK初始化
-
创建和配置播放器窗口
-
设置参数、回调函数处理视频帧和事件
-
开始|停止播放流媒体
-
处理窗口事件
接下来我们将详细分析这些步骤。
1. SDK初始化
SDK的初始化是集成过程中的第一步。初始化SDK时,我们需要配置日志、播放器实例以及其他必要的设置。以下是代码中与初始化相关的部分:
/** simpleplayerdemo.cpp* Created by daniusdk.com*/
void NT_SDKLogInit()
{SmartLogAPI log_api;memset(&log_api, 0, sizeof(log_api));GetSmartLogAPI(&log_api);log_api.SetLevel(SL_INFO_LEVEL);if (cur_path[0] != 0 )log_api.SetPath((NT_PVOID)cur_path);elselog_api.SetPath((NT_PVOID)"./");
}bool NT_PlayerSDKInit(SmartPlayerSDKAPI& player_api)
{memset(&player_api, 0, sizeof(player_api));GetSmartPlayerSDKAPI(&player_api);auto ret = player_api.Init(0, nullptr);if (NT_ERC_OK != ret){fprintf(stderr, "player_api.Init failed!\n");return false;}else{fprintf(stdout, "player_api.Init ok!\n");}return true;
}
上述代码中的NT_SDKLogInit()
函数初始化了日志记录器,而NT_PlayerSDKInit()
则初始化了播放器SDK。通过调用player_api.Init()
,我们可以为播放器实例做好准备。
2. 创建并配置播放器窗口
在Linux上,视频渲染通常通过X11窗口系统进行。在示例代码中,我们通过X11创建了主窗口和子窗口用于视频显示:
Window CreateSubWindow(Display* display, int screen, Window parent)
{XWindowAttributes parent_win_att;XGetWindowAttributes(display, parent, &parent_win_att);XSetWindowAttributes swa;swa.border_pixel = WhitePixel(display, screen);swa.event_mask = KeyPressMask | StructureNotifyMask;return XCreateWindow(display, parent, 0, 0, parent_win_att.width-4, parent_win_att.height-4,2, parent_win_att.depth, InputOutput, parent_win_att.visual, CWEventMask | CWBorderPixel, &swa);
}
在这里,我们使用XCreateWindow
创建了一个子窗口,这个窗口将用于渲染视频流。主窗口和子窗口的创建和尺寸设置是基于X11的窗口管理进行的。
3. 参数设置和回调函数处理
在集成SDK时,我们需要设置player参数、注册回调函数来处理视频帧的渲染、事件的响应等。
player_api.SetEventCallBack(handle, nullptr, &NT_OnSDKEventHandle);player_api.SetVideoSizeCallBack(handle, nullptr, &NT_SDKVideoSizeHandle);player_api.SetReportDownloadSpeed(handle, 1, 5); // 5秒上报一次下载速度player_api.SetRtspTimeout(handle, 15);player_api.SetRtspAutoSwitchTcpUdp(handle, 1);player_api.SetBuffer(handle, 0); // 设置缓存player_api.SetIsOutputAudioDevice(handle, 1);player_api.SetAudioOutputLayer(handle, 0); // 使用pluse 或者 alsa播放, 两个可以选择一个//player_api.SetAudioVolume(handle, 100);player_api.SetURL(handle, player_url_); // 设置播放地址, rtsp或者rtmp地址//player_api.SetXDisplayName(handle, NULL);player_api.SetXScreenNumber(handle, screen);player_api.SetRenderXWindow(handle, sub_wid); // 设置绘制的X窗口player_api.SetRenderScaleMode(handle, 1); // 按比例绘制或者全填充player_api.SetRenderTextureScaleFilterMode(handle, 3); player_api.SetVideoFrameCallBackV2(handle, 1280, 720, 3, NT_SP_E_VIDEO_FRAME_FORMAT_RGB32, nullptr, &NT_SDK_SDKVideoFrameCallBack);player_api.SetFastStartup(handle, 1);player_api.SetLowLatencyMode(handle, 0);
如果需要回调yuv或rgb数据,用于视觉算法或相关处理:
extern "C" void NT_SDK_SDKVideoFrameCallBack(NT_HANDLE handle, NT_PVOID user_data, NT_UINT32 status,const NT_SP_VideoFrame* frame)
{if (!frame)return;fprintf(stdout, "OnSDKVideoFrameCallBack handle:%p frame:%p, timestamp:%llu\n", handle, frame, frame->timestamp_);#if NEED_SAVE_BITMAPif (NT_SP_E_VIDEO_FRAME_FORMAT_RGB32 == frame->format_|| NT_SP_E_VIDEO_FRAME_FORMAT_ARGB == frame->format_) {struct timeval tv;if (gettimeofday(&tv, nullptr) != 0) {fprintf(stderr, "save bitmap file call gettimeofday failed");return;}uint64_t local_time_us = tv.tv_sec*UINT64_C(1000000) + tv.tv_usec;char file_name[128] = { 0 };sprintf(file_name, "./outbitmaps/%llu.bmp", (unsigned long long)local_time_us);if (!save_bitmap_file(frame->width_, frame->height_, frame->plane0_, frame->stride0_, frame->stride0_*frame->height_, file_name))fprintf(stderr, "save bitmap file failed, name:%s", file_name);elseg_bitmap_file_names_.emplace_back(file_name);while (g_bitmap_file_names_.size() > 32) {remove(g_bitmap_file_names_.front().c_str());g_bitmap_file_names_.pop_front();}}#endif // NEED_SAVE_BITMAP
}
在这个回调中,我们可以对视频帧进行处理。例如,我们可以将视频帧保存为位图文件,或者将其显示在窗口上。
4. 开始播放流媒体
当一切准备就绪后,我们就可以开始播放流媒体。SDK提供了StartPlay
接口来启动播放:
if (NT_ERC_OK != player_api.StartPlay(handle))
{player_api.Close(handle);handle = nullptr;fprintf(stderr, "player_api.StartPlay failed!\n");return 0;
}
这段代码尝试启动视频流的播放。如果播放失败,程序将输出错误信息并进行清理。
5. 处理窗口事件
为了保持窗口的响应性,我们需要处理X11窗口事件,例如窗口大小调整、按键事件等。在示例代码中,我们通过XNextEvent
和XPending
来处理窗口事件,并在需要时调整渲染窗口的大小。
while (true)
{while (MY_X11_Pending(display, 10)){XEvent xev;memset(&xev, 0, sizeof(xev));XNextEvent(display, &xev);if (xev.type == KeyPress){if (xev.xkey.keycode == XKeysymToKeycode(display, XK_Escape)){// 处理按下ESC键事件break;}}}
}
通过上述事件循环,程序能够响应用户输入(例如ESC键退出)并调整窗口的显示。
总结
集成大牛直播SDK的RTSP|RTMP播放模块到Linux应用程序中,关键步骤包括初始化SDK、创建并配置播放窗口、注册回调函数处理视频帧和事件、以及启动播放流媒体。通过这些步骤,开发者能够在Linux平台上实现高效超低延迟的视频播放功能。如果你有任何问题,欢迎跟我单独探讨。