Linux(含x86_64架构和aarch64架构)的RTSP|RTMP直播播放SDK,是大牛直播SDK发布的一款用于Linux平台的视频播放器开发库,支持多种视频流协议,旨在提供低延时的流媒体播放和高质量的渲染。通过集成此SDK,开发者可以方便地在应用中实现视频播放功能。
功能设计如下:
首先,我们需要确保我们的开发环境已经具备了运行NT Linux Smart Player SDK所需的依赖。通常,你需要安装X11开发库(用于窗口管理和视频渲染),并确保你的Linux环境配置支持编译C++代码。
在Linux平台上使用大牛直播SDK的RTSP|RTMP直播播放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);
else
log_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()
,我们可以为播放器实例做好准备。
在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的窗口管理进行的。
在集成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_BITMAP
if (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);
else
g_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
}
在这个回调中,我们可以对视频帧进行处理。例如,我们可以将视频帧保存为位图文件,或者将其显示在窗口上。
当一切准备就绪后,我们就可以开始播放流媒体。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;
}
这段代码尝试启动视频流的播放。如果播放失败,程序将输出错误信息并进行清理。
为了保持窗口的响应性,我们需要处理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平台上实现高效超低延迟的视频播放功能。如果你有任何问题,欢迎跟我单独探讨。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
扫码关注腾讯云开发者
领取腾讯云代金券
Copyright © 2013 - 2025 Tencent Cloud. All Rights Reserved. 腾讯云 版权所有
深圳市腾讯计算机系统有限公司 ICP备案/许可证号:粤B2-20090059 深公网安备号 44030502008569
腾讯云计算(北京)有限责任公司 京ICP证150476号 | 京ICP备11018762号 | 京公网安备号11010802020287
Copyright © 2013 - 2025 Tencent Cloud.
All Rights Reserved. 腾讯云 版权所有