038-第三代软件开发-简易视频播放器-自定义Slider (二)

本文主要是介绍038-第三代软件开发-简易视频播放器-自定义Slider (二),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

头图

第三代软件开发-简易视频播放器-自定义Slider (二)

文章目录

  • 第三代软件开发-简易视频播放器-自定义Slider (二)
    • 项目介绍
    • 简易视频播放器
    • 自定义Slider (二)
      • 横向
      • 纵向

关键字: QtQml关键字3关键字4关键字5

项目介绍

欢迎来到我们的 QML & C++ 项目!这个项目结合了 QML(Qt Meta-Object Language)和 C++ 的强大功能,旨在开发出色的用户界面和高性能的后端逻辑。

在项目中,我们利用 QML 的声明式语法和可视化设计能力创建出现代化的用户界面。通过直观的编码和可重用的组件,我们能够迅速开发出丰富多样的界面效果和动画效果。同时,我们利用 QML 强大的集成能力,轻松将 C++ 的底层逻辑和数据模型集成到前端界面中。

在后端方面,我们使用 C++ 编写高性能的算法、数据处理和计算逻辑。C++ 是一种强大的编程语言,能够提供卓越的性能和可扩展性。我们的团队致力于优化代码,减少资源消耗,以确保我们的项目在各种平台和设备上都能够高效运行。

无论您是对 QML 和 C++ 开发感兴趣,还是需要我们为您构建复杂的用户界面和后端逻辑,我们都随时准备为您提供支持。请随时联系我们,让我们一同打造现代化、高性能的 QML & C++ 项目!

重要说明☝

☀该专栏在第三代软开发更新完将涨价

简易视频播放器

其实咱们在前面屏保哪里已经搞过视频文件播放了,只是哪里没有进度条,也没有时间线,也不能控制播放暂停,今天我们就是把这些再加上去。如下图所示,这里因为原始录制的Gif 太大,无法上传,所以做了减帧处理,看着有点卡顿了。

这里咱就是直接上代码吧;

import QtQuick 2.15
import QtMultimedia 5.15
import QtQuick.Layouts 1.15                     // 布局需要
import QtQuick.Controls 2.15
Rectangle
{property string videoSource: "file"property bool fullScreen: falseid:rootcolor: "#000000"anchors.centerIn: parentwidth: 720height: 480visible: falseSoundEffect {id: playSoundsource: "qrc:/Audio/T_Resource/T_Audio/T_Base/buttonTach.wav"}//    Video//    {//        id:video_show//        anchors.fill: parent//        loops: MediaPlayer.Infinite//        source: root.videoSource//    }MediaPlayer{id:media_videosource: videoSource                 // 绝对路径loops: MediaPlayer.Infinitevolume: 0.5}VideoOutput{id:out_putanchors.fill: parentsource: media_video}RowLayout{id:layout_menuanchors.left: parent.leftanchors.right: parent.rightanchors.bottom: parent.bottomheight: 26spacing: 20Item{width: 26height: 20Image {anchors.centerIn: parentheight: 26fillMode: Image.PreserveAspectFitsource: (media_video.playbackState === MediaPlayer.PlayingState ) ? "qrc:/Video/T_Resource/T_Image/Vidoe/zt.png" : "qrc:/Video/T_Resource/T_Image/Vidoe/bf.png"}MouseArea{anchors.fill: parentonClicked: (media_video.playbackState === MediaPlayer.PlayingState ) ? media_video.pause() : media_video.play();}}Item {implicitWidth: 50Text {anchors.centerIn: parentfont.pixelSize: 20color: "#FFFFFF"text: {// 创建变量获取时间当前播放位置,单位毫秒var milliseconds = media_video.position// 创建变量,将当前播放位置的毫秒转换为分钟,并向下取舍var minutes = Math.floor(milliseconds / 60000)// 获取不足 60秒的毫秒数milliseconds -= minutes * 60000// 创建变量,不足60秒的毫秒数转换为秒var seconds = milliseconds / 1000// 进行四舍五入seconds = Math.round(seconds)// 判断秒数是否小于10秒,来输出时间格式,最终格式为:mm:ssif(seconds < 10)return minutes + ":0" + secondselsereturn minutes + ":" + seconds}}}Slider{id:durationTimeSliderLayout.fillWidth: truevalue: media_video.position / media_video.durationbackground: Rectangle{x: durationTimeSlider.leftPaddingy: durationTimeSlider.topPadding + durationTimeSlider.availableHeight / 2 - height / 2implicitHeight: 4implicitWidth: 200width: durationTimeSlider.availableWidthheight: implicitHeightradius: 2color: "#F0F0F0"    // 进度条背景颜色// 视频已经播放的区域Rectangle{width: durationTimeSlider.visualPosition * parent.widthheight: parent.heightcolor: "#36ABDF"    // 进度条已经走完的颜色radius: 2}}// 滑块样式handle: Rectangle{antialiasing: truex: durationTimeSlider.leftPadding + durationTimeSlider.visualPosition* (durationTimeSlider.availableWidth - width)y: durationTimeSlider.topPadding + durationTimeSlider.availableHeight / 2 - height / 2implicitWidth: 20implicitHeight: 20radius: 10border.color: "#bdbebf"    // 滑块边框颜色// 判断滑块按压状态,设置不同的颜色color: durationTimeSlider.pressed ? "#B0C4DE" : "#F0F0F0"// 滑块中心的区域,我这里设置了透明Rectangle{width: 4height: 4radius: 2color: "transparent"anchors.centerIn: parent}}property real index: 0property bool changed: false// 滑块移动时,将 index 设置为滑块当前位置onMoved: {if(pressed){index = position}}onPressedChanged: {if(pressed === true){changed = true}else if (changed === true){media_video.seek(index * media_video.duration)changed = false}}}Item {implicitWidth: 50Text {anchors.centerIn: parentfont.pixelSize: 20color: "#FFFFFF"text: {var millseconds = media_video.duration.valueOf()var minutes = Math.floor(millseconds / 60000)millseconds -= minutes * 6000var secounds = millseconds / 1000secounds = Math.round(secounds)// 返回 mm : ss 格式时间if(secounds < 10)return minutes + ":0" + secoundselsereturn minutes + ":" + secounds}}}Item{id:item_volumewidth: 26height: 20Image {anchors.centerIn: parentheight: 26fillMode: Image.PreserveAspectFitsource: "qrc:/Video/T_Resource/T_Image/Vidoe/yl_z.png"}MouseArea{anchors.fill: parentonClicked: item_volum.visible = !item_volum.visible}}Item{width: 26height: 20Image {anchors.centerIn: parentheight: 26fillMode: Image.PreserveAspectFitsource: fullScreen ? "qrc:/Video/T_Resource/T_Image/Vidoe/sx.png" :"qrc:/Video/T_Resource/T_Image/Vidoe/qp.png"}MouseArea{anchors.fill: parentonClicked: root.fullScreen = !root.fullScreen}}}Item {id:item_volumwidth: 42height: 235visible: falseanchors.bottom: layout_menu.topanchors.right: layout_menu.rightanchors.rightMargin: 36Text {anchors.top: parent.topanchors.horizontalCenter: parent.horizontalCenterfont.pixelSize: 20color: "#36ABDF"text: (volumeSlider.value * 100).toFixed(0)}Slider{id:volumeSliderwidth: 42height: 220from:0.0to:1.0stepSize: 0.01value: media_video.volumeanchors.bottom: parent.bottomanchors.horizontalCenter: parent.horizontalCenterorientation:Qt.Verticalbackground: Rectangle{anchors.horizontalCenter: parent.horizontalCentery: volumeSlider.topPadding + volumeSlider.availableHeight / 2 - height / 2implicitHeight: 200implicitWidth: 4width: 4height: volumeSlider.availableHeightradius: 2color: "#F0F0F0"    // 进度条背景颜色// 视频已经播放的区域Rectangle{anchors.bottom: parent.bottomwidth: parent.widthheight: parent.height - volumeSlider.visualPosition * parent.heightcolor: "#36ABDF"    // 进度条已经走完的颜色radius: 2}}// 滑块样式handle: Rectangle{antialiasing: trueanchors.horizontalCenter: parent.horizontalCentery: volumeSlider.topPadding + volumeSlider.visualPosition* (volumeSlider.availableHeight - height)implicitWidth: 20implicitHeight: 20radius: 10border.color: "#bdbebf"    // 滑块边框颜色// 判断滑块按压状态,设置不同的颜色color: volumeSlider.pressed ? "#B0C4DE" : "#F0F0F0"// 滑块中心的区域,我这里设置了透明Rectangle{width: 4height: 4radius: 2color: "transparent"anchors.centerIn: parent}}onValueChanged: media_video.volume = value}}function play(){media_video.play();}function stop(){if((media_video.playbackState === MediaPlayer.PlayingState  || media_video.playbackState === MediaPlayer.PausedState))media_video.stop();}
}

自定义Slider (二)

横向

        Slider{id:durationTimeSliderLayout.fillWidth: truevalue: media_video.position / media_video.durationbackground: Rectangle{x: durationTimeSlider.leftPaddingy: durationTimeSlider.topPadding + durationTimeSlider.availableHeight / 2 - height / 2implicitHeight: 4implicitWidth: 200width: durationTimeSlider.availableWidthheight: implicitHeightradius: 2color: "#F0F0F0"    // 进度条背景颜色// 视频已经播放的区域Rectangle{width: durationTimeSlider.visualPosition * parent.widthheight: parent.heightcolor: "#36ABDF"    // 进度条已经走完的颜色radius: 2}}// 滑块样式handle: Rectangle{antialiasing: truex: durationTimeSlider.leftPadding + durationTimeSlider.visualPosition* (durationTimeSlider.availableWidth - width)y: durationTimeSlider.topPadding + durationTimeSlider.availableHeight / 2 - height / 2implicitWidth: 20implicitHeight: 20radius: 10border.color: "#bdbebf"    // 滑块边框颜色// 判断滑块按压状态,设置不同的颜色color: durationTimeSlider.pressed ? "#B0C4DE" : "#F0F0F0"// 滑块中心的区域,我这里设置了透明Rectangle{width: 4height: 4radius: 2color: "transparent"anchors.centerIn: parent}}property real index: 0property bool changed: false// 滑块移动时,将 index 设置为滑块当前位置onMoved: {if(pressed){index = position}}onPressedChanged: {if(pressed === true){changed = true}else if (changed === true){media_video.seek(index * media_video.duration)changed = false}}}

纵向

        Slider{id:volumeSliderwidth: 42height: 220from:0.0to:1.0stepSize: 0.01value: media_video.volumeanchors.bottom: parent.bottomanchors.horizontalCenter: parent.horizontalCenterorientation:Qt.Verticalbackground: Rectangle{anchors.horizontalCenter: parent.horizontalCentery: volumeSlider.topPadding + volumeSlider.availableHeight / 2 - height / 2implicitHeight: 200implicitWidth: 4width: 4height: volumeSlider.availableHeightradius: 2color: "#F0F0F0"    // 进度条背景颜色// 视频已经播放的区域Rectangle{anchors.bottom: parent.bottomwidth: parent.widthheight: parent.height - volumeSlider.visualPosition * parent.heightcolor: "#36ABDF"    // 进度条已经走完的颜色radius: 2}}// 滑块样式handle: Rectangle{antialiasing: trueanchors.horizontalCenter: parent.horizontalCentery: volumeSlider.topPadding + volumeSlider.visualPosition* (volumeSlider.availableHeight - height)implicitWidth: 20implicitHeight: 20radius: 10border.color: "#bdbebf"    // 滑块边框颜色// 判断滑块按压状态,设置不同的颜色color: volumeSlider.pressed ? "#B0C4DE" : "#F0F0F0"// 滑块中心的区域,我这里设置了透明Rectangle{width: 4height: 4radius: 2color: "transparent"anchors.centerIn: parent}}onValueChanged: media_video.volume = value}

这部分qml 代码很好懂,没有啥需要注意的吧,这里需要注意的就是一部分

    MediaPlayer{id:media_videosource: videoSource                 // 绝对路径loops: MediaPlayer.Infinitevolume: 0.5}VideoOutput{id:out_putanchors.fill: parentsource: media_video}

其实我最开始是用了Video组件的,但是再全屏的时候遇到问题,就是画面不会跟着全屏,应该是哪里跟着改下就可,不过我没有时间处理,这个功能就是播放一下宣教视频和宣传视频,所以目前不会有太多的精力放在这里。


博客签名2021

这篇关于038-第三代软件开发-简易视频播放器-自定义Slider (二)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



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

相关文章

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

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

【前端学习】AntV G6-08 深入图形与图形分组、自定义节点、节点动画(下)

【课程链接】 AntV G6:深入图形与图形分组、自定义节点、节点动画(下)_哔哩哔哩_bilibili 本章十吾老师讲解了一个复杂的自定义节点中,应该怎样去计算和绘制图形,如何给一个图形制作不间断的动画,以及在鼠标事件之后产生动画。(有点难,需要好好理解) <!DOCTYPE html><html><head><meta charset="UTF-8"><title>06

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

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

自定义类型:结构体(续)

目录 一. 结构体的内存对齐 1.1 为什么存在内存对齐? 1.2 修改默认对齐数 二. 结构体传参 三. 结构体实现位段 一. 结构体的内存对齐 在前面的文章里我们已经讲过一部分的内存对齐的知识,并举出了两个例子,我们再举出两个例子继续说明: struct S3{double a;int b;char c;};int mian(){printf("%zd\n",s

EasyPlayer.js网页H5 Web js播放器能力合集

最近遇到一个需求,要求做一款播放器,发现能力上跟EasyPlayer.js基本一致,满足要求: 需求 功性能 分类 需求描述 功能 预览 分屏模式 单分屏(单屏/全屏) 多分屏(2*2) 多分屏(3*3) 多分屏(4*4) 播放控制 播放(单个或全部) 暂停(暂停时展示最后一帧画面) 停止(单个或全部) 声音控制(开关/音量调节) 主辅码流切换 辅助功能 屏

Spring 源码解读:自定义实现Bean定义的注册与解析

引言 在Spring框架中,Bean的注册与解析是整个依赖注入流程的核心步骤。通过Bean定义,Spring容器知道如何创建、配置和管理每个Bean实例。本篇文章将通过实现一个简化版的Bean定义注册与解析机制,帮助你理解Spring框架背后的设计逻辑。我们还将对比Spring中的BeanDefinition和BeanDefinitionRegistry,以全面掌握Bean注册和解析的核心原理。

《x86汇编语言:从实模式到保护模式》视频来了

《x86汇编语言:从实模式到保护模式》视频来了 很多朋友留言,说我的专栏《x86汇编语言:从实模式到保护模式》写得很详细,还有的朋友希望我能写得更细,最好是覆盖全书的所有章节。 毕竟我不是作者,只有作者的解读才是最权威的。 当初我学习这本书的时候,只能靠自己摸索,网上搜不到什么好资源。 如果你正在学这本书或者汇编语言,那你有福气了。 本书作者李忠老师,以此书为蓝本,录制了全套视频。 试

Oracle type (自定义类型的使用)

oracle - type   type定义: oracle中自定义数据类型 oracle中有基本的数据类型,如number,varchar2,date,numeric,float....但有时候我们需要特殊的格式, 如将name定义为(firstname,lastname)的形式,我们想把这个作为一个表的一列看待,这时候就要我们自己定义一个数据类型 格式 :create or repla

SAM2POINT:以zero-shot且快速的方式将任何 3D 视频分割为视频

摘要 我们介绍 SAM2POINT,这是一种采用 Segment Anything Model 2 (SAM 2) 进行零样本和快速 3D 分割的初步探索。 SAM2POINT 将任何 3D 数据解释为一系列多向视频,并利用 SAM 2 进行 3D 空间分割,无需进一步训练或 2D-3D 投影。 我们的框架支持各种提示类型,包括 3D 点、框和掩模,并且可以泛化到不同的场景,例如 3D 对象、室

树莓派5_opencv笔记27:Opencv录制视频(无声音)

今日继续学习树莓派5 8G:(Raspberry Pi,简称RPi或RasPi)  本人所用树莓派5 装载的系统与版本如下:  版本可用命令 (lsb_release -a) 查询: Opencv 与 python 版本如下: 今天就水一篇文章,用树莓派摄像头,Opencv录制一段视频保存在指定目录... 文章提供测试代码讲解,整体代码贴出、测试效果图 目录 阶段一:录制一段