qt实现播放视屏的时候,加载外挂字幕(.srt文件解析)

news2024/12/22 0:00:41

之前用qt写了一个在windows下播放视频的软件,具体介绍参见qt编写的视频播放器,windows下使用,精致小巧_GreenHandBruce的博客-CSDN博客

后来发现有些视频没有内嵌字幕,需要外挂字幕,这时候,我就想着把加载外挂字幕的功能加上。如下图:

这里先做了解析.srt字幕文件的功能。具体实现如下

1.先在窗口放一个label,将label调整到界面底部,设置字体,颜色

//显示字幕用的label;
    labelSubTitle = new myLabel(this);
//    labelSubTitle->setText("这里显示字幕文件");
    QFont font("微软雅黑",15,QFont::Bold);
    QPalette palette = labelSubTitle->palette();
    palette.setColor(QPalette::WindowText,Qt::white);
    labelSubTitle->setPalette(palette);
    labelSubTitle->setFont(font);
    labelSubTitle->setAlignment(Qt::AlignCenter);

2.在打开视频文件的时候找到同文件夹下的.srt文件

    int nIndex = fileName.lastIndexOf('.');//寻找‘.’符号在字符串中的id
    nIndex++;
    QString srtfile =fileName.mid(0,nIndex); //截取‘.’符号后面的字符串,这是为了获取文件后缀名
    srtfile +="srt";
    EncodingFormat code = FileCharacterEncoding(srtfile);
    QFile file(srtfile);
    if(!file.open(QIODevice::ReadOnly)) {
        qDebug()<<"未找到外挂字幕文件:"<<srtfile<<endl;
    }

3.解析.srt文件,先看一下.srt字幕文件格式如下:


然后写个结构体用来存放解析之后的srt内容,如下:

struct SrtInfo
{
    qint16 Num;
    QTime dtStart;
    QTime dtEnd;
    QString strSubTitle;
};

然后解析,在解析的时候要注意.srt的编码格式,(编码格式这块参见我上一篇文章qt按照不同编码格式读取文字(UTF-16LE,UTF-8,UTF-8BOM,UTF-16BE)-CSDN博客)

void VideoPlayer::ParseSubTitle(QString fileName)
{
    int nIndex = fileName.lastIndexOf('.');//寻找‘.’符号在字符串中的id
    nIndex++;
    QString srtfile =fileName.mid(0,nIndex); //截取‘.’符号后面的字符串,这是为了获取文件后缀名
    srtfile +="srt";
    EncodingFormat code = FileCharacterEncoding(srtfile);
    QFile file(srtfile);
    if(!file.open(QIODevice::ReadOnly)) {
        qDebug()<<"未找到外挂字幕文件:"<<srtfile<<endl;
    }
    m_SrtInfoLst.clear();
    QTextCodec::ConverterState state;
    QTextCodec *codec = QTextCodec::codecForName("UTF-8");
    if(code==EncodingFormat::UTF16LE)
    {
        codec = QTextCodec::codecForName("UTF-16LE");
    }
    else if(code==EncodingFormat::UTF8)
    {
        codec = QTextCodec::codecForName("UTF-8");
    }
    else if(code==EncodingFormat::UTF8BOM)
    {
        codec = QTextCodec::codecForName("UTF-8");
    }
    else if(code==EncodingFormat::UTF16BE)
    {
        codec = QTextCodec::codecForName("UTF-16BE");
    }
    QTextStream stream_src(&file);
    stream_src.setCodec(codec);
    while(!stream_src.atEnd()) {
        QString str = stream_src.readLine();
        str = str.replace('\r',"");//替换回车符
        str = str.replace('\n',"");//替换换行符
        bool ok;
        qint16 nID = str.toInt(&ok,10);
        if(ok)
        {
            SrtInfo info;
            info.Num = nID;
            if(stream_src.atEnd())
                break;
            QString str2=stream_src.readLine();
            str2 = str2.replace('\r',"");//替换回车符
            str2 = str2.replace('\n',"");//替换换行符
            str2 = str2.replace(' ',"");//替换空格符
            if(str2=="")
                continue;
            info.dtStart = QTime::fromString(str2.split('-').first(),"hh:mm:ss,zzz");
            info.dtEnd = QTime::fromString(str2.split('>').last(),"hh:mm:ss,zzz");

            QString str3=stream_src.readLine();
            if(str3=="")
                continue;
            str3 = str3.replace('\r',"");//替换回车符
            str3 = str3.replace('\n',"");//替换换行符
            info.strSubTitle = str3;

            QString str4=stream_src.readLine();
            if(str4=="")
                continue;
            str4 = str4.replace('\r',"");//替换回车符
            str4 = str4.replace('\n',"");//替换换行符
            info.strSubTitle.append('\n');
            info.strSubTitle.append(str4);

            m_SrtInfoLst.append(info);
        }
    }
    file.close();
}

然后就是在播放视频的时候,找到当前时刻对应的字幕并显示在label上,如下:

void VideoPlayer::positionChanged(qint64 position)
{
    m_positionSlider->setValue(position);
    QTime timeCrt = QTime(0,0,0);
    timeCrt = timeCrt.addMSecs(position);
    QTime timeTotal =QTime(0,0,0);
    timeTotal = timeTotal.addMSecs(m_mediaPlayer->duration());
    QString str = timeCrt.toString("hh:mm:ss")+"/"+timeTotal.toString("hh:mm:ss");
//    m_labelTiem->setFont(QFont::gra);
    m_labelTiem->setText(str);
    if(m_mediaPlayer->duration()>0&&position>=m_mediaPlayer->duration())
    {
        //图标变成play
        QImage img;
        img.load(":/play");
        m_labelPlay->setPixmap(QPixmap::fromImage(img));
    }
    bool bShow = false;
    foreach(const SrtInfo item,m_SrtInfoLst)
    {
        if(item.dtStart<timeCrt && item.dtEnd>timeCrt)
        {
            labelSubTitle->setText(item.strSubTitle);
            bShow = true;
            break;
        }
    }
    if(!bShow)
    {
        labelSubTitle->setText("");
    }
}

完整代码参见

https://download.csdn.net/download/weixin_43935474/88561361

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1246166.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

什么是零长期特权(ZSP)

零长期特权&#xff08;ZSP&#xff09;是一个 IT 安全术语&#xff0c;指的是非永久性的访问权限或权限&#xff0c;ZSP 最初由 Gartner 创造&#xff0c;是一种通过删除多余的永久特权&#xff08;也称为长期特权&#xff09;来帮助改善组织安全态势的方法。 ZSP 是零信任安…

【OpenSTL】方便好用的时空预测开源库

OpenSTL&#xff1a;方便好用的时空预测开源库 时空预测学习是一种学习范式&#xff0c;它使得模型能够通过在无监督的情况下从给定的过去帧预测未来帧&#xff0c;从而学习空间和时间的模式。尽管近年来取得了显著的进展&#xff0c;但由于不同的设置、复杂的实现和难以复现性…

【精选】框架初探篇之——MyBatis入门必知【面试常问】

什么是MyBatis? MyBatis是一个半自动的ORM框架&#xff0c;其本质是对JDBC的封装。使用MyBatis不需要写JDBC代码&#xff0c;但需要程序员编写SQL语句。之前是apache的一个开源项目iBatis&#xff0c;2010年改名为MyBatis。 补充&#xff1a; Hibernate也是一款持久层ORM框架&…

若依vue-修改标题和图标

因为我们拉下来的代码,图标和logo是若依的,这和我们需要做出来的效果有差别 这个时候就需要去对应的文件内去修改标题和图标 (主要就是这两个地方的图标和标题) 修改菜单里面的logo以及文字 修改文字 位置: src/layout/component/Sidebar/Logo.vue 此处的title文字是定义在…

大厂前沿技术导航

百度Geek说 - 知乎 腾讯技术 - 知乎 美团技术团队

HttpClient库请求代码示例

首先&#xff0c;我们需要导入HttpClient库&#xff0c;以便我们可以使用它来发送HTTP请求。以下是如何完成此操作的代码&#xff1a; java import org.apache.http.HttpEntity; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.…

新苹果手机如何导入旧手机数据?解决方案来了,记得收藏!

为了保持其竞争优势&#xff0c;苹果公司不断推出新的产品和服务&#xff0c;因此苹果手机的更新换代速度是比较快的。正巧最近刚出了iPhone15&#xff0c;相信很多小伙伴已经换上了期待已久的新手机。 更换新手机后&#xff0c;大家都会面临一个问题&#xff1a;新苹果手机如…

TikTok Shop 与英国皇家邮政合作:为卖家提供“Click and Drop”服务

11 月 21 日&#xff0c;TikTok Shop 宣布与皇家邮政 建立新的合作伙伴关系 &#xff0c;为平台上的商家推出 Click & Drop。此次合作将使各种规模的商家能够通过将皇家邮政的 Click & Drop 与其 TikTok Shop 帐户集成来改善其履行体验并更有效地发出订单&#xff0c;…

什么手机30万?VERTU唐卡手机顶配56.8万

近日,一则新闻在社交媒体上引发了广泛关注。一名男子遗失了一部价值30万的VERTU唐卡定制款手机,而一位女士在捡到这部手机后,误以为是一部普通的老年机,引发了种种误会。30万的手机是什么牌子?VERTU唐卡手机浮出水面 据了解,这部VERTU唐卡定制款手机是一款豪华的奢侈品定制手机…

leetcode:495. 提莫攻击

一、题目 链接&#xff1a;495. 提莫攻击 - 力扣&#xff08;LeetCode&#xff09; 函数原型&#xff1a;int findPoisonedDuration(int* timeSeries, int timeSeriesSize, int duration) 二、思路 遍历数组timeSeries&#xff0c;如果 元素值duration < 下一元素值 &#x…

Windows下安装Anaconda3并使用JupyterNoteBook

下载安装包 Anaconda官网 进官网&#xff0c;点击下载 自动根据当前系统下载对应的包了&#xff0c;安装包大约1G&#xff0c;喝杯Java耐心等待。 安装 很多人安装C盘&#xff0c;我这里放D盘。 注意&#xff1a;你的文件夹目录一定要不能有空格 然后其他的直接默认install即…

【ChatGLM3-6B】Docker下部署及微调

【ChatGLM2-6B】小白入门及Docker下部署 注意&#xff1a;Docker基于镜像中网盘上上传的有已经做好的镜像&#xff0c;想要便捷使用的可以直接从Docker基于镜像安装看Docker从0安装前提下载启动访问 Docker基于镜像安装容器打包操作&#xff08;生成镜像时使用的命令&#xff0…

oracle rac环境归档日志清除

文章目录 一、处理步骤1、使用终端登录上服务器查看磁盘使用状态2、使用恢复备份管理工具RMAN删除归档日志 二、详细操作步骤三、定时任务自动清归档日志1、编写删除脚本4、测试脚本运行情况5、设置定时任务每周执行一次&#xff0c;并测试运行效果 昨天单位的所有系统都连不上…

干货科普 | 不同类型的机器人及其在工作中的应用

原创 | 文 BFT机器人 制造商在其操作中使用各种类型的机器人&#xff0c;每种机器人都具有特定的能力和功能。我们将讨论制造业中使用的一些最常见类型的机器人&#xff0c;以及哪种机器人可能最适合您的应用。 01 关节机器人 关节式机器人是一种工业机器人&#xff0c;具有一…

管理后台系统,springboot+redis+nginx+html+bootstrap

一个简易版的管理后台系统&#xff0c;前后端分离&#xff0c;可适用于小团队开发&#xff0c;支持二次开发。 后端主要技术springboot&#xff0c;他可以帮我们快速的搭建项目&#xff0c;并快速实现开发。 redis做缓存&#xff0c;保存登录状态和一些高频率查询的基础数据。…

玻色量子“揭秘”之背包问题与Ising建模

摘要&#xff1a;背包问题(Knapsack problem)是一种组合优化的NP-Complete问题。问题可以描述为&#xff1a;给定一组物品&#xff0c;每种物品都有自己的重量和价格&#xff0c;在限定的总重量内&#xff0c;我们如何选择&#xff0c;才能使得物品的总价格最高。 背包问题早期…

高清录屏软件推荐,捕捉每一个美好瞬间

在数字媒体和内容创作领域&#xff0c;高清录屏软件已经成为了日常工作与娱乐中不可或缺的一部分。无论是录制游戏视频、制作教育教程&#xff0c;还是记录演示文稿&#xff0c;高清画质能够让您的内容更加生动、吸引人。在本文中&#xff0c;我们将介绍三款不同的高清录屏软件…

微信小程序商城实例mpvue-xbyjShop-master(附精选源码32套,涵盖商城团购等)

mpvue-xbyjShop 基于mpvue的微信小程序商城&#xff08;小程序端&#xff0c;服务端&#xff09; 小程序端 技术栈 mpvue mpvue-router-patch mpvue-entry vuex webpack ES6/7 flyio mpvue-wxparse 项目运行 微信开发中工具选中mpvue-xbyjShop/buyer作为项目目录即可功…

RFID技术在刀具智能管理中的应用

RFID技术在刀具智能管理中的应用 科技日新月异&#xff0c;工业科技的不断提升,慢慢的改变了传统制造业。RFID技术的崛起改变了传统的人工记录数据、盘点物料的方式&#xff0c;带来更高效、错误率低的解决方案。 刀具是生产过程中不可或缺的工具&#xff0c;高效管理和利用刀…

Zabbix-Liunx服务器内存使用率测试

要在Python 2.7中运行内存消耗脚本并安装psutil&#xff0c;您需要先安装pip。以下是完整的步骤&#xff0c;包括如何在Python 2.7环境中安装pip&#xff0c;然后安装psutil&#xff0c;以及最后如何运行内存消耗脚本。 步骤1: 安装pip 在Python 2.7中安装pip&#xff1a; 首先…