Audio AudioPolicy

一、AudioPolicy相关类

AudioPolicy是Android系统中的一个音频策略管理框架,它的主要目的是协调各种声音音频流的输出,以保证音频资源按照预期的方式和优先级分配和管理,为用户提供良好的音频体验。在Android系统中,每个应用程序都可以使用音频资源(输入/输出)来播放声音、录制声音或者执行音频处理等操作。因此,当多个应用程序同时请求音频资源时,需要有一个主管部门来分配和管理这些资源,这就是AudioPolicy。

针对与Car, Android 将音频策略部分,通过提供外部(app 层)注入的方式,放在更加灵活的 app java层来实现。

以前的android基本为了手机设计,输出设备相对较少也不会给应用来控制,应用只是给一个stream类型,由AudioPolicy在底层根据你的stream类型偷偷地给你选一个设备,现在android要用于车机,发现这些音频设备变多了,手机上的那一套做很难满足需求,为了即保留对原来手机的逻辑支持,有可在车机上自定义更高级的策略玩法,于是想了个办法,把所有设备对应什么用途这些定义不再是直接写在AudioPolicy里面了,而是可以通过函数的方式注入进来,这样这些设备用途的定义,都可以放在更加灵活的app层面来做,并且不光是设备的usage定义,还有音量控制,音频焦点请求等这些逻辑一样,都可以先把回调注入 进来。

如此,对于手机上的场景,可以使用默认的策略,对于汽车,只需要再添加一个app,把新的策略注册进去即可覆盖替换原先的策略。 这个支持app层注册音频规则和控制回调的策略,即动态策略,它包括了 设备选择(mix规则)、音量控制(分频分区域控制音量)、音频焦点申请这三个策略。

AudioPolicy的主要作用如下:

1、分配音频流:根据优先和使用场景等信息,将不同应用程序的音频请求分配到合适的硬件模块上,保证音频播放的流畅性和稳定性。

2、控制音频焦点:通过定义音频焦点的概念,控制多个应用程序之间的音频焦点的转移,以保证应用程序音频资源的使用效率。

3、优化音频资源利用:针对不同的硬件和应用场景,合理配置音频设备路径,对各种类型的音频请求进行分类和度量,以最大化利用系统中的音频资源。

4、管理音频设备状态:清晰地了解各种音频设备的当前状态,根据硬件信息和音频请求的不同等因素,动态调整音频设备的连接和传输方式,保证音频传输的稳定性和高效性。

5、管理音量和音频效果:通过生成音量曲线和设置各种音频效果,实现对音量、音频均衡器等参数的有效管理和控制。

AudioPolicy有许多类,包括:

AIDL:

  • AudioPolicyConfig.aidl

  • AudioProductStrategy.aidl

  • AudioVolumeGroup.aidl

  • AudioPolicyDeviceState.aidl

  • AudioPolicyForcedConfig.aidl

  • AudioPolicyForceUse.aidl

  • IAudioPolicyCallback.aidl

  • IAudioPolicyService.aidl

  • IAudioPolicyServiceClient.aidl

JAVA类(frameworks/base/media/java/android/media/audiopolicy):

  • AudioPolicy 定义系统与应用程序之间的音频路由及策略

  • AudioPolicyConfig 保存音频策略信息,包括硬件模块,输入/输出设备,音量曲线等

  • AudioMix 对AudioMixingRule和AudioFormat的封装

  • AudioMixingRule 描述音频流输出策略

  • AudioProductStrategy 用于封装与给定产品策略关联的属性集合(出于传统原因,保持与流类型的关联)

  • AudioVolumeGroup 用于创建不同播放属性(例如媒体)与单个音量控件之间的关联。

  • AudioVolumeGroupChangeHandler

C++类( frameworks/av/services/audiopolicy):

  • AudioPolicyClientImpl AudioPolicy的客户端实现

  • AudioPolicyInterfaceImpl AudioPolicyService的实现接口

  • AudioPolicyService 音频策略服务

  • AudioPolicyManager 提供的默认音频策略或路由信息

  • AudioInputDescriptor 音频输入的描述符

  • AudioOutputDescriptor 音频输出的描述符

  • AudioPolicyEffects 用于管理音频效果

  • VolumeCurve 用于描述解析出的音频曲线的具体数值

  • AudioPatch 用于表示音频中端到端的连接关系

  • AudioRoute 用于描述音频信号从输入到输出的路径

  • AudioPolicyMix 用于管理音频流的混音

  • IOProfile 记录了当前所能支持的设备

  • PolicyAudioPort 一个音频策略相关的对象,它包含了一个音频端口(AudioPort)的属性和状态信息

  • Serializer 用于解析audio_policy_configuration.xml

  • DeviceDescriptor 设备的描述,记录设备的地址和设备类型,并与 IOProfile都继承了AudioPort

  • ClientDescriptor

  • EffectDescriptor

  • CaptureStateNotifier

  • SpatializerPoseController

  • EngineBase

  • LastRemovableMediaDevices

  • ProductStrategy

  • VolumeGroup

  • Engine

  • EngineInstance

  • InputSource

  • Stream

  • AudioCollections

  • AudioProfileVectorHelper

  • HwModule

  • SoundTriggerSession

  • TypeConverter

1、JAVA类

AudioPolicy

定义系统与应用程序之间的音频路由及策略。

AudioPolicy代码位于:

frameworks/base/media/java/android/media/audiopolicy/AudioPolicy.java

frameworks/base/media/java/android/media/audiopolicy/IAudioPolicyCallback.aidl

AudioPolicy 的定义:

public class AudioPolicy {
    public static class Builder {}
    public static abstract class AudioPolicyStatusListener {}
    public static abstract class AudioPolicyFocusListener {
        public void onAudioFocusGrant(AudioFocusInfo afi, int requestResult) {}
        public void onAudioFocusLoss(AudioFocusInfo afi, boolean wasNotified) {}
        public void onAudioFocusRequest(AudioFocusInfo afi, int requestResult) {}
        public void onAudioFocusAbandon(AudioFocusInfo afi) {}
    }
    public static abstract class AudioPolicyVolumeCallback {}
    private class EventHandler extends Handler {}
}

AudioPolicyConfig

保存音频策略信息,包括硬件模块,输入/输出设备,音量曲线等。

AudioPolicyConfig代码位于:

frameworks/base/media/java/android/media/audiopolicy/AudioPolicyConfig.java

frameworks/base/media/java/android/media/audiopolicy/AudioPolicyConfig.aidl

AudioPolicyConfig的定义:

public class AudioPolicyConfig implements Parcelable {}

AudioMix

AudioMix是对AudioMixingRule和AudioFormat的封装。AudioMixingRule用于描述音频流输出策略。

AudioMix代码位于:

frameworks/base/media/java/android/media/audiopolicy/AudioMix.java

frameworks/base/media/java/android/media/audiopolicy/AudioMixingRule.java

AudioMix的定义:

public class AudioMix {}

AudioVolumeGroup

用于创建不同播放属性(例如媒体)与单个音量控件之间的关联。

AudioVolumeGroup代码位于:

frameworks/base/media/java/android/media/audiopolicy/AudioVolumeGroup.java

frameworks/base/media/java/android/media/audiopolicy/AudioVolumeGroupChangeHandler.java

frameworks/base/media/java/android/media/audiopolicy/AudioVolumeGroup.aidl

AudioVolumeGroup的定义:

public final class AudioVolumeGroup implements Parcelable {}
public class AudioVolumeGroupChangeHandler {}

AudioProductStrategy

用于封装与给定产品策略关联的属性集合(出于传统原因,保持与流类型的关联)。

AudioProductStrategy代码位于:

frameworks/base/media/java/android/media/audiopolicy/AudioProductStrategy.java

frameworks/base/media/java/android/media/audiopolicy/AudioProductStrategy.aidl

AudioProductStrategy的定义:

public final class AudioVolumeGroup implements Parcelable {}
public class AudioVolumeGroupChangeHandler {}

2、C++类

AudioPolicyService

AudioPolicyService是Android系统中的一个服务,其封装了音频策略和音频输出通道,AudioPolicyService会使用AudioPolicyManager提供的默认音频策略或路由信息。

AudioPolicyService代码位于:

frameworks/av/media/libaudioclient/aidl/android/media/IAudioPolicyServiceClient.aidl

frameworks/av/media/libaudioclient/aidl/android/media/IAudioPolicyService.aidl

frameworks/av/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp

frameworks/av/services/audiopolicy/service/AudioPolicyClientImpl.cpp

frameworks/av/services/audiopolicy/service/AudioPolicyService.cpp

frameworks/av/services/audiopolicy/service/AudioPolicyService.h

AudioPolicyService的定义:

oneway interface IAudioPolicyServiceClient {}
interface IAudioPolicyService {}
class AudioPolicyClientInterface {}
class AudioPolicyClient : public AudioPolicyClientInterface {}
class AudioPolicyService : public BinderService<AudioPolicyService>, public media::BnAudioPolicyService, public IBinder::DeathRecipient, public SpatializerPolicyCallback {}

AudioPolicyManager

AudioPolicyManager负责管理音频输入和输出源、音量控制、音频通道配置和音频效果等默认的音频策略和路由定义。

AudioPolicyManager代码位于:

frameworks/av/services/audiopolicy/managerdefault/AudioPolicyManager.cpp

frameworks/av/services/audiopolicy/managerdefault/AudioPolicyManager.h

AudioPolicyManager的定义:

class AudioPolicyManager : public AudioPolicyInterface, public AudioPolicyManagerObserver {}
class AudioPolicyManagerObserver {}

VolumeGroup

VolumeGroup定义了一个音量组,描述了该组中的音频流类型、音量设置范围、音量调整规则等。在Android系统中,每个音频流类型都对应一个VolumeGroup对象,该对象包含了该音频流类型的所有音量控制相关参数。

VolumeGroup代码位于:

frameworks/av/services/audiopolicy/engine/common/src/VolumeGroup.cpp

frameworks/av/services/audiopolicy/engine/common/include/VolumeGroup.h

VolumeGroup的定义:

class VolumeGroup : public virtual RefBase, private HandleGenerator<uint32_t> {}
class VolumeGroupMap : public std::map<volume_group_t, sp<VolumeGroup> > {}

VolumeCurve

VolumeCurve用于计算在给定音量范围内的实际音量值,它包括一个标准音量范围和一个可选的增益表。

VolumeCurve代码位于:

frameworks/av/services/audiopolicy/engine/common/src/VolumeCurve.cpp

frameworks/av/services/audiopolicy/engine/common/include/VolumeCurve.h

frameworks/av/services/audiopolicy/common/managerdefinitions/include/IVolumeCurves.h

VolumeCurve的定义:

class VolumeCurve : public RefBase {}

AudioPolicyEffects

AudioPolicyEffects用于管理音频效果,它包含了所有音频效果的描述,以及控制每一个效果在音频处理路径上的插入和移除。

AudioPolicyEffects代码位于:

frameworks/av/services/audiopolicy/service/AudioPolicyEffects.cpp

frameworks/av/services/audiopolicy/service/AudioPolicyEffects.h

AudioPolicyEffects的定义:

class AudioPolicyEffects : public RefBase {}

AudioOutputDescriptor

AudioOutputDescriptor是音频输出的描述符。用于维护每个打开的音频输出的当前配置,并跟踪每个音频流类型对此输出的使用情况。

AudioOutputDescriptor代码位于:

frameworks/av/services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp

frameworks/av/services/audiopolicy/common/managerdefinitions/include/AudioOutputDescriptor.h

AudioOutputDescriptor的定义:

class ActivityTracking {}
class VolumeActivity : public ActivityTracking {}
class RoutingActivity : public ActivityTracking {}
class AudioOutputDescriptor: public AudioPortConfig, public PolicyAudioPortConfig,
        public AudioIODescriptorInterface, public ClientMapHandler<TrackClientDescriptor> {}
class SwAudioOutputDescriptor: public AudioOutputDescriptor {}
class HwAudioOutputDescriptor: public AudioOutputDescriptor {}
class SwAudioOutputCollection : public DefaultKeyedVector< audio_io_handle_t, sp<SwAudioOutputDescriptor> > {}
class HwAudioOutputCollection : public DefaultKeyedVector< audio_io_handle_t, sp<HwAudioOutputDescriptor> > {}

AudioInputDescriptor

AudioInputDescriptor是音频输入的描述符。用于维护每个打开的音频输入的当前配置并跟踪此输入的使用情况。

AudioInputDescriptor代码位于:

frameworks/av/services/audiopolicy/common/managerdefinitions/src/AudioInputDescriptor.cpp

frameworks/av/services/audiopolicy/common/managerdefinitions/include/AudioInputDescriptor.h

AudioInputDescriptor的定义:

class AudioInputDescriptor: public AudioPortConfig, public PolicyAudioPortConfig,
        public AudioIODescriptorInterface, public ClientMapHandler<RecordClientDescriptor> {}

AudioPatch

从Android5.0之后,AOSP引入了AudioPatch概念,用于表示音频中端到端的连接关系。从代码中推测,AudioPatch主要用于连接source与sink。这里的source,既可以是实实在在的音频输入设备,如MIC,也可以是底层中混音后的音频流;这里的sink则表示输出设备,如扬声器、耳机等。

引入这个概念以后,对音频来讲,显然抽象程度更高,更容易理解宏观上的概念,如插拔耳机时,只要更换连接就可以,但更不易理解实现的细节,如音频数据在插拔耳机时如何运送到新设备上。

AudioPatch代码位于:

frameworks/av/services/audiopolicy/common/managerdefinitions/src/AudioPatch.cpp

frameworks/av/services/audiopolicy/common/managerdefinitions/include/AudioPatch.h

AudioPatch的定义:

class AudioPatch : public RefBase, private HandleGenerator<audio_patch_handle_t> {}

AudioRoute

AudioRoute用于描述音频信号从输入到输出的路径,包括路径上的模块和设备等信息,在AudioPolicy中,可以通过AudioRoute来精选音频流的路由和设备的选择,以确保正确的音频数据在正确的时候从正确的设备播放出来。

AudioRoute代码位于:

frameworks/av/services/audiopolicy/common/managerdefinitions/src/AudioRoute.cpp

frameworks/av/services/audiopolicy/common/managerdefinitions/include/AudioRoute.h

AudioRoute的定义:

class AudioRoute  : public virtual RefBase {}

AudioPolicyMix

AudioPolicyMix用于管理音频流的混音。

AudioPolicyMix代码位于:

frameworks/av/services/audiopolicy/common/managerdefinitions/src/AudioPolicyMix.cpp

frameworks/av/services/audiopolicy/common/managerdefinitions/include/AudioPolicyMix.h

AudioPolicyMix的定义:

class AudioPolicyMix : public AudioMix, public RefBase {}
class AudioPolicyMixCollection : public Vector<sp<AudioPolicyMix>> {}

PolicySerializer

PolicySerializer用于解析audio_policy_configuration.xml得到HwModule 的集合。

Serializer代码位于:

frameworks/av/services/audiopolicy/common/managerdefinitions/src/Serializer.cpp

frameworks/av/services/audiopolicy/common/managerdefinitions/include/Serializer.h

Serializer的定

class PolicySerializer {}

PolicyAudioPort

PolicyAudioPort是一个音频策略相关的对象,它包含了一个音频端口(AudioPort)的属性和状态信息,并定义了一组用于管理这些音频端口的策略。

PolicyAudioPort代码位于:

frameworks/av/services/audiopolicy/common/managerdefinitions/src/PolicyAudioPort.cpp

frameworks/av/services/audiopolicy/common/managerdefinitions/include/PolicyAudioPort.h

PolicyAudioPort的定义:

class PolicyAudioPort : public virtual RefBase, private HandleGenerator<audio_port_handle_t> {}
class PolicyAudioPortConfig : public virtual RefBase {}

IOProfile

可以理解记录了当前所能支持的设备,这个是通过 Serializer.cpp里的AudioRoute解析获取的。

IOProfile代码位于:

frameworks/av/services/audiopolicy/common/managerdefinitions/src/IOProfile.cpp

frameworks/av/services/audiopolicy/common/managerdefinitions/include/IOProfile.h

IOProfile的定义:

class IOProfile : public AudioPort, public PolicyAudioPort {}

DeviceDescriptor

设备的描述,记录设备的地址和设备类型,并与 IOProfile都继承了AudioPort。

DeviceDescriptor代码位于:

frameworks/av/services/audiopolicy/common/managerdefinitions/src/DeviceDescriptor.cpp

frameworks/av/services/audiopolicy/common/managerdefinitions/include/DeviceDescriptor.h

DeviceDescriptor的定义:

class DeviceDescriptor : public DeviceDescriptorBase, public PolicyAudioPort, public PolicyAudioPortConfig {}
class DeviceVector : public SortedVector<sp<DeviceDescriptor> > {}

HwModule

HwModule代码位于:

frameworks/av/services/audiopolicy/common/managerdefinitions/src/HwModule.cpp

frameworks/av/services/audiopolicy/common/managerdefinitions/include/HwModule.h

HwModule的定义:

class HwModule : public RefBase {}

AudioPolicyEngine

AudioPolicyEngine是Android系统中的一个音频处理引擎,它通过音频策略来处理和控制音频的输入和输出,AudioPolicyEngine代码位于:

frameworks/av/services/audiopolicy/engine/common/src/EngineBase.cpp

frameworks/av/services/audiopolicy/engine/common/src/LastRemovableMediaDevices.cpp

frameworks/av/services/audiopolicy/engine/common/src/ProductStrategy.cpp

frameworks/av/services/audiopolicy/engine/common/src/EngineDefaultConfig.h

frameworks/av/services/audiopolicy/engine/common/include/EngineBase.h

frameworks/av/services/audiopolicy/engine/common/include/LastRemovableMediaDevices.h

frameworks/av/services/audiopolicy/engine/common/include/ProductStrategy.h

frameworks/av/services/audiopolicy/engine/config/src/EngineConfig.cpp

frameworks/av/services/audiopolicy/engine/config/include/EngineConfig.h

frameworks/av/services/audiopolicy/engine/interface/EngineInterface.h

frameworks/av/services/audiopolicy/engine/interface/AudioPolicyManagerObserver.h

frameworks/av/services/audiopolicy/engineconfigurable/src/Engine.cpp

frameworks/av/services/audiopolicy/engineconfigurable/src/EngineInstance.cpp

frameworks/av/services/audiopolicy/engineconfigurable/src/InputSource.cpp

frameworks/av/services/audiopolicy/engineconfigurable/src/Stream.cpp

frameworks/av/services/audiopolicy/engineconfigurable/src/Collection.h

frameworks/av/services/audiopolicy/engineconfigurable/src/Element.h

frameworks/av/services/audiopolicy/engineconfigurable/src/Engine.h

frameworks/av/services/audiopolicy/engineconfigurable/src/InputSource.h

frameworks/av/services/audiopolicy/engineconfigurable/src/Stream.h

frameworks/av/services/audiopolicy/engineconfigurable/include/AudioPolicyEngineInstance.h

frameworks/av/services/audiopolicy/engineconfigurable/include/EngineDefinition.h

frameworks/av/services/audiopolicy/engineconfigurable/interface/AudioPolicyPluginInterface.h

frameworks/av/services/audiopolicy/enginedefault/src/Engine.cpp

frameworks/av/services/audiopolicy/enginedefault/src/EngineInstance.cpp

frameworks/av/services/audiopolicy/enginedefault/src/Engine.h

Oher

frameworks/av/media/libaudioclient/aidl/android/media/AudioPolicyDeviceState.aidl

frameworks/av/media/libaudioclient/aidl/android/media/AudioPolicyForcedConfig.aidl

frameworks/av/media/libaudioclient/aidl/android/media/AudioPolicyForceUse.aidl

frameworks/av/services/audiopolicy/service/CaptureStateNotifier.cpp

frameworks/av/services/audiopolicy/service/Spatializer.cpp

frameworks/av/services/audiopolicy/service/SpatializerPoseController.cpp

frameworks/av/services/audiopolicy/service/BinderProxy.h

frameworks/av/services/audiopolicy/service/CaptureStateNotifier.h

frameworks/av/services/audiopolicy/service/Spatializer.h

frameworks/av/services/audiopolicy/service/SpatializerPoseController.h

frameworks/av/services/audiopolicy/common/include/policy.h

frameworks/av/services/audiopolicy/common/include/Volume.h

frameworks/av/services/audiopolicy/common/managerdefinitions/src/AudioCollections.cpp

frameworks/av/services/audiopolicy/common/managerdefinitions/src/AudioProfileVectorHelper.cpp

frameworks/av/services/audiopolicy/common/managerdefinitions/src/ClientDescriptor.cpp

frameworks/av/services/audiopolicy/common/managerdefinitions/src/EffectDescriptor.cpp

frameworks/av/services/audiopolicy/common/managerdefinitions/src/SoundTriggerSession.cpp

frameworks/av/services/audiopolicy/common/managerdefinitions/src/TypeConverter.cpp

frameworks/av/services/audiopolicy/common/managerdefinitions/include/AudioCollections.h

frameworks/av/services/audiopolicy/common/managerdefinitions/include/AudioProfileVectorHelper.h

frameworks/av/services/audiopolicy/common/managerdefinitions/include/ClientDescriptor.h

frameworks/av/services/audiopolicy/common/managerdefinitions/include/EffectDescriptor.h

frameworks/av/services/audiopolicy/common/managerdefinitions/include/SoundTriggerSession.h

frameworks/av/services/audiopolicy/common/managerdefinitions/include/TypeConverter.h

二、audiopolicy流程

audiopolicy是音频的一个策略管理,主要负责通过配置文件和代码初始化后得到配置数据;用于决策音频数据进入具体的输出通道,如图中描述音频配置的数据结构:

通过AudioPolciyManager初始化的时候,通过 Serializer.cpp解析audio_policy_configuration.xml得到HwModule 的集合。xml与数据模型对应关系如下表格:

xmlclass描述

module

HwModule

模块

mixPort

IOProfile

IO概述AUDIO_PORT_ROLE_SOURCE

profile

AudioProfile

音频的格式参数

devicePort

DeviceDescriptor

设备描述AUDIO_PORT_ROLE_SINK

gain

AudioGain

音频的增益

route

AudioRoute

音频的路线

attachedDevices

DeviceDescriptor

绑定模块的设备

defaultOutputDevice

DeviceDescriptor

默认的输出设备

IOProfile:可以理解记录了当前所能支持的设备,这个是通过 Serializer.cpp里的AudioRoute解析获取的。

DeviceDescriptor:设备的描述,记录设备的地址和设备类型,并与 IOProfile都继承了AudioPort。

AudioRoute:代表音频的线路, 可以连接 IOProfile和DeviceDescriptor的关系

OpenOutput Devices流程

待更新

OpenInput Devices流程

待更新

  • 26
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
audiopolicy指的是音频策略,是指在计算机系统中对音频资源进行管理和控制的一种机制。它通过定义一系列规则和策略,决定音频设备的分配、使用、优先级等方面,以确保音频资源的合理利用和音频服务的高效运行。 audiopolicy具体负责的内容包括以下几个方面: 1. 音频设备管理:audiopolicy会监控计算机系统中的各种音频设备,如扬声器、麦克风等,对其进行管理和控制。它会检测设备的状态、连接状况等,并根据系统的需要进行设备的自动切换和配置。 2. 音频资源分配:audiopolicy会根据各个应用程序的需求和优先级,对音频资源进行分配。它可以确定哪个应用程序可以在某个时间段内占用音频设备,从而协调各应用程序之间的音频资源竞争。 3. 音频服务管理:audiopolicy会管理和监控各类音频服务,如播放器、通话、语音助手等。它会确保这些音频服务之间的合理协同和资源共享,避免冲突和互相干扰。 4. 音频优化和调节:audiopolicy可以对音频进行优化和调节,以提供更好的音频体验。它可以根据设备的特性和用户的喜好,对音频进行音量调节、音色调整等,以满足用户的需求。 总之,audiopolicy是计算机系统中的一个重要组成部分,它通过管理和控制音频资源,为用户提供高质量的音频服务,并确保各应用程序之间的音频资源竞争和协同。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值