qt学习:mplayer播放器(视频)+arm如何播放视频实战+c启动播放器

目录

作用

linux下载

arm下载

使用方法

键盘

命令

命令词有很多,举例几个

在arm上qt实战

配置ui界面

添加头文件,成员,函数

添加视频按钮点击事件

列表选项双击事件

播放按钮点击事件

暂停继续按钮点击事件

停止按钮点击事件

上一首按钮点击事件

下一首按钮点击事件

快进按钮点击事件

快退按钮点击事件

静音按钮点击事件

音量滑动条拖动事件

运行命令返回结果的槽函数

c调用播放器


作用

可以播放视频和音频

linux下载

sudo apt install mplayer

arm下载

由于arm版本qt没有多媒体模块,只能使用第三方播放器(mplayer或者madplay),对于arm平台而言,它就相当于一个可执行文件,可以当做命令来使用,在linux下可以使用system函数来执行mplayer,将播放音乐的命令集成到程序中,在qt中把mplayer当做是一个进程QProoess,那么,可以使用它来播放音乐

  1. 下载mplayer源码,进行交叉编译配置生成一个程序,一般都有现成的
  2. 将程序放到板子上的/bin目录下加权限
  3. 添加环境

使用方法

键盘

  • mplayer xxx,xxx是播放的视频,可以通过键盘来控制

命令

  • mplayer -slave -quiet xxx,xxx是播放的视频
    • -slave是表示用命令的方式
    • -quiet是表示不输出多余的信息
  • 进入之后可以输入命令词来进行控制视频

命令词有很多,举例几个

  • pause是暂停/播放
  • seek xx快进xx秒,如果是负数就是后退
  • get_time_length返回播放文件的长度,多少秒
  • get_file_name返回当前播放文件的名字
  • get_meta_year返回当前播放文件的年份

在arm上qt实战

在linux上用交叉编译后将可执行文件放到开发板上,再安装第三方播放器,就可以运行了

配置ui界面

添加头文件,成员,函数

#include <QProcess>
#include <QListWidgetItem>
#include <QFileDialog>
#include <QDebug>
#include <QThread>
#include <QTime>
#include <QPoint>

private:
    QProcess *m_process;//进程指针
    int index;//歌曲索引

添加视频按钮点击事件

    //弹出选择文件对话框,并返回选择文件的路径
    QStringList lists = QFileDialog::getOpenFileNames(this,"add video","","video file (*.mp4 *.MP4 *.avi)");
    //将添加的文件显示到列表上
    for(int i=0; i<lists.size(); i++){
        //新建一个选项
        QListWidgetItem *item = new QListWidgetItem;
        //选项设置图标
        item->setIcon(QIcon(":/new/prefix1/pic/video.png"));
        //将路径名字写入选项
        item->setText(lists.at(i).toLocal8Bit());
        //将选项加入到列表上
        ui->listWidget->addItem(item);
    }

列表选项双击事件

    //获取列表的第几首歌曲
    index = ui->listWidget->currentRow();
    //并执行播放
    on_btn_player_clicked();

播放按钮点击事件

    //先停止当前视频
    on_btn_stop_clicked();

    //获取并打印显示视频的控件的全局坐标和长宽
    int posX = ui->label_videoShow->mapToGlobal(QPoint(0, 0)).x();
    int posY = ui->label_videoShow->mapToGlobal(QPoint(0, 0)).y();
    int width = ui->label_videoShow->width();
    int height = ui->label_videoShow->height();
    qDebug()<<"geometry posX:"<<posX<<"\tgeometry posY:"<<posY;
    qDebug()<<"width:"<<width<<"\theight:"<<height;
    //组合视频播放字符串命令
    QString cmd = QString::fromLocal8Bit("mplayer  -slave -quiet -geometry %1:%2  -zoom -x %3 -y %4 %5 &")
                        .arg(posX)
                        .arg(posY)
                        .arg(width)
                        .arg(height)
                        .arg(ui->listWidget->item(index)->text());//视频名字
    //通过进行来运行命令
     m_process->start(cmd.toLocal8Bit().data());

     //get_time_length返回播放文件的长度,以秒为单位   ANS_LENGTH=264.00
     m_process->write("get_time_length\n");
    //关联当进程运行命令的后返回结果时就会发出readyRead信号,会执行onRecvData槽函数
    //等于执行ls命令获取目录,当ls命令产生任何输出时,就会发出readyRead信号
     connect(m_process,&QProcess::readyRead,this,&MainWindow::onRecvData);

暂停继续按钮点击事件

     //向进程写入命令
    m_process->write("pause\n");

停止按钮点击事件

    //判断进程是否在运行,在运行就杀死进程
    if(m_process->state() == QProcess::Running){
         m_process->kill();
    }
    //等待直到子进程完成其工作或遇到错误并退出
    m_process->waitForFinished();

上一首按钮点击事件

    //将索引加一
    index = --index < 0 ? (ui->listWidget->count()-1) :index;
    //并执行播放
    on_btn_player_clicked();

下一首按钮点击事件

    //ui->listWidget->count();返回列表有多少哥选项
    //将索引加一
    index = ++index % ui->listWidget->count();
    //并执行播放
    on_btn_player_clicked();

快进按钮点击事件

     //向进程写入命令
    m_process->write("seek +10\n");

快退按钮点击事件

     //向进程写入命令
    m_process->write("seek -10\n");

静音按钮点击事件

    //向进程写入命令
    m_process->write("mute\n");

音量滑动条拖动事件

    //显示当前播放的音量数值
    ui->label_volumeValue->setText(QString::fromLocal8Bit("当前音量:%1").arg(position));

运行命令返回结果的槽函数

//运行命令的后的槽函数
void MainWindow::onRecvData()
{
    //获取并打印运行命令返回的数据
    QString data = m_process->readAll();
    qDebug()<<data;
    //从 m_process 读取的数据中是否包含字符串 "ANS_LENGTH"。如果包含,说明数据中包含了文件的时间长度信息
    //获取文件时间长度  ANS_LENGTH=264.00
    if(data.contains("ANS_LENGTH")){
        //返回来的时间长度是浮点型,必须转成浮点型,如果转成int 会转换失败
        bool ok;
        //首先移除 "ANS_LENGTH=" 字符串和换行符再转为浮点型
        double timeLength = data.remove("ANS_LENGTH=").remove("\n").toDouble(&ok);
        //判断有没有获取到数据
        if(ok){
            //创建一个时间对象,从0开始
            QTime timeFormat(0,0,0);
            //加入前面获取到的文件时间长度
            timeFormat = timeFormat.addSecs(timeLength);
            //显示时间长度
            ui->label_timeLength->setText(timeFormat.toString());
            //设置 时间长度滑动进度条的最大值为时间长度
            ui->horizontalSlider_seek->setMaximum(timeLength);
        }else{
            qDebug()<<"string to double error";
        }
    }
}

c调用播放器

在启动mplaver播放器的时候,使用选项参数 -input file=/tmp/fifo 将有名管道文件 传递给mplaver播放器进程,此时该mplaver播放器进程执行的时候,会打开该有名管道文件,Mplaver从有名管道读到主进程发送的命令。然后在编程中 往有名管道文件中 输入相关slave命令,达到控制播放器的效果。但是,如果使用get_fle_name等命令想要获取 从mplaver播放器 返回的数据,则还需要创建一个无名管道文件,然后再创建一个子进程,把子进程的标准输出重定向无名管道的写端,Mplayer发出的内容发送到无名管道中,父进程通过读管道就可以读到Mplayer发出的信息。

代码

#include<stdio.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<unistd.h>
#include<string.h>
#include<stdlib.h>

int fifofd;

int init_open()
{
    //创建管道文件  --mkfifo
    int ret = mkfifo("/tmp/fifo",0777);
    if(ret==-1)
    {
        perror("mkfifo error");
        return -1;
    }
    //打开管道文件
    fifofd = open("/tmp/fifo",O_RDWR);
    if(fifofd==-1)
    {
        perror("open fifo error");
        return -1;
    }
}

int write_cmd(char *cmd)
{
    //往管道写命令
    write(fifofd,cmd,strlen(cmd));
}

int main(void)
{
    //初始化管道
    init_open();
    //使用slave命令,将管道和播放器绑定在一起
    system("mplayer -slave -quiet -input file=/tmp/fifo 1.mp3 &");
    while(1)
    {
        write_cmd("seek +10\n");
        sleep(3);
    }
    close(fifofd);
    return 0;
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

挑战杯 python+深度学习+opencv实现植物识别算法系统

0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; 基于深度学习的植物识别算法研究与实现 &#x1f947;学长这里给一个题目综合评分(每项满分5分) 难度系数&#xff1a;4分工作量&#xff1a;4分创新点&#xff1a;4分 &#x1f9ff; 更多…

【Linux】缓冲区与缓冲区的刷新策略

目录 1.缓冲区基础 1.1缓冲区的刷新策略 1.1.1三种刷新策略 1.1.2.两种强制刷新策略 2.用户级语言层缓冲区 2.1.默认在显示器输出 2.2.重定向到文件输出 2.3.write调用没有显示两份的原因 3.模拟实现文件缓冲区 3.1 myFileBuffer.h 3.2 myFileBuffer.c 4.系统内核缓…

Linux系统调试课:Linux错误码介绍

文章目录 一、错误码二、错误码返回案例三、使用 goto 语句沉淀、分享、成长,让自己和他人都能有所收获!😄 📢错误代码由内核或用户空间应用程序(通过errno变量)解释。错误处理在软件开发中非常重要,而不仅仅是在内核开发中。幸运的是,内核提供的几种错误,几乎涵盖了可…

一步步建立一个C#项目(连续读取S7-1500PLC数据)

首先创建一个新项目 1、窗体应用 2、配置存储位置 3、选择框架 拖拽一个Button,可以选择视图菜单---工具箱 4、工具箱 拖拽Lable控件和TextBook控件 5、拖拽控件 接下来右键解决方案&#xff0c;点击管理NuGet程序包 6、NuGet程序包 7、安装S7net 8、点击安装 9、安装完成 …

杨幂《哈尔滨1944》现场无剧本,大胆突破令人惊艳。

♥ 为方便您进行讨论和分享&#xff0c;同时也为能带给您不一样的参与感。请您在阅读本文之前&#xff0c;点击一下“关注”&#xff0c;非常感谢您的支持&#xff01; 文 |猴哥聊娱乐 编 辑|徐 婷 校 对|侯欢庭 杨幂在《哈尔滨1944》的拍摄现场&#xff0c;竟然不带剧本&am…

空想--让MYSQL安装双引擎SQL优化器

坑人的innodb_thread_concurrencyMYSQL的优化器是硬解析, 应用每次发往MYSQL的SQL是文本格式,需要编译,虽然时间不多,也就几百毫秒的事情,可架不住SQL的请求并发量啊! 为此数据库走了两条路线, 一条是ORACLE的缓存路线, 另外一条就是MYSQL的快速路线. ORACLE是尽可能的深度…

【电路】500W 12V至220V的逆变器

本电路采用LT1073芯片DC&#xff0d;DC转换器&#xff0c;将1.5V电压升压到5V或12V。该IC有三个不同的版本&#xff0c;这取决于输出电压。两个具有5V和12V的固定输出电压&#xff0c;而最有趣的是&#xff0c;可以进行调整。该调整是通过两个电阻器的分压器&#xff0c;连接到…

有没有那种不烂大街的跨年文案?

​迎接新年的曙光&#xff1a;那些不落俗套的跨年文案 当钟声敲响&#xff0c;旧的一年逝去&#xff0c;新的一年悄然来临&#xff0c;我们总希望用一些特别的话语来表达对过去的怀念和对未来的期待。在这个信息爆炸的时代&#xff0c;许多跨年文案都已经被人们看过无数次&…

数据结构第十天(排序算法总结)

目录 前言 常数时间复杂度&#xff1a;O(1) 线性时间复杂度&#xff1a;O(n) 线性对数时间复杂度&#xff1a;O(n log n) 平方时间复杂度&#xff1a;O(n^2) 对数时间复杂度&#xff1a;O(log n) 前言 排序算法的学习可以告一段落了。但算法的学习永不停止。 今天&…

RBAC权限控制系统-手撸RBAC

手撸RBAC 一、概述 1、什么是RBAC RBAC&#xff08;Role-Based Access Control&#xff09;是一种访问控制机制&#xff0c;它基于角色的概念&#xff0c;将权限授予特定的角色&#xff0c;而不是直接授予个体用户。 这种模型允许管理员根据用户的角色来管理他们的权限&…

elementPlus实现动态表格单元格合并span-method方法总结

最近在做PC端需求的时候&#xff0c;需要把首列中相邻的同名称单元格合并。 我看了一下elementPlus官网中的table表格&#xff0c;span-method可以实现单元格合并。 我们先看一下官网的例子&#xff1a; 合并行或列 多行或多列共用一个数据时&#xff0c;可以合并行或列。 …

9.0 Zookeeper 节点特性

本章节介绍一下 zookeeper 的节点特性和简单使用场景&#xff0c;正是由于这些节点特性的存在使 zookeeper 开发出不同的场景应用。 1、同一级节点 key 名称是唯一的 实例&#xff1a; $ ls / $ create /runoob 2 已存在 /runoob 节点&#xff0c;再次创建会提示已经存在。 …

Mysql大表添加字段失败解决方案

背景 最近遇到一个问题&#xff0c;需要在user用户表千万级别数据中添加两个字段&#xff0c;发现老是加不上去&#xff0c;一直卡死。表数据量不仅大&#xff0c;而且是一个热点表&#xff0c;访问频率特别高&#xff0c;而且该表的访问是在一个大事务中。加字段的时候一直在…

Vue3大事件项目(ing)

文章目录 核心内容1.大事件项目介绍2.大事件项目创建3.Eslint配置代码风格4.配置代码检查工作流问题: pnpm lint是全量检查,耗时问题,历史问题 5.目录调整6.vue-router4 路由代码解析7.引入 Element Plus 组件库8.Pinia 构建仓库 和 持久化9.Pinia 仓库统一管理 核心内容 Vue3…

CX341A 安装驱动与刷固件

参考 驱动安装1 DPDK编译&#xff1a;支持Mellanox 25Gbps网卡 - 知乎 NVIDIA Mellanox CX网卡固件、驱动系列操作 - 知乎 驱动安装2 Mellanox网卡驱动安装指南 Mellanox OFED_崇尚匀速 追求极致的技术博客_51CTO博客 驱动与固件&#xff1a; 家用万兆网络指南 6 - 比…

3、生成式 AI 如何帮助您改进数据可视化图表

生成式 AI 如何帮助您改进数据可视化图表 使用生成式 AI 加速和增强数据可视化。 图像来源:DALLE 3 5 个关键要点: 数据可视化图表的基本结构使用 Python Altair 构建数据可视化图表使用 GitHub Copilot 加快图表生成速度使用 ChatGPT 为您的图表生成相关内容使用 DALL-E 将…

JCTC | 利用几何深度学习对蛋白质-配体结合pose进行等变灵活建模

Overview 该论文解决了药物开发中蛋白质-配体复合结构灵活建模的挑战。作者提出了一种名为FlexPose的新型深度学习框架&#xff0c;它可以直接对复杂结构进行建模&#xff0c;而不需要传统的采样和评分策略。 该模型结合了标量-向量双特征表示和 SE(3)等变网络设计来处理动态结…

[word] word表格内容自动编号 #经验分享#微信#其他

word表格内容自动编号 在表格中的内容怎么样自动编号&#xff1f;我们都知道Word表格和Excel表格有所不同&#xff0c;Excel表格可以轻松自动编号&#xff0c;那么在Word表格中如何自动编号呢&#xff1f; 1、选中内容后&#xff0c;点击段落-自动编号&#xff0c;选择其中一…

基于SSM的实习管理系统(有报告)。Javaee项目。ssm项目。

演示视频&#xff1a; 基于SSM的实习管理系统&#xff08;有报告&#xff09;。Javaee项目。ssm项目。 项目介绍&#xff1a; 采用M&#xff08;model&#xff09;V&#xff08;view&#xff09;C&#xff08;controller&#xff09;三层体系结构&#xff0c;通过Spring Spri…

【MATLAB】使用梯度提升树在回归预测任务中进行特征选择(深度学习的数据集处理)

1.梯度提升树在神经网络的应用 使用梯度提升树进行特征选择的好处在于可以得到特征的重要性分数&#xff0c;从而识别出对目标变量预测最具影响力的特征。这有助于简化模型并提高其泛化能力&#xff0c;减少过拟合的风险&#xff0c;并且可以加快模型训练和推理速度。此外&…