基于鸿蒙API10的RTSP播放器(八:音量和亮度调节功能的整合)

news2024/11/17 23:48:23
一、前言:

笔者在前面第六、七节文章当中,分别指出了音量和屏幕亮度的前置知识,在本节当中,我们将一并实现这两个功能,从而接续第五节内容。本文的逻辑分三大部分,先说用到的变量,再说界面,最后说功能。

其中音量功能,是设置的系统音量,而不是视频音量;其中亮度功能,是设置的应用亮度,而非系统亮度,请注意两者的区别。

亮度功能使用brightness库获取系统亮度值,在初始化亮度值,然后根据触摸情况通过window库设置亮度值

音量功能通过audio库,初始化音量值,根据触摸情况设置音量值

文中代码均是ArkTS代码,使用TS标志,是为了有颜色,好看,嘿嘿!

以下是效果图,即我手指左边垂直向下滑动时,出现亮度调节图标和进度条。
在这里插入图片描述

以下是效果图,即我手指右边垂直向下滑动时,出现音量调节图标和进度条。
在这里插入图片描述

二、状态变量:

// 以下代码均放在struct yourPageName{}结构体内,但在build(){}函数之外


// 控制图标和进度条是否显示  
@State volumeVisible:boolean = false;  
@State brightVisible: boolean = false;  
  
// 音量和亮度值  
@State volume:number = 0;  
@State bright:number = 50;  
  
// 手指触点横坐标位置  
@State fingerPosition:number = 0;  
  
// 屏幕一半宽度,我这里是500px  
@State halfDeviceWidth:number = 500;  
  
// 根据全局变量获得窗口控制器 ,这里需要提前在EntryAbility中设置全局变量,并把windowStage放进去,代码附下
windowStage: window.WindowStage = AppStorage.get('windowStage') as window.WindowStage;  
// 获取主窗口的方式  
mainWin: window.Window = this.windowStage.getMainWindowSync();


import AbilityConstant from '@ohos.app.ability.AbilityConstant';  
import hilog from '@ohos.hilog';  
import UIAbility from '@ohos.app.ability.UIAbility';  
import Want from '@ohos.app.ability.Want';  
import window from '@ohos.window';  
import { BusinessError } from '@kit.BasicServicesKit';  
  
  
export default class EntryAbility extends UIAbility {  
  onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void {  
    hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onCreate');  
  }  
  
  onDestroy(): void {  
    hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onDestroy');  
  }  
  
  onWindowStageCreate(windowStage: window.WindowStage): void {  
    // Main window is created, set main page for this ability  
    hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageCreate');  
  
    console.log('onWindowStageCreate');  
    // 这里设置全局变量,把我们需要的窗体控制器放进去
    AppStorage.setOrCreate('windowStage',windowStage);  
  
    windowStage.loadContent('pages/Index', (err) => {  
      if (err.code) {  
        hilog.error(0x0000, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err) ?? '');  
        return;  
      }  
      hilog.info(0x0000, 'testTag', 'Succeeded in loading the content.');  
    });  
  }  
  
  onWindowStageDestroy(): void {  
    // Main window is destroyed, release UI related resources  
    hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageDestroy');  
  }  
  
  onForeground(): void {  
    // Ability has brought to foreground  
    hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onForeground');  
  }  
  
  onBackground(): void {  
    // Ability has back to background  
    hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onBackground');  
  }  
}

三、界面逻辑:**

这里使用了Stack组件,按照栈概念,可以将图片和进度条在同一时刻一起显示。可以看到笔者这里设置了if语句中的三个变量,分别判断触摸点是否移动,触摸点在屏幕左边还是右边,是否显示。

Stack(){  
    // 亮度调节UI  
  if (this.fingerPosition != 0 && this.fingerPosition < this.halfDeviceWidth && this.brightVisible){  
    Image($r('app.media.ic_bright_white'))  
      .width(50)  
      .aspectRatio(1.0)  
    Progress({value:this.bright,total:100,type:ProgressType.Ring})  
      .color('#ffffffff')  
      .width(100)  
      .aspectRatio(1.0)  
    // 音量调节UI  
  }else if (this.fingerPosition != 0 && this.fingerPosition > this.halfDeviceWidth && this.volumeVisible){  
    Image($r('app.media.ic_volume_white'))  
      .width(50)  
      .aspectRatio(1.0)  
    Progress({value:this.volume,total: 20,type:ProgressType.Ring})  
      .color('#ffffffff')  
      .width(100)  
      .aspectRatio(1.0)  
  }  
}  // Stack组件可以自行调节,这段代码也可以嵌入进其他代码中,里面的图片随便找一个就好了
.width('100%')  
.height('40%')  
.backgroundColor(Color.Black)
四、功能逻辑:

我们需要在页面渲染之前完成一些初始化的工作,包括主窗体的获取,音量的初始化,亮度的初始化。

当然,也可以直接在第一部分定义变量的时候直接赋值,但直接赋值的弊端就是,以音量调节为例,进度条每次从设置的音量值开始变化,而不是从系统本来的值开始变化。笔者这里的初始化代码附下

// 此函数是生命周期函数,在struct yourPageName(){}中,build(){}之外
aboutToAppear() {  

 // 初始化音量
  audioManager.getVolume(audio.AudioVolumeType.MEDIA, (err: BusinessError, value: number) => {  
    if (err) {  
      console.error(`Failed to obtain the volume. ${err}`);  
      return;  
    }  
    this.volume = value;  
    console.info('Callback invoked to indicate that the volume is obtained:'+value);  
  });  
  //
    
//  音量初始化,这里代码笔者注释了,选择在定义变量的时候直接赋值0.5
// brightness.getValue({  
//   success: (data: BrightnessResponse) => {  
//     console.log('success get brightness value:' + data.value);  
//     // brightness库中获取的亮度值介于0到255,而window库中设置的亮度值介于0到1,这里在做转换  
//     this.bright = ((data.value/255)*10)%10  
//     try {  
//       this.mainWin.setWindowBrightness(this.bright, (err) => {  
//         if (err.code) {  
//           console.error('Failed to set the brightness. Cause: ' + JSON.stringify(err));  
//           return;  
//         }  
//         console.info('Succeeded in setting the brightness.');  
//       });  
//     } catch (exception) {  
//       console.error('Failed to set the brightness. Cause: ' + JSON.stringify(exception));  
//     }  
//   },  
//   fail: (data: string, code: number) => {  
//     console.error('get brightness fail, code: ' + code + ', data: ' + data);  
//   }  
// });


// 初始化主窗体
  this.windowStage = AppStorage.get('windowStage') as window.WindowStage;  
  // 获取主窗口的方式  
  this.mainWin = this.windowStage.getMainWindowSync();  
  // 获取最上层窗口的方式  
  // window.getLastWindow(getContext(this));  
  

}

为上面的Stack组件添加触摸事件,具体功能见代码注释,这里面的try-catch语句主要方便调试,代码如果可以正常运行的话,直接去掉try-catch语句和日志打印,那么代码可以很简介。里面最核心的函数是if语句。


Stack(){
	//代码上面有,此处省略
}
.gesture(  
  GestureGroup(GestureMode.Exclusive,  
    // 添加触摸手势,并通过direction控制手势滑动方向为上下滑动  
    PanGesture({direction:PanDirection.Vertical})  
      .onActionStart((event: GestureEvent) => {  
        // 获取屏幕宽度和高度,便于后面的手势操作  
        if (event.fingerList[0].localX < this.halfDeviceWidth) {  
          this.brightVisible = true;  
        } else {  
          this.volumeVisible = true;  
        }  
      })  
      .onActionEnd(() => {  
        // 当手指离开屏幕时,清除currentIcon状态和关闭图标/进度条  
        this.volumeVisible = false;  
        this.brightVisible = false;  
      })  
      .onActionUpdate((event?:GestureEvent| undefined)=>{  
  
        // 取得系统亮度,为this.bright赋初值  
        if (!event) return; // 如果 event 是 undefined,直接返回,不执行后续代码  
        // 通过event.fingerList[0].localX获取触摸点的横坐标  
        this.fingerPosition = event.fingerList[0].localX  
        // 向上滑动  
        if (event.offsetY < 0){  
          // 触摸点在屏幕右侧  
          if (this.volume < 20 && this.fingerPosition > this.halfDeviceWidth){  
            // 音量值增加  
            this.volume += 0.2  
            audioManager.setVolume(audio.AudioVolumeType.MEDIA, this.volume, (err: BusinessError) => {  
              if (err) {  
                console.error(`Failed to set the volume. ${err}`);  
                return;  
              }  
              console.info('Callback invoked to indicate a successful volume setting.');  
            });  
          }  
          // 触摸点在屏幕左侧  
          if (this.bright < 100 && this.fingerPosition < this.halfDeviceWidth){  
            // 亮度值增加  
            this.bright += 1  
            try {  
              this.mainWin.setWindowBrightness(this.bright / 100 , (err) => {  
                if (err.code) {  
                  console.error('Failed to set the brightness. Cause: ' + JSON.stringify(err));  
                  return;  
                }  
                console.info('Succeeded in setting the brightness.');  
              });  
            } catch (exception) {  
              console.error('Failed to set the brightness. Cause: ' + JSON.stringify(exception));  
            }  
          }        // 向下滑动  
        }else{  
          // 触摸点在屏幕右侧  
          if (this.volume > 0 && this.fingerPosition > this.halfDeviceWidth){  
            // 音量值减小  
            this.volume -= 0.2  
            audioManager.setVolume(audio.AudioVolumeType.MEDIA, this.volume, (err: BusinessError) => {  
              if (err) {  
                console.error(`Failed to set the volume. ${err}`);  
                return;  
              }  
              console.info('Callback invoked to indicate a successful volume setting.');  
            });  
          }  
          // 触摸点在屏幕左侧  
          if (this.bright > 0 && this.fingerPosition < this.halfDeviceWidth){  
            // 亮度值减小  
            this.bright -= 1  
            try {  
              this.mainWin.setWindowBrightness(this.bright / 100 , (err) => {  
                if (err.code) {  
                  console.error('Failed to set the brightness. Cause: ' + JSON.stringify(err));  
                  return;  
                }  
                console.info('Succeeded in setting the brightness.');  
              });  
            } catch (exception) {  
              console.error('Failed to set the brightness. Cause: ' + JSON.stringify(exception));  
            }  
          }        
        }      
    }),  
  )  
)

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

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

相关文章

智慧环保平台建设方案

智慧环保平台建设方案摘要 政策导向与建设背景 背景&#xff1a;全国生态环境保护大会提出坚决打好污染防治攻坚战&#xff0c;推动生态文明建设&#xff0c;目标是在2035年实现生态环境质量根本好转。构建生态文明体系&#xff0c;包括生态文化、生态经济、目标责任、生态文明…

表格标记<table>

一.表格标记、 1table&#xff1a;表格标记 2.caption:表单标题标记 3.tr:表格行标记 4.td:表格中数据单元格标记 5.th:标题单元格 table标记是表格中最外层标记&#xff0c;tr表示表格中的行标记&#xff0c;一对<tr>表示表格中的一行&#xff0c;在<tr>中可…

Excel数据转置|Excel数据旋转90°

Excel数据转置|Excel数据旋转90 将需要转置的数据复制在旁边空格处点击鼠标右键&#xff0c;选择图中转置按钮&#xff0c;即可完成数据的转置。&#xff01;&#xff01;&#xff01;&#xff01;非常有用啊啊啊&#xff01;&#xff01;&#xff01;

嵌入式Linux学习笔记(2)-C语言编译过程

c语言的编译分为4个过程&#xff0c;分别是预处理&#xff0c;编译&#xff0c;汇编&#xff0c;链接。 一、预处理 预处理是c语言编译的第一个阶段&#xff0c;该任务主要由预处理器完成。预处理器会根据预处理指令对源代码进行处理&#xff0c;将预处理指令替换为相应的内容…

游戏各个知识小点汇总

抗锯齿原理记录 SSAA&#xff1a;把成像的图片放大N倍&#xff0c;然后每N个点进行平均值计算。一般N为2的倍数。比如原始尺寸是1000x1000&#xff0c;长宽各放大2倍变成2000x2000。 举例&#xff1a; 原始尺寸&#xff1a; 放大2倍后 最后平均值计算成像&#xff1a; MSAA&…

基于SpringBoot+Vue的网上蛋糕销售系统

作者&#xff1a;计算机学姐 开发技术&#xff1a;SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等&#xff0c;“文末源码”。 专栏推荐&#xff1a;前后端分离项目源码、SpringBoot项目源码、SSM项目源码 系统展示 【2025最新】基于JavaSpringBootVueMySQL的…

踩坑记:Poco库,MySql,解析大文本的bug

这两天在调试一个小功能&#xff0c;使用c,读取MySql。使用的是Poco库。按照官网的写法&#xff1a; std::cout << "read normal data by poco recordset "<<std::endl;Poco::Data::MySQL::Connector::registerConnector();Poco::Data::Session session(…

.NET 6.0 + WPF 使用 Prism 框架实现导航

合集 - .NET 基础知识(3) 1..NET 9 优化&#xff0c;抢先体验 C# 13 新特性08-202.《黑神话&#xff1a;悟空》神话再现&#xff0c;虚幻引擎与Unity/C#谁更强&#xff1f;08-21 3..NET 6.0 WPF 使用 Prism 框架实现导航09-11 收起 阅读目录 前言什么是Prism?安装 Prism使…

【卷起来】VUE3.0教程-09-整合Element-plus

最后一次课了&#xff0c;给个关注和赞呗 &#x1f332; 简介 Element Plus 是一个基于 Vue 3 的高质量 UI 组件库。它包含了丰富的组件和扩展功能&#xff0c;例如表格、表单、按钮、导航、通知等&#xff0c;让开发者能够快速构建高质量的 Web 应用。Element Plus 的设计理念…

洛谷 P4683 [IOI2008] Type Printer

原题点这里 题目来源于&#xff1a;洛谷 题目本质&#xff1a;深搜&#xff0c;字典树Trie 当时想法&#xff1a;当时看了题目标签&#xff0c;就有思路了&#xff08;见代码注释&#xff09;&#xff0c;但一直REWA最后只剩下RE。 正确思路&#xff1a; 我们使用字典树来完…

【机器学习】任务四:使用贝叶斯算法识别葡萄酒类别和使用三种不同的决策树方法(ID3,C4.5,CART)对鸢尾花数据进行分类

目录 1.基础知识 1.1 高斯贝叶斯&#xff08;Gaussian Naive Bayes&#xff09; 1.2 决策树&#xff08;Decision Tree&#xff09; 1.3 模型评价&#xff08;Model Evaluation&#xff09; 1.3.1 评价维度&#xff1a; 1.3.2 评价方法&#xff1a; 2.使用贝叶斯算法识别…

android 删除系统原有的debug.keystore,系统运行的时候,重新生成新的debug.keystore,来完成App的运行。

1、先上一个图&#xff1a;这个是keystore无效的原因 之前在安装这个旧版本android studio的时候呢&#xff0c;安装过一版最新的android studio&#xff0c;然后通过模拟器跑过测试的demo。 2、运行旧的项目到模拟器的时候&#xff0c;就报错了&#xff1a; Execution failed…

proteus+51单片机+AD/DA学习5

目录 1.DA转换原理 1.1基本概念 1.1.1DA的简介 1.1.2DA0832芯片 1.1.3PCF8591芯片 1.2代码 1.2.1DAC8053的代码 1.2.2PCF8951的代码 1.3仿真 1.3.1DAC0832的仿真 1.3.2PFC8951的仿真 2.AD转换原理 2.1AD的基本概念 2.1.1AD的简介 2.1.2ADC0809的介绍 2.1.3XPT2…

双指针算法专题(1)

找往期文章包括但不限于本期文章中不懂的知识点&#xff1a; 个人主页&#xff1a;我要学编程(ಥ_ಥ)-CSDN博客 所属专栏&#xff1a; 优选算法专题 目录 双指针算法的介绍 283. 移动零 1089. 复写零 202. 快乐数 11.盛最多水的容器 双指针算法的介绍 在正式做题之前&a…

C++ 获取文件夹下的全部文件及指定文件(代码)

文章目录 1.&#xff08;C17&#xff09;获得指定目录下的所有文件&#xff08;不搜索子文件夹&#xff09;2.&#xff08;C11&#xff09;获得指定目录下的所有文件&#xff08;不搜索子文件夹&#xff09;3.&#xff08;C11&#xff09;获取目录下指定格式的所有文件&#xf…

工厂安灯系统在优化生产流程上的优势

工厂安灯系统通过可视化的方式&#xff0c;帮助工厂管理者和操作工人及时了解生产状态&#xff0c;快速响应问题&#xff0c;从而优化生产流程。 一、安灯系统实时监控与反馈 安灯系统的核心功能是实时监控生产线的状态。通过在生产现场设置灯光、显示屏等设备&#xff0c;工人…

OpenGL(四) 纹理贴图

几何模型&材质&纹理 渲染一个物体需要&#xff1a; 几何模型&#xff1a;决定了物体的形状材质&#xff1a;绝对了当灯光照到上面时的作用效果纹理&#xff1a;决定了物体的外观 纹理对象 纹理有2D的&#xff0c;有3D的。2D图像就是一张图片&#xff0c;3D图像是在…

记得忘记密码情况下如何退出苹果Apple ID

在日常使用苹果手机时&#xff0c;我们可能会遇到需要退出Apple ID的情况&#xff0c;比如更换手机、不再使用某些服务或出于安全考虑等。下面&#xff0c;我们就来详细介绍一下苹果手机如何退出Apple ID。 情况一&#xff1a;记得Apple ID密码 若是记得Apple ID密码&#xff…

3. 轴指令(omron 机器自动化控制器)——>MC_HomeWithParameterMC_Move

机器自动化控制器——第三章 轴指令 3 MC_HomeWithParameter变量▶输入变量▶输出变量 功能说明▶原点复位动作与原点复位参数的关系▶重启运动指令▶多重启动运动指令▶错误代码 MC_Move变量▶输入变量▶输出变量▶输入输出变量 功能说明▶指令详情▶重启运动指令▶多重启动运…

pytorch入门(1)——pytorch加载数据初认识

环境配置及其安装&#xff1a; 2023最新pytorch安装&#xff08;超详细版&#xff09;-CSDN博客 pytorch加载数据初认识 Dataset&#xff1a;创建可被Pytorch使用的数据集 提供一种方式获取数据及其label Dataloader&#xff1a;向模型传递数据 为网络提供不同的数据形式 …