WebRTC Android API

【安卓开发实战】Webview RTC 适配:实现跨平台实时通信 WebRTC是一种支持网页浏览器进行实时语音对话或视频对话的技术,它包括了一系列的API,如音频捕获、视频捕获、网络通信等。WebRTC的目标是让实时通信变得更加简单和易用。Webview RTC适配是安卓开发中实现实时通信的关键技术。通过本文的讲解和示例,开发者可以更好地了解WebRTC技术在安卓平台上的适配问题和解决方案,为自己的应用实现高质量的实时通信功能。希望本文能对您的开发工作带来帮助。 阅读详情

WebRTC Android API

WebRTC For Android相关的API有VideoCapturerAndroid, VideoRenderer, MediaStream, PeerConnection 和 PeerConnectionFactory等。通过这些功能完善、说明详细的API,可以显示任何想要显示的本地音视频流和远程音视频流。下面我们将逐一讲解。

类图

WebRTC Android API类图


PeerConnectionFactory

PeerConnectionFactory是WebRTC Android API最核心的类。理解这个类并了解它如何使用是深入了解Android WebRTC开发的关键。
首先需要初始化PeerConnectionFactory,如下:

// First, we initiate the PeerConnectionFactory with
// our application context and some options.
PeerConnectionFactory.initializeAndroidGlobals(
context,
initializeAudio,
initializeVideo,
videoCodecHwAcceleration);

为了理解这个方法,需要了解每个参数的意义:

context
    应用上下文,或者上下文相关的,和其他地方传递的一样。

initializeAudio
    是否初始化音频的布尔值。

initializeVideo
    是否初始化视频的布尔值。跳过这两个就允许跳过请求API的相关权限,例如DataChannel应用。

videoCodecHwAcceleration
    是否允许硬件加速的布尔值。

initializeAndroidGlobals()返回布尔值,true表示一切OK,false表示有失败。

如果一切ok,可以使用PeerConnectionFactory 的构造方法创建工厂:

PeerConnectionFactory peerConnectionFactory = new PeerConnectionFactory();

有了peerConnectionFactory实例,就可以从用户设备获取视频和音频,最终将其渲染到屏幕上。

VideoCapturerAndroid & CameraEnumerationAndroid

VideoCapturerAndroid是VideoCapturer接口的实现,封装了一系列Camera API,为访问摄像头设备的流信息提供了方便。要创建VideoCapturerAndroid的实例,首先需要通过CameraEnumerationAndroid类获取摄像头设备基本信息,如数量、名称。如下:

// Returns the number of camera devices
CameraEnumerationAndroid.getDeviceCount();

// Returns the name of the camera with camera index. Returns null if the
// camera can not be used.
CameraEnumerationAndroid.getDeviceName(0);

// Returns the front face device name
CameraEnumerationAndroid.getNameOfFrontFacingDevice();
// Returns the back facing device name
CameraEnumerationAndroid.getNameOfBackFacingDevice();
// Creates a VideoCapturerAndroid instance for the device name
VideoCapturerAndroid.create(name);

有了包含摄像流信息的VideoCapturerAndroid实例,就可以创建从本地设备获取到的包含视频流信息的MediaStream,从而发送给另一端。但做这些之前,我们首先研究下如何将自己的视频显示到应用上面。

VideoSource & VideoTrack

从VideoCapturer实例中获取一些有用信息,或者要达到最终目标————为连接端获取合适的媒体流,或者仅仅是将它渲染给用户,我们需要了解VideoSource 和 VideoTrack类。

VideoSource允许方法开启、停止设备捕获视频。这在为了延长电池寿命而禁止视频捕获的情况下比较有用。

VideoTrack 是简单的添加VideoSource到MediaStream 对象的一个封装。

我们通过代码看看它们是如何一起工作的。capturer是VideoCapturer的实例,videoConstraints是MediaConstraints的实例。

// First we create a VideoSource
VideoSource videoSource = 
    peerConnectionFactory.createVideoSource(capturer, videoConstraints);

// Once we have that, we can create our VideoTrack
// Note that VIDEO_TRACK_ID can be any string that uniquely
// identifies that video track in your application
VideoTrack localVideoTrack = 
    peerConnectionFactory.createVideoTrack(VIDEO_TRACK_ID, videoSource);

AudioSource & AudioTrack

AudioSource和AudioTrack与VideoSource和VideoTrack相似,只是不需要AudioCapturer 来获取麦克风,audioConstraints是 MediaConstraints的一个实例。

// First we create an AudioSource
AudioSource audioSource =
    peerConnectionFactory.createAudioSource(audioConstraints);

// Once we have that, we can create our AudioTrack
// Note that AUDIO_TRACK_ID can be any string that uniquely
// identifies that audio track in your application
AudioTrack localAudioTrack =
    peerConnectionFactory.createAudioTrack(AUDIO_TRACK_ID, audioSource);

VideoRenderer

通过把VideoRenderer.Callbacks的实现作为参数传入VideoRenderer的构造方法,WebRTC允许实现自己的渲染。另外,它提供了一种非常好的默认方式VideoRendererGui。简而言之,VideoRendererGui是一个GLSurfaceView ,使用它可以绘制自己的视频流。我们通过代码看一下它是如何工作的,以及如何添加renderer 到 VideoTrack。

// To create our VideoRenderer, we can use the 
// included VideoRendererGui for simplicity
// First we need to set the GLSurfaceView that it should render to
GLSurfaceView videoView = (GLSurfaceView) findViewById(R.id.glview_call);

// Then we set that view, and pass a Runnable
// to run once the surface is ready
VideoRendererGui.setView(videoView, runnable);

// Now that VideoRendererGui is ready, we can get our VideoRenderer
VideoRenderer renderer = VideoRendererGui.createGui(x, y, width, height);

// And finally, with our VideoRenderer ready, we
// can add our renderer to the VideoTrack.
localVideoTrack.addRenderer(renderer);

也可以通过SurfaceViewRenderer创建VideoRenderer的实例并添加到VideoTrack。SurfaceViewRenderer是一个SurfaceView并实现了VideoRenderer.Callbacks接口。

SurfaceViewRenderer localRender = (SurfaceViewRenderer) findViewById(R.id.local_video_view);

VideoRenderer renderer = new VideoRenderer(localRender);

localVideoTrack.addRenderer(renderer);

MediaConstraints

MediaConstraints是MediaStream中音频和视频轨道的各种约束。对于大多数需要MediaConstraints的方法,一个简单的MediaConstraints实例就可以做到。

MediaConstraints audioConstraints = new MediaConstraints();

MediaStream

现在可以在本地看见自己了,接下来就要想办法让对方看见自己。这需要创建MediaStream,然后将其添加到PeerConnection 传送给对方。接下来我们就研究如何添加本地的VideoTrack 和AudioTrack来创建一个合适的MediaStream。

// We start out with an empty MediaStream object, 
// created with help from our PeerConnectionFactory
// Note that LOCAL_MEDIA_STREAM_ID can be any string
MediaStream mediaStream = peerConnectionFactory.createLocalMediaStream(LOCAL_MEDIA_STREAM_ID);

// Now we can add our tracks.
mediaStream.addTrack(localVideoTrack);
mediaStream.addTrack(localAudioTrack);

我们现在有了包含视频流和音频流的MediaStream实例,而且在屏幕上显示了我们的脸庞。现在就该把这些信息传送给对方了。

PeerConnection

现在我们有了自己的MediaStream,就可以开始连接远端了。这可以通过PeerConnection实现。创建PeerConnection很简单,只需要PeerConnectionFactory的协助即可。

PeerConnection peerConnection = peerConnectionFactory.createPeerConnection( iceServers, constraints,  observer);

参数的作用如下:

iceServers
    连接到外部设备或者网络时需要用到这个参数。在这里添加STUN 和 TURN 服务器就允许进行连接,即使在网络条件很差的条件下。

constraints
    MediaConstraints的一个实例,应该包含offerToRecieveAudio 和 offerToRecieveVideo

observer
     PeerConnection.Observer的一个实例。

PeerConnection 包含了addStream、addIceCandidate、createOffer、createAnswer、getLocalDescription、setRemoteDescription 和其他类似方法。我们快速浏览一下这几个重要的方法,看它们是如何工作的。
addStream
这个是用来将MediaStream 添加到PeerConnection中的,如同它的命名一样。如果你想要对方看到你的视频、听到你的声音,就需要用到这个方法。

addIceCandidate
一旦内部IceFramework发现有candidates允许其他方连接你时,就会创建IceCandidates 。当通过PeerConnectionObserver.onIceCandidate传递数据到对方时,需要通过任何一个你选择的信号通道获取到对方的IceCandidates。使用addIceCandidate 添加它们到PeerConnection,以便PeerConnection可以通过已有信息试图连接对方。

createOffer/createAnswer
这两个方法用于原始通话的建立。如你所知,在WebRTC中,已经有了caller和callee的概念,一个是呼叫,一个是应答。createOffer是caller使用的,它需要一个sdpObserver,它允许获取和传输会话描述协议Session Description Protocol (SDP)给对方,还需要一个MediaConstraint。一旦对方得到了这个请求,它将创建一个应答并将其传输给caller。SDP是用来给对方描述期望格式的数据(如video、formats、codecs、encryption、resolution、 size等)。一旦caller收到这个应答信息,双方就相互建立的通信需求达成了一致,如视频、音频、解码器等。

setLocalDescription/setRemoteDescription
这个是用来设置createOffer和createAnswer产生的SDP数据的,包含从远端获取到的数据。它允许内部PeerConnection 配置链接以便一旦开始传输音频和视频就可以开始真正工作。

PeerConnection.Observer

这个接口提供了一种监测PeerConnection事件的方法,例如收到MediaStream时,或者发现iceCandidates 时,或者需要重新建立通讯时。这个接口必须被实现,以便你可以有效处理收到的事件,例如当对方变为可见时,向他们发送信号iceCandidates。

调用顺序

发起呼叫

发起呼叫

接受呼叫

接受呼叫

关闭连接

关闭连接

Demo

AppRTCDemo

安卓WebRTC与SRS实战:从零搭建实时音视频推拉流系统 本文详细介绍了如何在安卓平台上集成WebRTC,并结合SRS流媒体服务器从零搭建一套低延迟的实时音视频推拉流系统。内容涵盖SRS服务器部署与WebRTC配置、安卓端WebRTC库的集成、音视频轨道的创建与捕获、以及与SRS信令交互实现推流和拉流的完整代码实战。文章还提供了关键的避坑指南和性能调优建议,帮助开发者快速构建适用于在线教育、直播连麦等高实时性场景的安卓应用。 阅读详情

相关推荐

一文学会WebRTC API:掌握实时通信利器

WebRTC(Web Real-Time Communication)是一项开放标准和技术集合,由 W3C 和 IETF 等组织共同推动和维护,旨在通过Web浏览器实现实时通信和媒体流传输。WebRTC于2011年6月1日开源并在Google、Mozilla、Opera支持下被纳入万维网联盟的W3C推荐标准,其提供了一组API和协议,使开发者能够在浏览器中构建实时音视频通信、数据传输和协作应用。目前WebRTC已得到包括主流的Web浏览器(如Chrome、Firefox、Safari)和移动设备平台的广泛的

bjxiaxueliang的CODING小栈 2715

WebRtc入门 - API说明

文章目录一、媒体设备1.1 摄像头异常说明实例1.2 共享屏幕异常说明实例1.3 查询媒体设备说明定义MediaDeviceInfo属性说明使用实例找出所有摄像头1.4 监听媒体设备变化使用方法更新所有摄像头1.5 从canvas获取媒体流二、媒体约束2.1 约束类型2.1.1 媒体流约束MediaStreamConstraints2.1.2 [媒体轨道约束MeidaTrackConstraints](https://developer.mozilla.org/en-US/docs/Web/API/Medi

成长之路 5633

WebRTC笔记之一:开篇

一.无插件的实时通讯 想像一下,如果你的手机、电视、电脑都可以通过一个平台进行通信,想像一下,你可以在Web应用中轻松地加入视频聊天和p2p数据分享,这就是WebRTC的愿景。 想试一试吗?WebRTC现在已经被集成到Chrome、Opera和Firefox,在apprtc.appspot.com有个简单的视频聊天应用可供测试。 1.在Chrome、Opera或F

草上爬的博客 4万+

WebRTC 教程一:WebRTC信令、架构和 API 入门

本文主要介绍了 WebRTC 是什么,其和 Websocket 的异同,WebRTC 信令,架构和 API 入门。

m0_60259116的博客 6758

学习Android音视频开发:探索WebRTC的新潮流

学习Android音视频开发和拥抱WebRTC的新潮流需要一定的时间和精力。通过深入了解音视频基础知识、学习Android的音视频API、理解WebRTC的工作原理,并编写示例代码,您可以逐步掌握这些技术,并在自己的应用中实现音视频通信功能。要学习Android音视频开发,您需要了解Android平台上的音视频框架和API。在开始学习Android音视频开发之前,了解一些基本的音视频概念和技术是很重要的。通过编写和运行这样的示例代码,您可以实际体验和理解Android音视频开发和WebRTC的工作原理。

syntax_bug719的博客 209

Overleaf+EndNote+BibTeX:手把手搞定Elsevier期刊投稿的参考文献格式(避坑指南)

本文详细介绍了如何利用Overleaf、EndNote和BibTeX三大工具无缝协作,解决Elsevier期刊投稿中的参考文献格式问题。从工具链配置、文献库导出、BibTeX文件优化到Overleaf集成与编译,提供全流程指南和常见问题解决方案,帮助学术新手高效完成Elsevier期刊投稿。

weixin_30616969的博客 509

【亲测免费】 Android WebRTC API 使用教程

Android WebRTC API 使用教程 项目介绍 Android WebRTC API 是一个开源项目,旨在为 Android 开发者提供一个简单易用的 WebRTC 接口。WebRTC(Web Real-Time Communication)是一个支持网页浏览器进行实时语音对话或视频对话的API。该项目通过封装 WebRTC 的核心功能,使得在 Android 平台上实现音视频通话变得更...

gitblog_00458的博客 790

湿敏电阻HR202的两种驱动方案实测:IO充放电法 vs. 交流方波ADC法,哪个更适合你?

本文深入评测湿敏电阻HR202的两种驱动方案:IO充放电法和交流方波ADC法。通过原理图分析、精度实测和资源占用对比,揭示交流方波ADC法在精度和稳定性上的优势,特别适合长期监测场景。同时提供IO充放电法在资源受限情况下的应用建议,帮助工程师根据项目需求做出最优选择。

weixin_30421809的博客 466

Android WebRTC API 项目常见问题解决方案

Android WebRTC API 项目常见问题解决方案 一、项目基础介绍 Android WebRTC API 是一个开源项目,它提供了一个用于简化 Android 设备上 WebRTC 信令的模块。WebRTC 是一个支持网页浏览器进行实时通信的 API,它允许在浏览器之间直接进行点对点通信,无需服务器中转。该项目使用 Java 作为主要的编程语言,并利用了 PubNub 作为信令传输工具,...

gitblog_01196的博客 909

手把手教你用VMware虚拟机搭建PCAN开发环境:从Ubuntu安装到CAN通讯实战

本文详细指导如何在VMware虚拟机中搭建PCAN开发环境,涵盖从Ubuntu系统安装、VMware精细配置、PCAN-USB设备直通,到Linux驱动编译、can-utils工具集使用及完整CAN通讯测试的全过程。通过实战步骤与故障排查技巧,帮助开发者快速构建稳定高效的CAN总线开发与测试沙盒,特别适合车载诊断与嵌入式通讯应用。

weixin_29216353的博客 223

PredFormer实战:用Transformer搞定交通流量预测(附TaxiBJ数据集代码)

本文详细介绍了如何利用PredFormer这一基于Transformer的先进模型进行交通流量预测,特别针对TaxiBJ数据集提供了完整的实战代码和优化策略。PredFormer通过门控Transformer块(GTB)的创新设计,在时空预测任务中展现出显著优势,相比传统方法将MSE降低33.1%,推理速度提升4.4倍。文章还涵盖了模型轻量化、部署优化等实用技巧,为智慧城市建设中的交通预测提供了高效解决方案。

weixin_29194817的博客 445

Android WebRTC实战:如何用Camera2 API实现高清视频录制与实时播放(附完整代码)

本文详细介绍了如何利用Android Camera2 API与WebRTC结合实现高清视频录制与实时播放。通过Camera2 API的手动控制三要素、帧级精确控制等高级特性,优化WebRTC视频流采集,提升视频质量与性能。文章包含完整代码示例,帮助开发者快速实现专业级视频采集方案。

weixin_29196891的博客 104

〖进阶篇1〗YAML参数解析:从nav2_params.yaml看机器人导航调优

本文深入解析了ROS2 Nav2导航系统中关键的nav2_params.yaml文件,提供了从定位、行为树、运动控制到环境感知等核心模块的参数调优实战指南。文章通过具体场景案例,如狭窄走廊、动态仓库和高精度对接,详细阐述了如何调整AMCL粒子数、控制器权重、代价地图膨胀半径等参数,以解决机器人导航中的犹豫、碰撞和精度问题,帮助开发者实现从“能用”到“好用”的进阶。

m9n0o的博客 417

WebRTC SDK API封装(3)-Android/iOS平台

前面两篇已经讲了如何手动编译并封装WebRTC Native C/C++ API的方法及思路,本篇继续对封装的API进行进一步使用,将此功能使用在移动端进行演示,这种使用方式,更适合于即时通讯类产品应用. 打入补丁文件 由于 创建工程目录 以下命令 gn gen --args 修改编译文件 这里主要修改主目录src/BUILD.gn文件,此文件为编译整个WebRTC系统的入口文件,类似于M...

bingdele的专栏 1884

Sqlserver2012评估期已过问题解决(启动数据库服务报错1705都是同样的问题,数据库过期未激活)

一、背景: 因为之前安装sqlserver2012忘记输入序列号,如今出现评估期已过的问题,前几天忙活半天,才解决,发现网 上叙述都非常凌乱,并且仅仅有大意,有的非常难操作。所以把我操作的过程和大家交流分享: 一定要有序列号的输入。不然会有很多其它的麻烦出现: 二、问题解决: 第一步:进入SQL2012配置工具中的安装中心。 第二步:再进入左側维护选项界面,然后选择选择版本号升级。 ...

堂前燕的博客 3266

uniapp [安卓苹果App端] - 详细实现下载文件保存到用户手机本地,指定文件存储位置路径及文件夹名称下载并保存,Uniapp app端将文件下载保存并储存到指定目录(手机系统存储空间权限检测)

uni-app,安卓Android,苹果ios,安卓app端,苹果App端,uniapp苹果安卓app,app端下载文件,移动端文件下载,并保存到手机本地存储空间,uniapp下载文件保存到手机本地,iOS下载文件怎么保存,系统读写存储空间权限,下载文件到本地详细流程及源代码,保存自定义目录,uniapp,实现下载文件并保存到本地,文件后缀,如何指定手机的存放目录路径url,点击下载文档到手机中并提示存储位置,如何在uniapp中实现文件下载功能,uniApp文件下载,怎么指定文件保存目录,下载报错,没反应

🏆 前端领域优质创作者 1万+

探索实时通信新境界:PubNub Android WebRTC Signaling API深度解析与推荐

探索实时通信新境界:PubNub Android WebRTC Signaling API深度解析与推荐 android-webrtc-apiPubnub Android WebRTC Signaling Library项目地址:https://gitcode.com/gh_mirrors/an/android-webrtc-api 项目简介 在当今这个高速发展的数字时代,实时音视频通讯已成为连...

gitblog_00031的博客 646

GibbsCAM软件二次开发:GibbsCAM软件API接口详解

API(Application Programming Interface,应用程序编程接口)是一种允许不同软件之间进行通信的接口。在GibbsCAM软件中,API提供了与外部程序交互的能力,使得开发者可以利用GibbsCAM的强大功能进行二次开发,定制化满足特定的制造需求。GibbsCAM的API主要基于.NET框架,使用C#或VB.NET等语言进行编程。在GibbsCAM软件中,通过API接口创建自定义几何形状是实现复杂零件设计和加工策略定制的关键步骤。

kkchenjj的博客 1496

Android WebRTC回声消除

WebRTC 的回声消除系统主要包含声学回声消除(AEC)模块、语音活动检测(VAD)模块、舒适噪声生成(CNG)模块等。WebRTC是一个由谷歌主导开发的开源项目,其目标是通过简单的API,实现实时通信(RTC)。WebRTC项目包含了多个处理音视频通讯问题的模块,其中就包括了一个性能优异的回声消除(AEC)模块。它旨在为开发者提供一个高效、可靠的解决方案,以消除通话中的回声干扰,提升用户体验。主要回声消除函数就是上面介绍的这几个,如果要放到Android上调,就要把这几个包成jni的形式。

zmlovelx(帅得不敢出门 程序员群31843264) 3028

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

android rtc框架,AndroidRTC

AndroidRTCAn example of native WebRTC on Android using PubNub's PnWebRTC API for signaling.Big News: PubNub Releases Android WebRTC Signaling API!This means that you can now create video chatting appl...

weixin_39789857的博客 642

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

Android WebRTC实战:从零构建高效实时通信应用

基于火山引擎豆包大模型,从零搭建一个实时语音通话应用。它不是简单的问答,而是需要你亲手打通 ASR(语音识别)→ LLM(大脑思考)→ TTS(语音合成)的完整 WebSocket 链路。对于想要掌握 AI 原生应用架构的同学来说,这是个绝佳的练手项目。架构理解:掌握实时语音应用的完整技术链路(ASR→LLM→TTS)技能提升:学会申请、配置与调用火山引擎AI服务定制能力:通过代码修改自定义角色性格与音色,实现“从使用到创造”从0到1构建生产级别应用,脱离Demo,点击打开。

2600_94959822的博客 1118

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

Android音频使用webrtc降噪处理、回声消除

WebRTC(Web Real-Time Communication)是一种支持实时音视频通信的开放性网络技术,它可以在Web浏览器中直接进行音视频通信,也可以被集成到移动应用中,包括Android应用。下面将介绍WebRTC技术的简介和特点,以及WebRTC在Android应用中的应用场景和优势。WebRTC技术的简介和特点WebRTC是一种基于Web的实时通信技术,由Google、Mozilla和Opera等公司联合推动,已经成为了Web应用中实现实时音视频通信的主要标准。

虎哥LoveDroid 9132

Android调用uc播放器,在UC android浏览器中使用摄像头设备(WebRTC API)

我们正在开发Web应用程序,它应该使用摄像头设备(WebRTC标准)来读取QR码,并且我们是UC Android浏览器中的严重问题。 这里是我们的应用程序的例子https://www.publicstaticvoidmain.cz/qr/在UC android浏览器中使用摄像头设备(WebRTC API)它适用于大多数常见浏览器,但我们在UC Android Browser(迷你版)支持下苦苦挣扎...

weixin_31032795的博客 1650

webrtc-android播放声音

找了好久,没找到API,真想吐槽文档匮乏&demo代码混乱。。。 /** * Enables/disables playout of received audio streams. Enabled by default. * * Note that even if playout is enabled, streams will only be played out ...

yeshen.org 2406

ScreenStream:安卓设备屏幕共享的革命性解决方案

ScreenStream是一款功能强大的Android应用程序,它允许用户轻松地将设备屏幕和音频内容实时分享到任何支持浏览器的设备上。无论是远程教学、技术支持还是团队协作,这款应用都能提供便捷高效的屏幕共享体验。 ## 核心特性与技术优势 ScreenStream基于Android MediaProjection API构建,支持Android 6.0及以上版本。应用提供三种不同的流媒体模式,

gitblog_00861的博客 759

webrtc native 声音控制

再次吐槽文档匮乏。 有个方法可以控制 public void onAddStream(MediaStream stream) { ... stream.audioTracks.get(0).setVolume(mVolume); } 参考资料: https://chromium.googlesource.com/external/webrtc/+/lkgr/sdk/android/api/...

yeshen.org 1992
上一篇: Android插件化开发技术
下一篇: Android仿小米商城底部导航栏(基于BottomNavigationBar)
Rain松
博客等级 码龄15年 361粉丝 111原创
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值