当前位置: 首页 > news >正文

零基础入门多媒体音频(2)-音频焦点2

说实话,android的代码是越来越难以阅读。业务函数里面狗皮膏药似的补丁与日俱增。继上篇简要介绍音频焦点的文章,这篇文章的主要内容是分析audiofocus的实现。看了一下午的相关代码都没找到做audiofocus策略的核心逻辑。目前能看懂的大概包含下面两个逻辑。欢迎评论区沟通。

audiofocus实现的核心代码是在project_dir/frameworks/base/services/core/java/com/android/server/audio/MediaFocusControl.java
project_dir/frameworks/base/services/core/java/com/android/server/audio/FocusRequester.java
project_dir在这里指代android源码的根目录。

1.MediaFocusControl会维护所有audiofocus申请信息的堆栈mFocusStack。
2.android当系统进入铃声或者通话状态,会静音住媒体播放器,代码片段如下,mRingOrCallActive变量会在应用申请焦点时进行判断刷新。

if (mRingOrCallActive) {mFocusEnforcer.mutePlayersForCall(USAGES_TO_MUTE_IN_RING_OR_CALL);} else {mFocusEnforcer.unmutePlayersForCall();}

3.audiofocus的监听器都是在AudioManager的队列里维护。代码如下:

    public void registerAudioFocusRequest(@NonNull AudioFocusRequest afr) {final Handler h = afr.getOnAudioFocusChangeListenerHandler();final FocusRequestInfo fri = new FocusRequestInfo(afr, (h == null) ? null :new ServiceEventHandlerDelegate(h).getHandler());final String key = getIdForAudioFocusListener(afr.getOnAudioFocusChangeListener());mAudioFocusIdListenerMap.put(key, fri);}

4.audiomanager进行焦点变化通知的核心类IAudioFocusDispatcher会调用listener。IAudioFocusDispatcher
自身会被注册给audioservice。

                status = service.requestAudioFocus(afr.getAudioAttributes(),afr.getFocusGain(), mICallBack,mAudioFocusDispatcher,clientId,getContext().getOpPackageName() /* package name */, afr.getFlags(),ap != null ? ap.cb() : null,sdk);

阅读代码期间出现重大错误,阅读函数handleFocusLossFromGain的时候,认为gain是增益的含义,没仔细阅读实现。导致增加阅读理解代码的时间周期。gain在这里应该是对应焦点的第一种类型,永久性焦点。犯了惯性思维的错误。遇到这种与认知相悖的地方应该更加小心。gain在这块代码里面的含义是获得,与之对应的是loss。

androidaudio进行audiofocus控制决策的核心代码是下面这一段

            if (mMultiAudioFocusEnabled&& (focusChangeHint == AudioManager.AUDIOFOCUS_GAIN)) {if (enteringRingOrCall) {if (!mMultiAudioFocusList.isEmpty()) {for (FocusRequester multifr : mMultiAudioFocusList) {multifr.handleFocusLossFromGain(focusChangeHint, nfr, forceDuck);}}} else {boolean needAdd = true;if (!mMultiAudioFocusList.isEmpty()) {for (FocusRequester multifr : mMultiAudioFocusList) {if (multifr.getClientUid() == Binder.getCallingUid()) {needAdd = false;break;}}}if (needAdd) {mMultiAudioFocusList.add(nfr);}nfr.handleFocusGainFromRequest(AudioManager.AUDIOFOCUS_REQUEST_GRANTED);notifyExtPolicyFocusGrant_syncAf(nfr.toAudioFocusInfo(),AudioManager.AUDIOFOCUS_REQUEST_GRANTED);return AudioManager.AUDIOFOCUS_REQUEST_GRANTED;}}

思考android Audio focus的设计时,我想到一个问题,如果某APP,先申请media类型的focus,然后再去申请call类型的focus会怎么样?

相关文章:

零基础入门多媒体音频(2)-音频焦点2

说实话,android的代码是越来越难以阅读。业务函数里面狗皮膏药似的补丁与日俱增。继上篇简要介绍音频焦点的文章,这篇文章的主要内容是分析audiofocus的实现。看了一下午的相关代码都没找到做audiofocus策略的核心逻辑。目前能看懂的大概包含下面两个逻辑…...

Spark杂谈

文章目录 什么是Spark对比HadoopSpark应用场景Spark数据处理流程什么是RDDSpark架构相关进程入门案例:统计单词数量Spark开启historyServer 什么是Spark Spark是一个用于大规模数据处理的统一计算引擎Spark一个重要的特性就是基于内存计算,从而它的速度…...

【PyTorch】进阶学习:一文详细介绍 torch.save() 的应用场景、实战代码示例

【PyTorch】进阶学习:一文详细介绍 torch.save() 的应用场景、实战代码示例 🌈 个人主页:高斯小哥 🔥 高质量专栏:Matplotlib之旅:零基础精通数据可视化、Python基础【高质量合集】、PyTorch零基础入门教程…...

私域流量运营的关键要素和基本步骤

解锁增长的四大关键: 关键要素一:精准营销 精准营销是私域流量运营的核心所在。通过精细化运营和个性化服务,企业可以将普通用户转化为忠实粉丝,提高用户的粘性和转化率。采用数据驱动的精准营销策略,深度挖掘用户需求…...

k8s部署hadoop

(作者:陈玓玏) 配置和模板参考helm仓库:https://artifacthub.io/packages/helm/apache-hadoop-helm/hadoop 先通过以下命令生成yaml文件: helm template hadoop pfisterer-hadoop/hadoop > hadoop.yaml用kube…...

deepspeed分布式训练在pytorch 扩展(PyTorch extensions)卡住

错误展示: Using /root/.cache/torch_extensions/py310_cu121 as PyTorch extensions root...
 Using /root/.cache/torch_extensions/py310_cu121 as PyTorch extensions root...
 错误表现: 出现在多卡训练过程的pytorch 扩展,deepspee…...

Rust 的 HashMap

在 Rust 中,HashMap 是一个从键(key)映射到值(value)的数据结构。它允许你以 O(1) 的平均时间复杂度存储、检索和删除键值对。HashMap 实现了 std::collections::HashMap 结构体,通常通过 use std::collect…...

exporter方式监控达梦数据库

蓝鲸监控 随着国产化和信创的深入,开始普遍使用国产化数据库–如达梦数据库,蓝鲸平台默认没有对其进行监控,但是平台了提供监控告警的能力。比如脚本采集,脚本的是一种灵活和快速的监控采集方式,不同层的监控对象都可…...

供应链安全之被忽略的软件质量管理平台安全

背景 随着我国信息化进程加速,网络安全问题更加凸显。关键信息基础设施和企业单位在满足等保合规的基础上,如何提升网络安全防御能力,降低安全事件发生概率?默安玄甲实验室针对SonarQube供应链安全事件进行分析,强调供…...

python入门(二)

python的安装很方便,我们这里就不再进行讲解,大家可以自己去搜索视频。下面分享一下Python的入门知识点。 执行命令的方式 在安装好python后,有两种方式可以执行命令: 命令行程序文件,后缀名为.py 对于命令行&…...

Mysql,MongoDB,Redis的横纵向对比

一,什么是Mysql Mysql是一款安全,可以跨平台,高效率的数据库系统,运行速度高,安全性能高,支持面向对象,安全性高,并且成本比较低,支持各种开发语言,数据库的存储容量大,有许多的内置函数。 二,什么是MongoDB MongoDB是基于分布式文件存储的数据库,是一个介于关…...

css3 实现html样式蛇形布局

文章目录 1. 实现效果2. 实现代码 1. 实现效果 2. 实现代码 <template><div class"body"><div class"title">CSS3实现蛇形布局</div><div class"list"><div class"item" v-for"(item, index) …...

基于消失点的相机自标定

基于消失点的相机自标定 附赠最强自动驾驶学习资料&#xff1a;直达链接 相机是通过透视投影变换来将3D场景转换为2D图像。在射影变换中&#xff0c;平行线相交于一点称之为消失点。本文详细介绍了两种利用消失点特性的标定方法。目的是为根据实际应用和初始条件选择合适的标…...

Python:filter过滤器

filter() 是 Python 中的一个内置函数&#xff0c;用于过滤序列&#xff0c;过滤掉不符合条件的元素&#xff0c;返回由符合条件元素组成的新列表。该函数接收两个参数&#xff0c;一个是函数&#xff0c;一个是序列&#xff0c;序列的每个元素作为参数传递给函数进行判定&…...

Python函数学习

Python函数学习 1.函数定义 在函数定义阶段只检查函数的语法问题 2.实参形参 ​​​​总结&#xff1a; &#xff08;1&#xff09;位置参数就是经常用的按照位置顺序给出实参的值&#xff1b; &#xff08;2&#xff09;关键字实参形式&#xff1a;key123&#xff1b;放在…...

IDEA中的Project工程、Module模块的概念及创建导入

1、IDEA中的层级关系&#xff1a; project(工程) - module(模块) - package(包) - class(类)/接口具体的&#xff1a; 一个project中可以创建多个module一个module中可以创建多个package一个package中可以创建多个class/接口2、Project和Module的概念&#xff1a; 在 IntelliJ …...

如何快速下载并剪辑B站视频

1、B站手机端右上角缓存视频&#xff1b; 2、在手机文件管理助手中找到android/data/80找到两个文件&#xff0c;video.m4s和audio.m4s&#xff0c;将它们发送到电脑&#xff0c;系统会默认保存在你的个人文件夹里&#xff0c;C:\users\用户名 3、下载ffmepg https://blog.cs…...

智慧矿山新趋势:大数据解决方案一览

1. 背景 随着信息技术的快速发展和矿山管理需求的日益迫切&#xff0c;智慧矿山作为一种创新的矿山管理方式应运而生。智慧矿山借助先进的信息技术&#xff0c;实现对矿山生产、管理、安全等各方面的智能化、高效化、协同化&#xff0c;是矿山行业转型升级的必然趋势。 欢迎关…...

Ubuntu使用Docker部署Nginx容器并结合内网穿透实现公网访问本地服务

目录 ⛳️推荐 1. 安装Docker 2. 使用Docker拉取Nginx镜像 3. 创建并启动Nginx容器 4. 本地连接测试 5. 公网远程访问本地Nginx 5.1 内网穿透工具安装 5.2 创建远程连接公网地址 5.3 使用固定公网地址远程访问 ⛳️推荐 前些天发现了一个巨牛的人工智能学习网站&#…...

面试笔记——Redis(使用场景、面临问题、缓存穿透)

Redis的使用场景 Redis&#xff08;Remote Dictionary Server&#xff09;是一个内存数据结构存储系统&#xff0c;它以快速、高效的特性闻名&#xff0c;并且它支持多种数据结构&#xff0c;包括字符串、哈希表、列表、集合、有序集合等。它主要用于以下场景&#xff1a; 缓…...

STM32F4基本定时器使用和原理详解

STM32F4基本定时器使用和原理详解 前言如何确定定时器挂载在哪条时钟线上配置及使用方法参数配置PrescalerCounter ModeCounter Periodauto-reload preloadTrigger Event Selection 中断配置生成的代码及使用方法初始化代码基本定时器触发DCA或者ADC的代码讲解中断代码定时启动…...

(转)什么是DockerCompose?它有什么作用?

一、什么是DockerCompose? DockerCompose可以基于Compose文件帮我们快速的部署分布式应用&#xff0c;而无需手动一个个创建和运行容器。 Compose文件是一个文本文件&#xff0c;通过指令定义集群中的每个容器如何运行。 DockerCompose就是把DockerFile转换成指令去运行。 …...

零基础在实践中学习网络安全-皮卡丘靶场(第九期-Unsafe Fileupload模块)(yakit方式)

本期内容并不是很难&#xff0c;相信大家会学的很愉快&#xff0c;当然对于有后端基础的朋友来说&#xff0c;本期内容更加容易了解&#xff0c;当然没有基础的也别担心&#xff0c;本期内容会详细解释有关内容 本期用到的软件&#xff1a;yakit&#xff08;因为经过之前好多期…...

接口自动化测试:HttpRunner基础

相关文档 HttpRunner V3.x中文文档 HttpRunner 用户指南 使用HttpRunner 3.x实现接口自动化测试 HttpRunner介绍 HttpRunner 是一个开源的 API 测试工具&#xff0c;支持 HTTP(S)/HTTP2/WebSocket/RPC 等网络协议&#xff0c;涵盖接口测试、性能测试、数字体验监测等测试类型…...

NPOI Excel用OLE对象的形式插入文件附件以及插入图片

static void Main(string[] args) {XlsWithObjData();Console.WriteLine("输出完成"); }static void XlsWithObjData() {// 创建工作簿和单元格,只有HSSFWorkbook,XSSFWorkbook不可以HSSFWorkbook workbook new HSSFWorkbook();HSSFSheet sheet (HSSFSheet)workboo…...

Python 高效图像帧提取与视频编码:实战指南

Python 高效图像帧提取与视频编码:实战指南 在音视频处理领域,图像帧提取与视频编码是基础但极具挑战性的任务。Python 结合强大的第三方库(如 OpenCV、FFmpeg、PyAV),可以高效处理视频流,实现快速帧提取、压缩编码等关键功能。本文将深入介绍如何优化这些流程,提高处理…...

Monorepo架构: Nx Cloud 扩展能力与缓存加速

借助 Nx Cloud 实现项目协同与加速构建 1 &#xff09; 缓存工作原理分析 在了解了本地缓存和远程缓存之后&#xff0c;我们来探究缓存是如何工作的。以计算文件的哈希串为例&#xff0c;若后续运行任务时文件哈希串未变&#xff0c;系统会直接使用对应的输出和制品文件。 2 …...

【Qt】控件 QWidget

控件 QWidget 一. 控件概述二. QWidget 的核心属性可用状态&#xff1a;enabled几何&#xff1a;geometrywindows frame 窗口框架的影响 窗口标题&#xff1a;windowTitle窗口图标&#xff1a;windowIconqrc 机制 窗口不透明度&#xff1a;windowOpacity光标&#xff1a;cursor…...

大模型智能体核心技术:CoT与ReAct深度解析

**导读&#xff1a;**在当今AI技术快速发展的背景下&#xff0c;大模型的推理能力和可解释性成为业界关注的焦点。本文深入解析了两项核心技术&#xff1a;CoT&#xff08;思维链&#xff09;和ReAct&#xff08;推理与行动&#xff09;&#xff0c;这两种方法正在重新定义大模…...

DriveGPT4: Interpretable End-to-end Autonomous Driving via Large Language Model

一、研究背景与创新点 (一)现有方法的局限性 当前智驾系统面临两大核心挑战:一是长尾问题,即系统在遇到新场景时可能失效,例如突发交通状况或非常规道路环境;二是可解释性问题,传统方法无法解释智驾系统的决策过程,用户难以理解车辆行为的依据。传统语言模型(如 BERT…...