共计 2446 个字符,预计需要花费 7 分钟才能阅读完成。
SkeyePlayer RTSP Windows 播放器新增 OSD 字幕叠加接口办法,这个接口和码率信息显示接口办法相似,都是调用 FFRender 库的接口实现的多 OSD 叠加,上面解说下该办法的调用和注意事项;
OSD 叠加办法申明如下:
LIB_SkeyePLAYER_API int SkeyePlayer_ShowOSD(int channelId, int show, Skeye_PALYER_OSD osd);
其中,channelId:播放器通道 ID,标识以后的播放器实例;
show:标识是否显示 OSD 叠加,0= 不事实 1= 显示
osd:显示信息填充构造,定义如下:
typedef struct tagSkeye_PALYER_OSD
{char stOSD[1024]; //OSD 字幕信息
DWORD alpha; // 通明通到 0 -255 0= 通明 255= 齐全不通明
DWORD color; //RGB(0xf9,0xf9,0xf9)
DWORD shadowcolor; //OSD 背景色彩 RGB(0x4d,0x4d,0x4d) 全为 0 背景通明
RECT rect; //OSD 基于图像右上角显示区域
int size; //OSD 字体的大小
}Skeye_PALYER_OSD;
留神:osd 字幕叠加通过”\r\n“结束符进行换行,一行的长度不能超过 128 个字节,总的 OSD 叠加不能超过 1024 个字节。其中 OSD 大小设置只有 D3D 渲染模式能力失效;
咱们曾经对 OSD 叠加的接口有所理解,上面咱们来写一段调用代码来看看成果:
//OSD Example
Skeye_PALYER_OSD osd;
osd.alpha = 255;
osd.size = 35;
osd.color = RGB(255,0,255);
osd.rect.left = 10;
osd.rect.right = 5000;
osd.rect.top = 100;
osd.rect.bottom = 800;
osd.shadowcolor = RGB(0,0,0);
char* ss = "这是 SkeyePlayer-RTSP-Win 播放器 \r\n 的字幕叠加接口的成果!!!\r\n 以 \"\\r\\n\"为换行完结符号 \r\n 留神:每行的长度不能超过 128 个字节 \r\n 总的 OSD 长度不能超过 1024 个字节";
strcpy(osd.stOSD ,ss);
SkeyePlayer_ShowOSD(m_ChannelId, 1, osd);
如上代码段所示,次要对 OSD_PLAYER_OSD 构造的参数进行设置,就能失去咱们想要的成果,如下图所示:
(1)GDI 显示
[外链图片转存中 …(img-6MyHsd96-1652407820539)]
(2)D3D 显示
[外链图片转存中 …(img-3J1hL1gx-1652407820541)]
比照两种形式的 OSD 叠加还是有所区别的,D3D 的因为有硬件加速,咱们能够看到 OSD 叠加更加清晰而且效率也高,OSD 则是绝对毛糙,而且在原 FFRender 库中 GDI 接口是不反对换行的,所以,咱们须要做一些技术解决,如下段代码所示:
std::string sOSD = pThread->osd.stOSD;
while (!sOSD.empty())
{char* subOSD = (char*)sOSD.c_str();
int nOSDLen = sOSD.length();
int sublen = 0;
int nEofPos = sOSD.find("\r\n");
if (nEofPos>127)
{subOSD[128] = 0;
sublen = 128;
}
if (pThread->renderFormat == GDI_FORMAT_RGB24)
{CopyRect(&osd[osdLines].rect, &pThread->osd.rect);
osd[osdLines].rect.top = pThread->osd.rect.top+40*osdLines;
osd[osdLines].rect.bottom = pThread->osd.rect.bottom+40*osdLines;
if (nEofPos>=0)
{subOSD[nEofPos] = 0;
sublen = nEofPos;
}
}
else
{CopyRect(&osd[osdLines].rect, &pThread->osd.rect);
osd[osdLines].rect.top = pThread->osd.rect.top+pThread->osd.size*osdLines;
osd[osdLines].rect.bottom = pThread->osd.rect.bottom+pThread->osd.size*osdLines;
if (nEofPos>=0)
{subOSD[nEofPos] = 0;
sublen = nEofPos;
}
}
MByteToWChar(subOSD, osd[osdLines].string, sizeof(osd[osdLines].string)/sizeof(osd[osdLines].string[0]));
osd[osdLines].color = pThread->osd.color;
osd[osdLines].shadowcolor = pThread->osd.shadowcolor;
osd[osdLines].alpha = pThread->osd.alpha;
osdLines++;
if (nEofPos>=0)
{sOSD = subOSD+nEofPos+2;}
else
{sOSD = "";}
}
简略形容下上段代码,即:通过查找“\r\n”结束符作为一条 OSD 信息,而一条 OSD 又不能超过 128 个字节进行换行,换行行高则通过 size 来确定,因为 GDI 不反对 size 大小的设定,所以咱们给了个固定值 40,当然为了紧凑点或者行间距大点还能够调整。
此外,目前版本的 SkeyePalyer RTSP Windows 播放器只反对软解码的 OSD 叠加显示,硬解码目前还不反对。