视频特效制作:如何给视频添加边框、水印、动画以及3D效果

ffmpeg生成裸眼3D、伪3D视频 2D视频转伪3D视频,可用平行眼直接观看 阅读详情

本文内容来自raywenderlich的这篇文章的翻译:AVFoundation Tutorial: Adding Overlays and Animations to Videos

这是我当年做视频大量参考的文章。写得非常好,建议看完我的这篇去看原文。

第一节:给视频添加边框

今天第一节先讲解如何为一个视频添加边框和动画,首先说明的是,这种边框和动画并不能直接修改视频的某一帧给他增加边框或者产生动画效果,这种动画更像是给视频的上面加一个calayer,然后控制这个layer产生动画效果。因为具体到某一帧的这种操作不是iphone应该做的他也做不到。

我们先来看一张图,了解一下给video增加动画的原理。

12.png

动画层的原理

你可以看到videoLayer这个东西,其实这个layer就是负责显示我们的视频,和他同级的是一个叫animationLayer的东西,我们能够掌控并且玩出花样的其实是这个叫animationLayer的东西,因为这个animationLayer可以由我们自己创建。

这里看一个图

VideoEditing.jpg

动画层的原理

这是原文中添加边框的效果。大家可以思考下原理是什么?

其实很简单,和我们videoLayer同级别的layer叫animationLayer(就是上图的background),他们共同有个父类叫做parentLayer,那么增加边框无非是把animationLayer这个layer找个边框的图片,然后把他放到videoLayer的下面,然后把videoLayer(crop也就是裁剪)的尺寸控制到刚好能显示animationLayer的四边,这样,不就成了带边框的效果么。

我找了一张带边框的图片。

54.jpg

带边框的图片

我们这时候创建一个CALayer,然后呢把这个layer的内容设置为图片内容。内容如下。

1
2
3
4
CALayer *backgroundLayer = [CALayer layer];
[backgroundLayer setContents:(id)[borderImage CGImage]];
backgroundLayer.frame = CGRectMake(0, 0, size.width, size.height);
[backgroundLayer setMasksToBounds:YES];

我们创建好了背景layer,那么需要创建videoLayer了,这时候设置calayer的frame需要注意,这时候你为了让videoLayer能够显示background layer的四边,所以需要这么设置。

1
2
3
  CALayer *videoLayer = [CALayer layer];
videoLayer.frame = CGRectMake(_widthBar.value, _widthBar.value,
                             size.width-(_widthBar.value*2), size.height-(_widthBar.value*2));

_widthBar.value就是我们边框的宽度,所以这句话的意思就是设置videoLayer的frame使其能够正确显示background layer的四边。

这时候,我们设置好了背景layer和videolayer那么怎么让系统知道,从而在编辑video的时候用到这些设置呢。需要使用这个方法。

1
2
3
4
  [parentLayer addSublayer:backgroundLayer];
    [parentLayer addSublayer:videoLayer];
   composition.animationTool = [AVVideoCompositionCoreAnimationTool
                            videoCompositionCoreAnimationToolWithPostProcessingAsVideoLayer:videoLayer inLayer:parentLayer];

这里的composition就是AVMutableVideoComposition,如果不知道是什么东西,看上一篇blog。 这里主要是告诉系统我们的layer层是parentLayer,在parentLayer里负责video显示的使我们的videoLayer。

其实你看到这里可以打开demo,找到这个类,然后修改一下parentLayer添加backgroundLayer和videoLayer的顺序,看看是什么情况。或者自己找几张图片,创建几个layer,把calayer的内容设置为图片,然后加到parentLayer里,看看有什么变化,总之需要自己多尝试。

65.png

这种是怎么做的呢?

这种又是怎么做的呢?自己思考下。

第二节,如何给视频添加水印

其实看完第一部分,添加水印的步骤已经呼之欲出,无非就是把我们自己建的水印放在一个layer上,然后把这个layer添加到videolayer的上面不就行了么。代码如下,注意注释内容。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// 1 - 这个layer就是用来显示水印的。
CATextLayer *subtitle1Text = [[CATextLayer alloc] init];
[subtitle1Text setFont:@ "Helvetica-Bold" ];
[subtitle1Text setFontSize:36];
[subtitle1Text setFrame:CGRectMake(0, 0, size.width, 100)];
[subtitle1Text setString:_subTitle1.text];
[subtitle1Text setAlignmentMode:kCAAlignmentCenter];
[subtitle1Text setForegroundColor:[[UIColor whiteColor] CGColor]];
// 2 - The usual overlay
CALayer *overlayLayer = [CALayer layer];
[overlayLayer addSublayer:subtitle1Text];
overlayLayer.frame = CGRectMake(0, 0, size.width, size.height);
[overlayLayer setMasksToBounds:YES];
CALayer *parentLayer = [CALayer layer];
CALayer *videoLayer = [CALayer layer];
parentLayer.frame = CGRectMake(0, 0, size.width, size.height);
videoLayer.frame = CGRectMake(0, 0, size.width, size.height);
// 这里看出区别了吧,我们把overlayLayer放在了videolayer的上面,所以水印总是显示在视频之上的。
[parentLayer addSublayer:videoLayer];
[parentLayer addSublayer:overlayLayer];
composition.animationTool = [AVVideoCompositionCoreAnimationTool
                              videoCompositionCoreAnimationToolWithPostProcessingAsVideoLayer:videoLayer inLayer:parentLayer];

SubtitleImage.png

水印内容

第三节:如何给视频添加动画

原理不想赘述,一切花样都在我们自己创建的layer上,因为我们用的是layer,所以自然可以使用基于CoreAnimation的动画来使我们的layer动起来。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
// 1
UIImage *animationImage = [UIImage imageNamed:@ "star.png" ];;
CALayer *overlayLayer1 = [CALayer layer];
[overlayLayer1 setContents:(id)[animationImage CGImage]];
overlayLayer1.frame = CGRectMake(size.width/2-64, size.height/2 + 200, 128, 128);
[overlayLayer1 setMasksToBounds:YES];
CALayer *overlayLayer2 = [CALayer layer];
[overlayLayer2 setContents:(id)[animationImage CGImage]];
overlayLayer2.frame = CGRectMake(size.width/2-64, size.height/2 - 200, 128, 128);
[overlayLayer2 setMasksToBounds:YES];
// 2 - Rotate
if  (_animationSelectSegment.selectedSegmentIndex == 0) {
CABasicAnimation *animation =
[CABasicAnimation animationWithKeyPath:@ "transform.rotation" ];
animation.duration=2.0;
animation.repeatCount=5;
animation.autoreverses=YES;
// rotate from 0 to 360
animation.fromValue=[NSNumber numberWithFloat:0.0];
animation.toValue=[NSNumber numberWithFloat:(2.0 * M_PI)];
animation.beginTime = AVCoreAnimationBeginTimeAtZero;
[overlayLayer1 addAnimation:animation forKey:@ "rotation" ];
animation = [CABasicAnimation animationWithKeyPath:@ "transform.rotation" ];
animation.duration=2.0;
animation.repeatCount=5;
animation.autoreverses=YES;
// rotate from 0 to 360
animation.fromValue=[NSNumber numberWithFloat:0.0];
animation.toValue=[NSNumber numberWithFloat:(2.0 * M_PI)];
animation.beginTime = AVCoreAnimationBeginTimeAtZero;
[overlayLayer2 addAnimation:animation forKey:@ "rotation" ];
// 3 - Fade
}  else  if (_animationSelectSegment.selectedSegmentIndex == 1) {
CABasicAnimation *animation
=[CABasicAnimation animationWithKeyPath:@ "opacity" ];
animation.duration=3.0;
animation.repeatCount=5;
animation.autoreverses=YES;
// animate from fully visible to invisible
animation.fromValue=[NSNumber numberWithFloat:1.0];
animation.toValue=[NSNumber numberWithFloat:0.0];
animation.beginTime = AVCoreAnimationBeginTimeAtZero;
[overlayLayer1 addAnimation:animation forKey:@ "animateOpacity" ];
animation=[CABasicAnimation animationWithKeyPath:@ "opacity" ];
animation.duration=3.0;
animation.repeatCount=5;
animation.autoreverses=YES;
// animate from invisible to fully visible
animation.fromValue=[NSNumber numberWithFloat:1.0];
animation.toValue=[NSNumber numberWithFloat:0.0];
animation.beginTime = AVCoreAnimationBeginTimeAtZero;
[overlayLayer2 addAnimation:animation forKey:@ "animateOpacity" ];
   // 4 - Twinkle
}  else  if (_animationSelectSegment.selectedSegmentIndex == 2) {
CABasicAnimation *animation =
[CABasicAnimation animationWithKeyPath:@ "transform.scale" ];
animation.duration=0.5;
animation.repeatCount=10;
animation.autoreverses=YES;
// animate from half size to full size
animation.fromValue=[NSNumber numberWithFloat:0.5];
animation.toValue=[NSNumber numberWithFloat:1.0];
animation.beginTime = AVCoreAnimationBeginTimeAtZero;
[overlayLayer1 addAnimation:animation forKey:@ "scale" ];
animation = [CABasicAnimation animationWithKeyPath:@ "transform.scale" ];
animation.duration=1.0;
animation.repeatCount=5;
animation.autoreverses=YES;
// animate from half size to full size
animation.fromValue=[NSNumber numberWithFloat:0.5];
animation.toValue=[NSNumber numberWithFloat:1.0];
animation.beginTime = AVCoreAnimationBeginTimeAtZero;
[overlayLayer2 addAnimation:animation forKey:@ "scale" ];
}
// 5
CALayer *parentLayer = [CALayer layer];
CALayer *videoLayer = [CALayer layer];
parentLayer.frame = CGRectMake(0, 0, size.width, size.height);
videoLayer.frame = CGRectMake(0, 0, size.width, size.height);
[parentLayer addSublayer:videoLayer];
[parentLayer addSublayer:overlayLayer1];
[parentLayer addSublayer:overlayLayer2];
composition.animationTool = [AVVideoCompositionCoreAnimationTool
                            videoCompositionCoreAnimationToolWithPostProcessingAsVideoLayer:videoLayer inLayer:parentLayer];
}

Animation.png

动画效果

第四节:如何给我们的视频layer做出3D效果

TiltImage.jpg

3D效果

上面的所有效果都是在我们的animatinLayer上做文章的,要知道videoLayer他本质上也是个CALayer,那么其实普通layer能做的事他也一样能做。代码如下。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// 1 - Layer setup
CALayer *parentLayer = [CALayer layer];
CALayer *videoLayer = [CALayer layer];
parentLayer.frame = CGRectMake(0, 0, size.width, size.height);
videoLayer.frame = CGRectMake(0, 0, size.width, size.height);
[parentLayer addSublayer:videoLayer];
// 2 - Set up the transform
CATransform3D identityTransform = CATransform3DIdentity;
// 3 - 具体设置可以看demo
if  (_tiltSegment.selectedSegmentIndex == 0) {
     identityTransform.m34 = 1.0 / 1000;  // greater the denominator lesser will be the transformation
}  else  if  (_tiltSegment.selectedSegmentIndex == 1) {
     identityTransform.m34 = 1.0 / -1000;  // lesser the denominator lesser will be the transformation
}
// 4 - 给我们的video层做rotation
videoLayer.transform = CATransform3DRotate(identityTransform, M_PI/6.0, 1.0f, 0.0f, 0.0f);
// 5 - Composition
composition.animationTool = [AVVideoCompositionCoreAnimationTool
                              videoCompositionCoreAnimationToolWithPostProcessingAsVideoLayer:videoLayer inLayer:parentLayer];

上面的代码很容易懂,就是给我们的video层做rotation,其实你可以改改demo里的数据,试试makescale,maketranslate之类的transform。

第五节:如何做出视频推进效果

具体内容看我的DEMO。

前4节DEMO地址:http://cdn2.raywenderlich.com/wp-content/uploads/2013/05/VideoEditing-Final2.zip

视频推进DEMO 地址:https://github.com/pingguo-zangqilong/VideoPushDemo

视频推进demo使用的时候直接点合成,不用选择视频。

转:http://www.cocoachina.com/ios/20141208/10542.html
FFmpeg字幕进阶:5分钟搞定ASS动态特效字幕(含代码示例) 本文详细介绍了如何使用FFmpeg和ASS格式创建动态特效字幕,包括基础参数设置、时间轴动画和高级视觉特效。通过代码示例,快速掌握文字渐隐、运动轨迹、3D旋转等专业技巧,提升视频制作质量。适合视频制作者、内容创作者和独立制片人使用。 阅读详情

相关推荐

剪映专业版教程:制作水晶立方体动画效果

本教程详解剪映专业版制作水晶立方体动画效果。核心操作:将5张9:16古风美女图裁剪为1:1比例,设背景填充-模糊;每张图设“立方体”组合动画时长2秒,复制替换片段完成图2至图5;添加“动感荧光”特效分别作用于单张图片(边框荧光流动)和轨道2全局(屏幕四周荧光流动);在每两张图交界处添加“花瓣环绕”特效时长1秒增强转场仪式感;叠加文字排版贴纸和水印文本;最后添加高清增强滤镜。该方法通过立方体动画与荧光特效配合实现水晶质感展示效果。

深耕计算机专业知识与技术。 500

Canvas使用

Canvas使用 canvas是一个可以使用脚本(通常为JavaScript)来绘制图形的 HTML 元素.例如,它可以用于绘制图表、制作图片构图或者制作简单的(以及不那么简单的)。像echarts、antv就是使用canvas来绘制图表的 标签 首先要有一个canvas标签存在于html中 <canvas id="charts" width="150" height="150">&l...

qq_42036203的博客 2872

从原理到代码:一文搞懂LFM信号脉冲压缩在Matlab中的实现

本文深入解析了LFM信号脉冲压缩的核心原理与Matlab实现方法。从线性调频信号的数学表达、时频特性入手,详细讲解了如何构建多目标回波仿真环境,并重点阐述了匹配滤波器的频域实现算法。文章提供了完整的、可运行的Matlab代码,涵盖信号生成、噪声添加、脉冲压缩及性能评估等关键步骤,并探讨了加窗处理、参数选择等工程实践中的考量,为雷达信号处理的学习与实践提供了清晰指南。

weixin_29063035的博客 414

如何给视频加边框

提取YUV数据ffmpeg -i input.mp4 -s 256x256 -pix_fmt yuv420p output_420.yuv 将亮度分量Y设置成255 int simplest_yuv420_border(char *url, int w, int h,int border,int num){ FILE *fp=fopen(ur...

weixin_34212189的博客 1066

机械臂开发必备:KDL库正逆解与动力学实战指南

在机器人算法领域,运动学与动力学计算是机械臂控制、仿真与轨迹规划的核心基础。正运动学描述关节空间到笛卡尔空间的映射,逆运动学则需要求解复杂的非线性方程,工程实现时常面临数值稳定性与调试效率的挑战。KDL(Kinematics and Dynamics Library)作为ROS生态中广泛使用的开源库,提供了统一的模型描述与高效求解器,将正逆解、雅可比矩阵及动力学参数计算封装为简洁接口,大幅降低开发门槛。无论是机械臂的笛卡尔空间轨迹跟踪,还是基于动力学模型的前馈控制,KDL都展现出强大的工程价值。本文从运动学

weixin_33860528的博客 2504

利用eds editor生成CANOPEN 设备eds文件

通过以上步骤,您可以根据实际设备的功能特性,自动生成一份符合CANopen协议标准的电子数据表(EDS文件),该文件可以被上位机软件或其他CANopen主站设备用于识别、配置和控制您的CANopen从站设备。使用CANopen EDS Editor生成CANOPEN设备的EDS文件是一个系统化的过程,它涉及将设备的具体技术参数和功能映射到CANopen规范定义的对象字典中。

weixin_38604759的博客 6458

ffmpeg给视频画边框

1、新建一个txt文件,并复制如下代码进入,然后保存。 @echo off & title cd /d %~dp0 for %%a in (*.mp4) do ( ffmpeg -i "%%~sa" -y -q:v 1 -vf drawbox=x=0:y=0:w=iw:h=ih:c=yellow:t=10 "out\%%~na.mp4" ) pause 2、把文件后缀修改为bat 。 3、把后缀为bat的文件放到要批量处理的视频文件夹里面。 4、在确保安装了ffmpe

mj412828668的博客 3903

YOLOv8_obb训练流程-原理解析[旋转目标检测理论篇]

本文主要介绍了YOLOv8旋转目标检测的流程,介绍了标签的解码、预测结果的解码,以及如何理解旋转角度等内容,还介绍旋转目标检测框的正样本选取及Loss计算。

ice 4731

叶孤城大神之--视频特效制作:如何给视频添加边框、水印、动画以及3D效果

原文地址http://www.cocoachina.com/ios/20141208/10542.html

zhonggaorong的专栏 1137

英伟达 Jetson AGX Thor 官方入门教程(二)CUDA、Docker、JetPack 设置

本文详细介绍了NVIDIA Jetson AGX Thor开发套件的安装与配置流程。主要内容包括:1) BSP安装的三种方法(Jetson ISO、SDK Manager和Linux刷写脚本)及其适用场景;2) Docker环境的完整配置步骤及测试方法;3) CUDA工具包的两种安装方式(容器化和原生安装)及其性能对比;4) JetPack SDK的安装选项。文章提供了详细的命令行操作指南和故障排除建议,帮助开发者快速搭建AI开发环境,充分发挥Jetson平台的硬件性能优势。

机器人控制与仿真应用 1731

leetcode134 加油站

题目如下 在一条环路上有 N 个加油站,其中第 i 个加油站有汽油 gas[i] 升。 你有一辆油箱容量无限的的汽车,从第 i 个加油站开往第 i+1 个加油站需要消耗汽油 cost[i] 升。你从其中的一个加油站出发,开始时油箱为空。 如果你可以绕环路行驶一周,则返回出发时加油站的编号,否则返回 -1。 说明: 如果题目有解,该答案即为唯一答案。 输入数组均为非空数组,且长度相同。 输...

ayang818 's blog 233

3d效果图制作傻瓜软件_3d短视频制作软件下载-3d短视频下载 v3.4 安卓版

3D短视频是一款专业制作视频的app,app里面有很多制作视频的模板,可以随意调节视频中物体的位置和属性,全新的VR视角让你的视频有一种不同的新颖感,分享到你的社交圈绝对引来一阵追捧。应用介绍3D视频制作是一款专业制作视频类的软件,主要特色是有大量炫酷的3D模板使得制作VR视角的视频变得简单而有个性。当然也支持图片模板制作视频,包含了大量的边框以及许多过渡动画使您任意搭配!更有功能强大的视频剪辑功...

weixin_39638105的博客 1251

[Dify 实战] 如何在内网环境部署 Dify 应用:彻底离线的企业级方案解析

企业内网环境如何离线部署Dify?本文提供详细教程:Dify作为开源AI平台,支持完全离线部署,无需外网访问。文中介绍两种部署方式:推荐使用Docker一键部署,也可选择源码安装定制化方案。重点讲解内网模型配置(支持Ollama/GPT-OSS等)、知识库存储(MinIO/PostgreSQL)及内网代理设置,并给出常见问题排查方法。该方案适用于金融、政府等对数据安全要求高的场景,确保敏感数据不泄露,实现完全本地化的AI应用闭环。

技术小甜甜:传播可落地技术,帮助个人和企业降低解决真实场景问题的成本 452

前端里的button怎么去除点击自带边框_这款系统自带的视频剪辑软件,了解一下...

接触该软件之前听说过有一款Movie Maker剪辑软件就是系统自带的,不过微软已经停止更新该软件了。在新的Windows系统中(Win10)出现了新的视频剪辑软件Video Maker(视频编辑器),应该是Movie Maker的升级版,接下来咱就把软件拉出来遛遛看看是骡子是马。软件在哪里?如果你是Win7系统,你可以试着在【开始菜单】中搜索“Movie Maker”,如果搜索不到结果,那么很遗...

weixin_39954487的博客 154

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

图片去字工具_【短视频】制作剪辑必备的24款工具

本文为你介绍:短视频制作工具、短视频剪辑工具、短视频制图工具等内容。短视频制作工具昨天朋友圈看到朋友发了这样一段话:俗话说,工欲善其事,必先利其器。01视频制作、剪辑APP1.剪映APP“剪映-轻而易剪”是由深圳市脸萌科技有限公司开发的,号称“抖音官方剪辑神器”;短视频制作剪辑剪映的底部基础功能和快影类似,都是剪辑、音频、贴纸、滤镜、特效、比例等,剪映导出的视频没有水印,但分享的路径非常...

weixin_39794347的博客 822

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

3种超火电影级PPT开场,跟着学,5分钟搞定高级感!

别再费劲琢磨PPT开场了!收下这3份“保姆级”配方,你只需要复制步骤,就能做出让同事眼前一亮的高级感开场。

2401_83179994的博客 1885

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

开发轻量级本地软件实现证件照尺寸调整/AI换底色/GIF生成/水印边框/套lut滤镜

PhotoMasterPro是一款桌面端轻量化影像处理工具,集成了证件照生成、色彩管理、GIF转换、水印添加等核心功能。软件采用模块化解耦架构,实现UI与引擎分离,支持多线程任务处理。关键技术包括"零拷贝"高性能渲染方案、异步防抖优化和50层撤销栈内存管理。其智能证件照模块支持多规格适配和AI智能换底,3DLUT滤镜引擎实现专业级色彩映射。软件提供两种分发方案:PyInstaller目录对齐打包法和Nuitka C++编译法,确保跨平台兼容性。

Chansrgj的博客 852

FFmpeg命令行滤镜使用

对视频的滤镜处理还是很有吸引力的,因为可以做出各种比较炫酷的视频效果。这篇学习使用FFmpeg命令行来简单的操作制作视频的滤镜效果。 Filter Filter的参数排列格式为: [输入流或标记名]滤镜参数[临时标记];[输入流或标记名]滤镜参数[临时标记名] 看一个命令行示例: ffmpeg -i input.mp4 -i logo.png -filter_complex "[...

LymanYe的博客 6252

ProCCD:复古CCD相机应用,重现经典胶片感

U300:清冷的蓝绿色调赋予照片文艺的日系电影氛围感,适合风景拍摄。- IXUS95:有着暖黄色调和独特颗粒质感,复古胶片感十足,是街拍首选。- Z30:色彩浓郁,能忠实呈现色调和细节,适用各种拍照场景。- M532:褪色和低饱和度赋予照片怀旧感;肤色表现佳,适合人物写真。

2501_90259289的博客 1680
上一篇: UICollectionView基本使用详解(OC)
下一篇: UITableViewCell 不同复用方式
直隶码农
博客等级 码龄19年 95粉丝 103原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值