Windows平台RTMP/RTSP播放器窗口添加OSD叠加文字效果

2023-10-31 05:20

本文主要是介绍Windows平台RTMP/RTSP播放器窗口添加OSD叠加文字效果,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

转载自:https://zhuanlan.zhihu.com/p/353750409

Windows平台RTMP/RTSP播放器窗口添加OSD叠加文字效果

牛哥

牛哥

大牛直播SDK联合创始人,daniusdk.com

好多开发者在做Windows平台特别是单屏多画面显示时,希望像监控摄像机一样,可以在播放画面添加OSD台标,以实现字符叠加效果,大多开发者可很轻松的实现以上效果,针对此,本文以大牛直播SDK (Github)的Windows平台demo为例,简单介绍下具体实现:

Windows平台RTMP播放器、RTSP播放器C++ demo

Windows平台C++的demo,以录像过程为例,动态在左上角显示个闪动的图标+当前时间,具体效果如下:

核心代码

std::shared_ptr<nt_argb_image_logo> CSmartPlayerDlg::MakeLogo()
{std::shared_ptr<nt_argb_image_logo> logo_image;if (!is_init_gdi_plus_ok_)return logo_image;if (!recoder_image_){static bool is_load_image_failed = false;if (!is_load_image_failed){recoder_image_.reset(Gdiplus::Image::FromFile(_T("red_circle.png")));if (recoder_image_ && Gdiplus::Ok != recoder_image_->GetLastStatus()){is_load_image_failed = true;recoder_image_.reset();}}}is_has_recoder_image_ = !is_has_recoder_image_;if (!recoder_image_){is_has_recoder_image_ = false;}if (m_hWnd == nullptr || !::IsWindow(m_hWnd))return logo_image;if (cur_logo_font_name_.empty()){cur_logo_font_name_ = FindLogoFontName();}if (cur_logo_font_name_.empty()){return logo_image;}Gdiplus::FontFamily font_family(cur_logo_font_name_.c_str());if (!font_family.IsAvailable()){return logo_image;}Gdiplus::Font font(&font_family, 10, Gdiplus::FontStyleBold, Gdiplus::Unit::UnitPoint);if (!font.IsAvailable()){return logo_image;}// 白色Gdiplus::SolidBrush solid_brush(Gdiplus::Color(255, 255, 255));Gdiplus::Graphics  graphics(m_hWnd);if (Gdiplus::Ok != graphics.GetLastStatus()){return logo_image;}int recoder_image_w = 18;int recoder_image_h = 18;if (recoder_image_){recoder_image_w = recoder_image_->GetWidth();recoder_image_h = recoder_image_->GetHeight();}auto image_w = recoder_image_w + 2 + 5;auto image_h = recoder_image_h + 5 + 5;graphics.SetTextRenderingHint(Gdiplus::TextRenderingHint::TextRenderingHintClearTypeGridFit);auto cur_time_str = MakeCurTimerStr();Gdiplus::RectF bounding_box(0, 0, 0, 0);graphics.MeasureString(cur_time_str.c_str(), -1, &font, Gdiplus::PointF(0, 0), &bounding_box);Gdiplus::SizeF text_size(0, 0);bounding_box.GetSize(&text_size);image_w += (int)text_size.Width;image_h = image_h > ((int)text_size.Height) ? image_h : ((int)text_size.Height);image_w += 2;image_h += 2;image_w = ByteAlign(image_w, 4);image_h = ByteAlign(image_h, 4);Gdiplus::Bitmap   bitmap(image_w, image_h, PixelFormat32bppARGB);if (Gdiplus::Ok != bitmap.GetLastStatus()){return logo_image;}Gdiplus::Graphics g(&bitmap);if (Gdiplus::Ok != g.GetLastStatus()){return logo_image;}int r_left = 2;int r_top = (image_h / 2) - (recoder_image_h / 2);r_top -= 1;if (is_has_recoder_image_){g.DrawImage(recoder_image_.get(), r_left, r_top);}r_left += recoder_image_w;r_left += 5;r_top = (image_h / 2) - (text_size.Height / 2);g.DrawString(cur_time_str.c_str(), -1, &font, Gdiplus::PointF(r_left, r_top), &solid_brush);Gdiplus::BitmapData locked_bitmapData;if (Gdiplus::Ok == bitmap.LockBits(nullptr, Gdiplus::ImageLockModeRead, PixelFormat32bppARGB, &locked_bitmapData)){auto buffer_size = locked_bitmapData.Stride * locked_bitmapData.Height;std::unique_ptr<NT_BYTE[]> buffer(new NT_BYTE[buffer_size]);if (buffer){logo_image = std::make_shared<nt_argb_image_logo>(locked_bitmapData.Width, locked_bitmapData.Height);logo_image->stride_ = locked_bitmapData.Stride;memcpy(buffer.get(), locked_bitmapData.Scan0, buffer_size);logo_image->data_.swap(buffer);}bitmap.UnlockBits(&locked_bitmapData);}return logo_image;
}

Windows平台RTMP播放器、RTSP播放器C# demo

Windows平台C#的demo,添加了“设置台标”选择框,在player窗口左上角显示“叠加字符展示”,具体内容、坐标可自定义,具体效果如下:

核心代码

        //设置OSD文本private void DrawOSD(string draw_text){// gdi 绘制的话,文本请自己绘制if (is_gdi_render_)return;if (player_handle_ == IntPtr.Zero)return;if (draw_text == null || draw_text.Length < 1){NTSmartPlayerSDK.NT_SP_SetRenderARGBLogo(player_handle_, IntPtr.Zero, 0, 0, 0, 0, 0, 0, 0);return;}Graphics graphics = this.CreateGraphics();SolidBrush solid_brush = new SolidBrush(Color.FromArgb(255, 255, 255));graphics.TextRenderingHint = System.Drawing.Text.TextRenderingHint.ClearTypeGridFit;SizeF text_size = new SizeF();text_size = graphics.MeasureString(draw_text, this.Font);int image_w = (int)text_size.Width + 4;int image_h = (int)text_size.Height + 4;image_w = (int)ByteAlign((UInt32)image_w, 4);image_h = (int)ByteAlign((UInt32)image_h, 4);Bitmap bmp = new Bitmap(image_w, image_h, System.Drawing.Imaging.PixelFormat.Format32bppArgb);Graphics g = Graphics.FromImage(bmp);g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.ClearTypeGridFit;float left = image_w / 2 - text_size.Width / 2;float top = image_h / 2 - text_size.Height / 2;g.DrawString(draw_text, this.Font, solid_brush, left, top);Rectangle rect = new Rectangle(0, 0, bmp.Width, bmp.Height);System.Drawing.Imaging.BitmapData bmp_data = bmp.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadOnly, bmp.PixelFormat);IntPtr ptr = bmp_data.Scan0;int strdie = Math.Abs(bmp_data.Stride);NTSmartPlayerSDK.NT_SP_SetRenderARGBLogo(player_handle_, ptr, strdie, bmp_data.Width,bmp_data.Height, 6, 6, bmp_data.Width, bmp_data.Height);// Unlock the bits.bmp.UnlockBits(bmp_data);}

注意,如果GDI模式下,我们数据回调到上层绘制的,这样加起来更简单:

            if (btn_check_add_osd.Checked){string draw_text = "叠加字符展示";Graphics graphics = this.CreateGraphics();SolidBrush solid_brush = new SolidBrush(Color.FromArgb(255, 255, 255));graphics.TextRenderingHint = System.Drawing.Text.TextRenderingHint.ClearTypeGridFit;g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.ClearTypeGridFit;float left = playWnd.Left + 4;float top = playWnd.Top + 4;g.DrawString(draw_text, this.Font, solid_brush, left, top);}

感兴趣的开发者可自行尝试。

发布于 03-01

这篇关于Windows平台RTMP/RTSP播放器窗口添加OSD叠加文字效果的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/313086

相关文章

windows系统下shutdown重启关机命令超详细教程

《windows系统下shutdown重启关机命令超详细教程》shutdown命令是一个强大的工具,允许你通过命令行快速完成关机、重启或注销操作,本文将为你详细解析shutdown命令的使用方法,并提... 目录一、shutdown 命令简介二、shutdown 命令的基本用法三、远程关机与重启四、实际应用

Windows自动化Python pyautogui RPA操作实现

《Windows自动化PythonpyautoguiRPA操作实现》本文详细介绍了使用Python的pyautogui库进行Windows自动化操作的实现方法,文中通过示例代码介绍的非常详细,对大... 目录依赖包睡眠:鼠标事件:杀死进程:获取所有窗口的名称:显示窗口:根据图片找元素:输入文字:打开应用:依

Python使用Pandas库将Excel数据叠加生成新DataFrame的操作指南

《Python使用Pandas库将Excel数据叠加生成新DataFrame的操作指南》在日常数据处理工作中,我们经常需要将不同Excel文档中的数据整合到一个新的DataFrame中,以便进行进一步... 目录一、准备工作二、读取Excel文件三、数据叠加四、处理重复数据(可选)五、保存新DataFram

javafx 如何将项目打包为 Windows 的可执行文件exe

《javafx如何将项目打包为Windows的可执行文件exe》文章介绍了三种将JavaFX项目打包为.exe文件的方法:方法1使用jpackage(适用于JDK14及以上版本),方法2使用La... 目录方法 1:使用 jpackage(适用于 JDK 14 及更高版本)方法 2:使用 Launch4j(

windows端python版本管理工具pyenv-win安装使用

《windows端python版本管理工具pyenv-win安装使用》:本文主要介绍如何通过git方式下载和配置pyenv-win,包括下载、克隆仓库、配置环境变量等步骤,同时还详细介绍了如何使用... 目录pyenv-win 下载配置环境变量使用 pyenv-win 管理 python 版本一、安装 和

bat脚本启动git bash窗口,并执行命令方式

《bat脚本启动gitbash窗口,并执行命令方式》本文介绍了如何在Windows服务器上使用cmd启动jar包时出现乱码的问题,并提供了解决方法——使用GitBash窗口启动并设置编码,通过编写s... 目录一、简介二、使用说明2.1 start.BAT脚本2.2 参数说明2.3 效果总结一、简介某些情

基于Redis有序集合实现滑动窗口限流的步骤

《基于Redis有序集合实现滑动窗口限流的步骤》滑动窗口算法是一种基于时间窗口的限流算法,通过动态地滑动窗口,可以动态调整限流的速率,Redis有序集合可以用来实现滑动窗口限流,本文介绍基于Redis... 滑动窗口算法是一种基于时间窗口的限流算法,它将时间划分为若干个固定大小的窗口,每个窗口内记录了该时间

Python使用pysmb库访问Windows共享文件夹的详细教程

《Python使用pysmb库访问Windows共享文件夹的详细教程》本教程旨在帮助您使用pysmb库,通过SMB(ServerMessageBlock)协议,轻松连接到Windows共享文件夹,并列... 目录前置条件步骤一:导入必要的模块步骤二:配置连接参数步骤三:实例化SMB连接对象并尝试连接步骤四:

流媒体平台/视频监控/安防视频汇聚EasyCVR播放暂停后视频画面黑屏是什么原因?

视频智能分析/视频监控/安防监控综合管理系统EasyCVR视频汇聚融合平台,是TSINGSEE青犀视频垂直深耕音视频流媒体技术、AI智能技术领域的杰出成果。该平台以其强大的视频处理、汇聚与融合能力,在构建全栈视频监控系统中展现出了独特的优势。视频监控管理系统EasyCVR平台内置了强大的视频解码、转码、压缩等技术,能够处理多种视频流格式,并以多种格式(RTMP、RTSP、HTTP-FLV、WebS

综合安防管理平台LntonAIServer视频监控汇聚抖动检测算法优势

LntonAIServer视频质量诊断功能中的抖动检测是一个专门针对视频稳定性进行分析的功能。抖动通常是指视频帧之间的不必要运动,这种运动可能是由于摄像机的移动、传输中的错误或编解码问题导致的。抖动检测对于确保视频内容的平滑性和观看体验至关重要。 优势 1. 提高图像质量 - 清晰度提升:减少抖动,提高图像的清晰度和细节表现力,使得监控画面更加真实可信。 - 细节增强:在低光条件下,抖