美文网首页
用Duilib制作我的视频播放器 —— WODPlayer

用Duilib制作我的视频播放器 —— WODPlayer

作者: 天下第九九八十一 | 来源:发表于2023-02-07 15:33 被阅读0次

主要需求:书签,快速seek,字幕,点击字幕查词。

为何不用potplayer?太卡,技术看不上,竟然保存同时设置和二进制图片文件到ini文件或注册表,一点不绿色。

播放组件,得的到的有三种:

  • MFPlayer,官方框架但解码器较少。
  • VLCPlayer,首次启动较慢。
  • 迅雷播放组件,闭源,存在BUG。最近试出一个导黑屏死机的BUG,复现三次。seek快但是不精准。

整合这些到一个应用。

可以切换核心的视频播放器见过吗。

然后界面,选duilib,站原生。

WODPlayer 控件简史

  • 2022年集成了MFPlayer、VLCPlayer、迅雷Player,各有优缺点
  • 控件有进度条、底部按钮,最初用魔改的wine代码实现,分别是trackbar.c和tabbar.c。
  • 2023 年重构,实现插件接口,分出动态链接库项目,扩展后可以接上任何播放器组件。
  • 替换窗口控件为无窗口自绘控件。进度条很简单,用gdi+绘制两个条一个圆,记得开启平滑画笔,再绘制些简单的阴影。
  • 时间进度条用定时器同步。
  • 原生按钮效果也不难,背景绘制一个淡蓝色方块和边框,前景绘制图标,点击、悬浮于按钮时,改变方块色、边框色,偏移前景图标,复刻原生外观。
  • 按钮点击事件仍然通过发送WM_COMMAND处理,装作原生控件。数字id在resource.h中手动指定然后写在布局xml里。

WODPlayer 无边框镂空窗口的曲折之路

不建议制作无边框窗口,坑太多。

但 WODPlayer 必须要无边框,因为有个需求,想让界面部分镂空:

为什么 WODPlayer 需要部分镂空

image (8).png

如果不镂空,那么视频两边出现黑边。

一旦开启系统级别的反色滤镜,黑边立马变成白边,非常刺目。

image (5).png

最大化和全屏尤为明显。

windows 平台半透明或镂空窗口(layered)有以下特性:

  • 同一窗口只能二选一,不能同时开启
  • 半透明只能完全半透明,子窗口无法取消,无法局部不透明。
  • 镂空透过指定关键颜色,扣除法实现,镂空部分可以点击到窗体后面

为什么部分镂空需要无边框

  • 发现普通窗口镂空存在BUG,当子窗口部分镂空时(WM_PAINT绘制透明关键色),则父窗口在子窗口底部下方区域50像素左右的高度失去点击事件的响应。猜测是将此部分区域当作caption标题栏处理了。

镂空部分下方区域,窗口失去焦点,失去响应。

抬高绘制区域50像素,则又可以响应。

screenshots.gif

这个应该不是duilib的问题。测试时已经注释掉相关代码(WM_NCHITTEST)。

无边框窗口如何实现窗口缩放?

duilib 通过指定window sizebox属性在窗体四边指定区域,响应 WM_NCHITTEST 事件,判断鼠标位置,在四个边上返回 HTTOPLEFT 等系统预设值,代表四个边或四个角,与普通窗口差不多。

但此时又出现坑点了。这也是为什么我不推荐无边框窗体的原因之一,问题太多。

问题就是 sizebox 属性只适合单窗口,如果duilib主窗口嵌套其他duilib窗口、嵌套其他控件窗口如播放器窗口、浏览器窗口等,则四边区域无法响应 WM_NCHITTEST 事件,完全收不到,主消息循环也拦截不到,除非四边空出一段距离。子窗口倒是可以接收与响应 WM_NCHITTEST 事件,然而一旦响应,则变成子窗口在父窗口内部的缩放改变大小。

所以需要其他方案,参考csdn收藏的一篇:Win32无边框窗体拖动、改变大小(WM_SYSCOMMAND方式),记录较为详细。可以在鼠标点击某些区域的时候,发送系统消息,触发窗口移动及缩放。

无边框窗口为何没有最大化、最小化动画

像百度网盘这种窗口,最大化、最小化没有动画,右上角按钮极小,属于负面教材。

无边框窗口之所以在最大化、最小化的时候没有动画,可能是窗口样式扣除了 WS_CAPTION 导致的。见以下代码,如果在窗口建立之前扣除没事,建立之后再抠出就会失去动画。

HWND CWindowWnd::Create(HWND hwndParent, LPCTSTR pstrName, DWORD dwStyle, DWORD dwExStyle, int x, int y, int cx, int cy, bool center, HMENU hMenu)
{
    // 调整窗口样式
    WindowImplBase* _this = dynamic_cast<WindowImplBase*>(this);
    if (_this)
    {
        if(_this->IsWindowLess()) dwStyle &= ~WS_CAPTION;
        else _this = NULL;
        dwStyle |= WS_CLIPSIBLINGS | WS_CLIPCHILDREN;
    }
    if( GetSuperClassName() != NULL && !RegisterSuperclass() ) return NULL;
    if( GetSuperClassName() == NULL && !RegisterWindowClass() ) return NULL;
    LPWSTR lpClassName = (LPWSTR)GetWindowClassName();
    LPWSTR lpName = (LPWSTR)pstrName;
    m_hWnd = ::CreateWindowEx(dwExStyle, lpClassName, lpName, dwStyle, x, y, cx, cy, hwndParent, hMenu, CPaintManagerUI::GetInstance(), this);

    if (_this)
    {
        //LONG styleValue = ::GetWindowLong(*this, GWL_STYLE);
        //::SetWindowLong(*this, GWL_STYLE, styleValue & ~WS_CAPTION);
    }

无边框窗口如何模拟系统标题栏

像chrome这种是如何绘制三个按钮的呢,代码卷帙浩繁难以取经,不如自制,应该不难。

百度网盘这种自己瞎画的,还请大家不要随便模仿。

potplayer 也是无边框,但是竟然没有菜单栏,而是用层级超多的右键菜单,而且鼠标稍微一移动就消失了,用起来气人。

模拟菜单栏

顶部自绘模拟的菜单栏可以布局在标题栏内部,不单独占用屏幕空间。

相关文章

  • 怎么用照片制作MV视频?把照片合集做成MV视频的软件,实用制作教

    怎么用照片制作MV视频?照片合集的MV视频制作教程是怎样的?到底用什么软件制作照片MV视频? 照片MV视频其实就是...

  • duilib相关资料

    Duilib[https://github.com/duilib/duilib]是一个Windows下免费开源的D...

  • 制作VR视频播放器

    最近VR火的不要不要的,但是综合起来,VR资源最多的还是全景图片和全景视频,今天在这里给大家简单介绍一下如何用制作...

  • UE 制作视频播放器

    制作之前的准备材料: 主要是音效播放器,播放列表,播放器以及创建播放器自带的媒体纹理,还有就是把媒体纹理变成umg...

  • FFmpeg & 音视频

    学习资料 雷霄骅 大神的 《基于 FFmpeg + SDL 的视频播放器的制作》课程的视频 最近接触了直播后,就一...

  • FFmpeg深度学习模块2019年小结

    FFmpeg是什么,通俗的说,在看片子的时候,需要用到视频播放器,而很多视频播放器的底层用的就是FFmpeg。这是...

  • FFmpeg & SDL

    学习资料 雷霄骅 大神的《基于 FFmpeg + SDL 的视频播放器的制作》课程的视频 SDL 一个跨平台的开源...

  • 01.视频播放器框架介绍

    视频播放器介绍文档 目录介绍 01.该视频播放器介绍 02.视频播放器功能 03.视频播放器架构说明 04.视频播...

  • 2021-06-25学习快乐

    上午,学习剪映视频,打开 制作 加入素材 长按,(可以视频,也可以图片),拖入剪映方框 点击播放器,数分,然后点击...

  • 视频播放器

    系统播放器 打开视频列表 调用系统播放器播放视频 调用系统播放器播放网络视频 VideoView播放器 调用 V...

网友评论

      本文标题:用Duilib制作我的视频播放器 —— WODPlayer

      本文链接:https://www.haomeiwen.com/subject/pnzxkdtx.html