前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >Linux平台x86_64|aarch64架构RTSP|RTMP直播播放器开发实践

Linux平台x86_64|aarch64架构RTSP|RTMP直播播放器开发实践

原创
作者头像
音视频牛哥
发布于 2025-03-28 03:46:25
发布于 2025-03-28 03:46:25
10400
代码可运行
举报
运行总次数:0
代码可运行

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模块,通常包括以下几个步骤:

  1. SDK初始化
  2. 创建和配置播放器窗口
  3. 设置参数、回调函数处理视频帧和事件
  4. 开始|停止播放流媒体
  5. 处理窗口事件

接下来我们将详细分析这些步骤。

1. SDK初始化

SDK的初始化是集成过程中的第一步。初始化SDK时,我们需要配置日志、播放器实例以及其他必要的设置。以下是代码中与初始化相关的部分:

代码语言:c
代码运行次数:0
运行
AI代码解释
复制
/*
 * 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(),我们可以为播放器实例做好准备。

2. 创建并配置播放器窗口

在Linux上,视频渲染通常通过X11窗口系统进行。在示例代码中,我们通过X11创建了主窗口和子窗口用于视频显示:

代码语言:c
代码运行次数:0
运行
AI代码解释
复制
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参数、注册回调函数来处理视频帧的渲染、事件的响应等。

代码语言:c
代码运行次数:0
运行
AI代码解释
复制
	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数据,用于视觉算法或相关处理:

代码语言:c
代码运行次数:0
运行
AI代码解释
复制
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
}

在这个回调中,我们可以对视频帧进行处理。例如,我们可以将视频帧保存为位图文件,或者将其显示在窗口上。

4. 开始播放流媒体

当一切准备就绪后,我们就可以开始播放流媒体。SDK提供了StartPlay接口来启动播放:

代码语言:c
代码运行次数:0
运行
AI代码解释
复制
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窗口事件,例如窗口大小调整、按键事件等。在示例代码中,我们通过XNextEventXPending来处理窗口事件,并在需要时调整渲染窗口的大小。

代码语言:c
代码运行次数:0
运行
AI代码解释
复制
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 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • ​Linux SmartPlayerSDK背景
  • 准备工作
  • 集成流程概述
  • 1. SDK初始化
  • 2. 创建并配置播放器窗口
  • 3. 参数设置和回调函数处理
  • 4. 开始播放流媒体
  • 5. 处理窗口事件
  • 总结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档