Thursday, January 13, 2022

SegmentFault 最新的文章

SegmentFault 最新的文章


新一代的编译工具 SWC

Posted: 13 Jan 2022 03:02 AM PST

最近前端圈掀起了一阵 rust 风,凡是能用 rust 重写的前端工具就用 rust 重写,今天介绍的工具就是通过 rust 实现的 bable:swc,一个将 ES6 转化为 ES5 的工具。

而且在 swc 的官网,很直白说自己和 babel 对标,swcbabel 命令可以相互替换,并且大部分的 babel 插件也已经实现。

使用 rust 的一个优势就是快,比如我们之前的一个项目,将 babel 替换成 swc 后,编译速度从原来的 7 秒提升到了 1 秒,效率直接爆炸。

上手

swc 与 babel 一样,将命令行工具、编译核心模块分化为两个包。

  • @swc/cli 类似于 @babel/cli;
  • @swc/core 类似于 @babel/core;
npm i -D @swc/cli @swc/core

通过如下命令,可以将一个 ES6 的 JS 文件转化为 ES5。

npx swc source.js -o dist.js

下面是 source.js 的代码:

const start = () => {   console.log('app started') }

代码中囊括了 ES6 的两个特性,const 声明箭头函数。经过 swc 转化后,这两个特性分别被转化成了 var 声明function 匿名函数

配置文件

swc 与 babel 一样,支持类似于 .babelrc 的配置文件:.swcrc,配置的格式为 JSON。

{   "jsc": { // 编译规则     "target": "es5", // 输出js的规范     "parser": {       // 除了 ecmascript,还支持 typescript       "syntax": "ecmascript",       // 是否解析jsx,对应插件 @babel/plugin-transform-react-jsx       "jsx": false,       // 是否支持装饰器,对应插件 @babel/plugin-syntax-decorators       "decorators": false,       // 是否支持动态导入,对应插件 @babel/plugin-syntax-dynamic-import       "dynamicImport": false,       // ……       // babel 的大部分插件都能在这里找到对应配置     },     "minify": {}, // 压缩相关配置,需要先开启压缩   },   "env": { // 编译结果相关配置     "targets": { // 编译结果需要适配的浏览器       "ie": "11" // 只兼容到 ie 11     },     "corejs": "3" // corejs 的版本   },   "minify": true // 是否开启压缩 }

babel 的插件系统被 swc 整合成了 jsc.parser 内的配置,基本上大部分插件都能照顾到。而且,swc 还继承了压缩的能力,通过 minify 属性开启,jsc.minify 用于配置压缩相关的规则,更详细的配置可查看文档

Node APIs

通过在 node.js 代码中,导入 @swc/core 模块,可以在 node.js 中调用 api 直接进行代码的编译,这对 CLI 工具的开发来说是常规操作。

// swc.mjs import { readFileSync } from 'fs' import { transform } from '@swc/core'  const run = async () => {   const code = readFileSync('./source.js', 'utf-8')     const result = await transform(code, {     filename: "source.js",   })   // 输出编译后代码   console.log(result.code) }  run()

打包代码

除了将代码转义,swc 还提供了一个简易的打包能力。我们新建一个 src 文件夹,在里面新建两个文件:index.jsutils.js

// src/index.js import { log } from './utils.js' const start = () => log('app started') start()
// src/utils.js export const log = function () {   console.log(...arguments) } export const errorLog = function () {   console.error(...arguments) }

可以看到 index.js 导入了 utils.js 中的一个方法,然后我们新建一个 spack.config.js 文件,该文件是 swc 打包的配置文件。

// spack.config.js module.exports = {   entry: {     // 打包的入口     web: __dirname + "/src/index.js",   },   output: {     // 打包后输出的文件夹     path: __dirname + "/dist",   }, };

然后在命令行运行:

$ npx spack

打包成功后,会在 dist 目录输出一个 web.js 文件。

可以看到,不仅将 index.jsutils.js 打包成了一个文件,还进行了 tree shaking,将 utils.js 中没有使用的 errorLog 方法删掉了。

能不能用?

babel 毕竟经过了这么多年的发展,不管是 bug 输了,还是社区活跃度都远远优于 swc。所以,如果是小产品试水还是可以试一下 swc 的,旧项目如果已经使用了 babel 还是不建议进行迁移。

在使用的过程,还是发现了一些小问题。比如,如果我使用了 async function,swc 会自动导入 regenerator-runtime 模块。

// 编译前,有个 async 方法 const start = async () => {   console.log('app started') }

调用 swc 编译后,代码如下:

这个结果看起来是没问题的,但是 swc 与 babel 类似,也有 helpers(@swc/helpers),同时提供了 externalHelpers 开关, 如果把 externalHelpers 设置为 true,swc 会将一些工具类,通过模块的形式导入。

// .swcrc {   "jsc": {     "externalHelpers": true   } }

externalHelpers 的默认值是 false,那这个时候,regenerator-runtime ,到底是通过模块的形式导入,还是把整个代码写入到文件?

swc 正好有个 [issue [https://github.com/swc-projec...]](https://github.com/swc-projec...) 在讨论这个问题。

除了上面说的这个问题,其实还有一点,就是作者觉得之前的架构有问题,正在加紧重写 2.0 版本,感觉可以期待一下,另外提一句,swc 的作者是一个 97 年的韩国小哥,目前大学都还没毕业,最后我也只能说一句:牛逼!

我们需要怎样的 Service

Posted: 09 Jan 2022 05:57 PM PST

14 世纪,英格兰的逻辑学家奥卡姆在他的《箴言书注》中说「不要浪费过多的东西,去做那些用较少的东西同样可以做好的事情」。后来这句话被简化为「奥卡姆剃刀原理」,即:如无必要,勿增实体。奥卡姆剃刀在各个领域都有他的运用,他不是一个公理,没有严谨的推导过程,但他却是一个在实践中被证明非常有效的解决问题的手段。

在编程世界里,有太多我们习以为常的东西,我相信存在即合理,同时我也相信存在都有前提,而前提会随着时间变化甚至消失。下面我想跟大家探讨下,我们前端项目中那些应该被剃刀剃掉的东西。

前端项目里的 service 层

在一个前端项目中,一般包含以下文件目录:

  • containers:页面
  • components:组件
  • utils:工具方法
  • routes:路由
  • services:数据服务
  • index.js 入口文件

我们的业务代码基本都在 containers components 里,utils 和 routes 也是必不可少的,但仔细思考我们就会发现,这里有个 services 文件夹,他被称为数据服务层,是我们跟后端打交道的。这一层真的需要吗?
我们来看看大家是怎么使用 service 的。

// services  文件夹下的 accoutService.js  import { post } from '@/utils/request';  // 获取账号列表 export const getAccountsList = params => post('/api/accounts.json', params); // 新增账号 export const insertAccount = params => post('/api/insertAccount.json', params); // 更新状态 export const updateAccount = params => post('/api/updateAccount.json', params); // 校验账号查询 export const checkAccount = params => post('/api/checkAccount.json', params);  -------- 使用 ---------  import { getAccountsList } from '@/services/accountService'  const App = () => {   const [name, setName] = useState('');     useEffect(() => {       getAccountsList().then((res) => {        setName(res.name);     });   }, [])   return <div>{name}</div>; }; 

从上面的代码我们可以看出,services 文件下基本是一些模板代码,偶尔有少见的一些数据转换。这些内容对于我们的业务代码来说,都是非业务相关的,写这些模板性的控制代码真的有必要吗?

service 里包含什么?

  • 数据转换逻辑 converHandler
  • 数据请求工具 request
  • 请求地址定义 url
  • 全局拦截器 interceptor
  • 附加功能 openApi

数据转换逻辑 converHandler:并不通用,有的一个请求在不同的页面需要走不同的转换逻辑,这些转换逻辑一般会写在调用位置的代码里,我也建议这么做,因为数据转换也是这块某个 container 的功能,而且为了方便测试,建议添加 handler.js 将转换逻辑抽离出来。

数据请求工具 request:主要是封装各种请求,这部分需要统一。非业务相关,可以提出来。

请求地址定义 url:这部分是强业务相关的,不应该放到 service 里,而是作为 service 的一个配置,由外部输入。

全局拦截器 interceptor:处理一些通用的业务状态码,比如编辑成功 10001,这部分也是强业务相关的,而且相对比较复杂,但是可以通过配置 schame 来描述,后面再讲。

附加功能 openAPI:如果你系统的接口想让别的系统复用,比如 MTEE 基础平台的接口需要复用给运营平台,那么前端需要提供领域物料,领域物料里会发请求,发请求要解决跨域、登陆、授权的问题,openAPI 应运而生。

综上可以看出,service 层只需要一些统一的逻辑处理和配置文件就能描述清楚,甚至我们可以把 Service 层简化为

$$service = request + config$$

我的 service 包

由此,我希望能设计这样一个 service 包,他需要包含下面的功能:

请求

支持常见的 get post jsonp 请求,以及对于这些请求的附加方法,比如 debounce、throttle、缓存、loading 等功能。也可以提供大家比较喜欢的 hooks API。

接口配置

一个接口包含域名 domain,地址路径 path,请求方法 method,参数 params,一些常见功能的开关,比如开启防抖 { debounce:true } 。参数的配置里,可以添加该参数的基本属性,比如是否必选 { require: true } ,这样包内可以对参数做必要的校验,这样可以保证非法数据传入后台。

环境切换

环境切换是一个非业务相关的功能,他不应该硬编码到代码里,带到线上。他应该只是一个配置,尽量与代码脱离,因此是用浏览器插件来切换,就是一个很好的方法。可以设计 service 包接收一个 domainMap,这个 domainMap 来自 window.GlobalConfig 下的某个变量,浏览器插件可以动态改变这个变量,就可以做到环境的切换了。
image.png

网关转发

我们写代码追求复用,从代码块的复用到组件复用,再到业务能力的复用,而业务能力复用的一个载体就是领域物料。一个领域物料里很有多个接口请求,如果我们把原来在业务代码里的组件拆出来作为领域物料的话,就不得不把项目里的 service 层也要打包进去,这样才能发送请求和处理一些统一的异常。上面的我提到的把是service 层做成一个包,别人在使用的时候,只需要传配置进来,也是出于领域物料这个场景。
这之后,我们还要解决一个问题:领域物料在不同站点使用带来的接口跨域问题。我们现在的解决办法是,前端搭建一套基于 node 的网关,用于做接口转发和鉴权。service 包里会集成这个过程,外部使用者只需要配置开不开启网关就可以了。他完全不需要知道网关是如何转发的,就像在自己的站点下写组件一样。

接口文档

我们在接手别的项目的时候,总是不容易找到他的接口文档,因为文档和代码是割裂的,文档的维护也有滞后性,甚至慢慢文档的链接也找不到了。因此,代码和文档应该在一起,最好是代码即文档。大家可能觉得用注释就可以了,但程序员总是要求别人写注释,但自己却不爱写。写注释如果可以像写代码一样,或许能规范这部分的行为。例如:

{     name: '获取账号',     domain: DOMAIN.TAOBAO,     url: '/api/getAccount.json',     method: METHOD.GET,     params: {       userId: {         name: '策略包id',         type: PARAM_TYPE.STRING,         required: true,       },     },     response: {         name: '账户名字'     },   },

这里用配置文件的方式规范了文档的形式,还可以与浏览器插件相结合,通过插件来查看当前用的接口文档。

异常拦截

异常分为服务器异常和业务异常,服务器异常一般是用 http 状态码,400、500等;业务异常则需要是用 body 里的 code 来表示。在真实的业务实践中,我们发现对于服务器异常我们是很容易写出通用的拦截器做一些处理的,但是对于业务异常,就相对比较复杂了,这里面存在几个问题:

  • 很多后端不习惯使用 code 返回相应的业务编码来表示不同的状态。
  • 前端直接使用后端返回的 message 展示给用户,这里有两个问题,① 后端的需要引入第三方库对 message 做国际化 ② 后端定义的 message 不是用户语言,用户一般是看不懂的。因此这里就需要一个第三方系统的参与,他提供业务 code 和前端动作的映射关系表,比如:后端返回 code:10000,前端应该弹窗并展示 message,定义的 json 如下:
{   code: 10000,   message: '编辑失败',   debug: '后端数据库读写异常,堆栈信息:',   showType: 'openDialog' }

这里的 message 是可以根据不同语言环境返回不同语言文字的,showType 表示了前端的动作类型,这个是可枚举的,其中肯定有一种动作是,不做动作,直接透传。这个第三方系统,就可以配置不同编码的动作,有利于精细化的管理异常,给用户更好的体验。

落地

实践是检验真理的唯一标准,基于上面的理想,我的 service 包也已经成型,使用他非常简单。只需要两步:
① 配置文件
② 引入包
③ 业务代码里调用

配置

// 配置文件 account.js  import { METHOD, PARAM_TYPE } from '@ali/hulu-service';  export const DOMAIN = {    TAOBAO: '//taobao.com',    ALIPAY: '//alipay.com', };  export default {   getAccount: {     name: '获取账号',     domain: DOMAIN.TAOBAO,     url: '/api/getAccount.json',     method: METHOD.GET,     params: {       userId: {         name: '策略包id',         type: PARAM_TYPE.STRING,         required: true,       },     },     response: {         name: '账户名字'     },   }, };

引入包

import HService from '@ali/hulu-service'; import account from './account';  // 初始化service const service = HService.init({   urls: [       account,   ] });  export default service;

调用 API

import Service from './service';  const App = () => {   const [name, setName] = useState('');     useEffect(() => {       Service.getAccount().then((res) => {        setName(res.name);     });   }, []);   return <div>{name}</div>; };  export default App;

同时基于浏览器插件,可以快速的切换环境,查看接口文档等。

想想边界

开头,我们说到奥卡姆剃刀,如无必要,勿增实体,这个的前提是,有清晰独立的实体,如果我们的实体之间相互勾连耦合,那又如何剃掉不必要的实体呢。
其实,无论做任何软件构架,都要分清楚边界,也就是一个模块他的定位是什么,哪些功能是他该做的,哪些不是。这里面一个非常重要的依据就是是否易于变更。哪些是业务的、常变化的,哪些是非业务的、一般不变的。我们的代码常常,坏就坏在边界不清晰,或者是边界原则没有一以贯之。工程代码里耦合了业务,业务代码里掺杂着工程(比如环境判断)。代码的坏味道是一点一点积累而成的,而这个坏的开始,就是初始的架构设计边界不清晰,没有用代码定义规范。
抵抗代码的腐败,这是一个漫漫长路,没有银弹,但确实可以精进一个人的系统思维。

作者:ES2049 / 黑石
文章可随意转载,但请保留此原文链接。
非常欢迎有激情的你加入 ES2049 Studio,简历请发送至 caijun.hcj@alibaba-inc.com

权威发布丨2021 中国技术品牌影响力企业

Posted: 12 Jan 2022 04:35 PM PST

前言

2021 年 3 月,《中华人民共和国国民经济和社会发展第十四个五年规划和 2035 年远景目标纲要》正式发布。"开源" 被首次写入国家 "五年规划",云计算、大数据、智能制造等关键词被多次提及。

"十四五" 是我国开启全面建设社会主义现代化国家新征程的第一个五年,全球新一轮科技革命和产业变革深入发展,软件和信息技术服务业迎来新的发展机遇。 

回首这一年,我们看到了数字经济的蓬勃发展,而这背后离不开无数开发者和科技企业夜以继日的付出。他们面对不断变化的外部环境,扎根行业,他们信奉技术力量,敢于技术创新,践行技术信仰,他们是技术先锋,探索改变世界的方向。

SegmentFault 思否作为中国领先的新一代开发者社区,依托数百万开发者用户数据分析,及各科技企业和个人在国内技术领域的行为、影响力指标,推出了第三届"中国技术先锋"年度评选。

本次评选共设SegmentFault 思否年度 TopWriter、SegmentFault 思否年度技术团队、中国开源先锋 33 人、中国新锐技术先锋企业榜、中国技术品牌影响力企业榜、最受开发者欢迎的技术活动榜等。其中TopWriter年度技术团队开源先锋 33 人已在本周发布,明天我们还将继续发布最受开发者欢迎的技术活动榜单。

无论是积极输出优质 UGC 内容的技术作者,还是高质量技术活动的主办方、在开发者生态上积极投入的科技企业,都是推动社会创新的 "先锋力量",我们推荐大家在 2022 年关注他们的发展和动态。

中国技术品牌影响力企业评选标准

  • 榜单必须以公司为主体申报参选,可推荐或自荐;
  • 参选公司必须为科技型企业,拥有成熟的产品服务、顶级技术人才储备和不断创新的技术能力;
  • 参评公司必须持续关注开发者生态,有各种形式的技术内容输出,如:积极参与或举办技术活动、有持续更新的技术博客、有成熟开源项目/积极参与开源等;
  • 参评公司技术品牌美誉度较高,在开发者人群中具备较高知名度及影响力。

2021 中国技术品牌影响力企业

上榜企业他们在社区被开发者点赞
Arm中国极术社区
DClouduni-app 研发团队
GoogleGoogle Cloud、谷歌开发者
IntelOpenVINO™
KyligenceKyligence
OceanBaseOceanBase
ONESONES
OPPOOPPO 数智技术
PingCAPPingCAP
UCloudUCloud
vivovivo互联网技术
阿里巴巴阿里云开发者社区、阿里云天池、阿里巴巴开源办公室、阿里巴巴淘系技术、阿里巴巴移动技术、友盟+
百度百度飞桨
地平线地平线开发者社区
华为HMS Core、华为云开发者社区、华为开源
浪潮浪潮云海 OS
蚂蚁集团蚂蚁体验科技、SOFAStack 团队
每日互动个推
葡萄城葡萄城开发控件
麒麟软件优麒麟
七牛云七牛云、Go+
青云QingCloudKubeSphere
声网Agora声网Agora
腾讯腾讯云 CODING、腾源会、腾讯优图实验室、腾讯云开发、腾讯游戏学堂、腾讯云 TVP
网易网易云信、网易易盾、网易有道技术团队、网易云音乐前端技术团队
微软微软中国、Microsoft Azure、Microsoft Reactor
微众银行微众开源
亚马逊云科技亚马逊云开发者
云智慧云智慧
字节跳动穿山甲、飞书开放平台、火山引擎

当开发者生态和技术品牌受到越来越多企业的重视,我们希望让开发者看到那些真正坚持长期价值,积极输出优质技术内容、坚持产品创新、为开发者创造价值和便利的企业或团队,帮助他们获得更多关注,也推动更多企业加大在开发者生态的投入,帮助开发者成长和成功。

关于 SegmentFault 思否

SegmentFault 思否作为中国领先的新一代开发者社区和专业技术媒体,是国内 DGC (Developer Generated Content) 内容最丰富、技术问答板块最活跃的开发者社区。

目前已经覆盖和服务了超过 1000 万开发者和上千家科技企业,帮助开发者解决了超过数百万个技术问题,用户原创产生的优质技术文章已累积超过 50 万篇,上千家科技企业技术团队入驻。

权威发布丨2021 中国新锐技术先锋企业

Posted: 12 Jan 2022 04:36 PM PST

前言

2021 年 3 月,《中华人民共和国国民经济和社会发展第十四个五年规划和 2035 年远景目标纲要》正式发布。"开源" 被首次写入国家 "五年规划",云计算、大数据、智能制造等关键词被多次提及。

"十四五" 是我国开启全面建设社会主义现代化国家新征程的第一个五年,全球新一轮科技革命和产业变革深入发展,软件和信息技术服务业迎来新的发展机遇。 

回首这一年,我们看到了数字经济的蓬勃发展,而这背后离不开无数开发者和科技企业夜以继日的付出。他们面对不断变化的外部环境,扎根行业,他们信奉技术力量,敢于技术创新,践行技术信仰,他们是技术先锋,探索改变世界的方向。

SegmentFault 思否作为中国领先的新一代开发者社区,依托数百万开发者用户数据分析,及各科技企业和个人在国内技术领域的行为、影响力指标,推出了第三届"中国技术先锋"年度评选。

本次评选共设SegmentFault 思否年度 TopWriter、SegmentFault 思否年度技术团队、中国开源先锋 33 人、中国新锐技术先锋企业榜、中国技术品牌影响力企业榜、最受开发者欢迎的技术活动榜等。其中 TopWriter年度技术团队开源先锋 33 人已在本周发布,明天我们还将继续发布最受开发者欢迎的技术活动榜单。

中国新锐技术先锋企业榜主要面向成立时间较短、融资轮次在 B 轮及 B 轮前的技术型初创公司,要求公司研发团队人数占比不低于 60% ,关注开发者生态、积极在社区贡献,在开发者群体中具备一定关注度及良好口碑,拥有较高成长性。

2021 中国新锐技术企业

名称
api7 支流科技
EMQ
Jina AI
Juicedata
KodeRover
OneFlow 一流科技
PerfMa
ShowMebug
SphereEx
StarRocks 鼎石科技
StreamNative
Vika 维格表
Zilliz
格物钛
火线安全
极狐 GitLab
摩尔线程
欧若数网
偶数科技
涛思数据

中国新锐技术先锋企业是推动社会创新的 "新锐力量",富有朝气和活力,我们推荐大家在 2022 年关注他们的发展和动态。

关于 SegmentFault 思否

SegmentFault 思否作为中国领先的新一代开发者社区和专业技术媒体,是国内 DGC (Developer Generated Content) 内容最丰富、技术问答板块最活跃的开发者社区。

目前已经覆盖和服务了超过 1000 万开发者和上千家科技企业,帮助开发者解决了超过数百万个技术问题,用户原创产生的优质技术文章已累积超过 50 万篇,上千家科技企业技术团队入驻。

一键AI着色,黑白老照片画面瞬间鲜活

Posted: 11 Jan 2022 07:20 PM PST

很多老照片或者电影受时代技术所限制,只能以黑白形式保存;经过编辑后的黑白视频和图片早已丢失彩色原图,这对于保存者来说都十分遗憾。如何能将单一乏味、陈旧斑驳的黑白照片变成鲜活亮丽的彩色照片,从照片中重新获取更多的特征细节,让观看者产生更强的代入感和情感共鸣呢?

华为视频编辑服务(Video Editor Kit)全新上线的"AI着色"能力,为开发者提供了黑白一键着色的解决方案。应用在集成视频编辑服务"AI着色"能力后,用户只需要上传一张黑白照片或者一段黑白视频,即可获得鲜活多彩的彩色照片或视频。

操作简单,效果也很不错!

快来看下集成步骤吧!

集成代码

1 开发准备

详细准备步骤可参考华为开发者联盟官网:
https://developer.huawei.com/...

2 编辑工程集成

2.1 设置应用的鉴权信息

可以通过api_key或者Access Token来设置应用鉴权信息。

  • 通过setAccessToken方法设置Access Token,在应用启动时初始化设置一次即可,无需多次设置。

    MediaApplication.getInstance().setAccessToken("your access token");
  • 通过setApiKey方法设置api_key,在应用启动时初始化设置一次即可,无需多次设置。

    MediaApplication.getInstance().setApiKey("your ApiKey");

    2.2设置唯一标识ID,即License ID。

License ID是进行管控的有效凭证,您要保证设置License ID的唯一性。

MediaApplication.getInstance().setLicenseId("License ID");

2.2.1初始化Editor运行环境

创建编辑工程,需要首先创建Editor对象并初始化其运行环境。当离开编辑工程时,应释放Editor实例。

(1) 创建Editor对象

HuaweiVideoEditor editor = HuaweiVideoEditor.create(getApplicationContext());

(2) 指定预览窗口的布局位置

预览窗口负责视频图像画面的渲染,由视频编辑原子能力SDK内部创建SurfaceView来实现。在创建窗口之前,需要在您的App中指定预览窗口的布局位置。

<LinearLayout         android:id="@+id/video_content_layout"         android:layout_width="0dp"         android:layout_height="0dp"         android:background="@color/video_edit_main_bg_color"         android:gravity="center"         android:orientation="vertical" /> // 指定预览窗口  LinearLayout mSdkPreviewContainer = view.findViewById(R.id.video_content_layout);  // 设置预览窗口承载的布局  editor.setDisplay(mSdkPreviewContainer);

(3) 初始化运行环境,如果License鉴权失败,会抛出LicenseException。

当Editor对象创建之后,此时还没有占用实际的系统资源,需要手动选择其环境初始化的时机,此时视频编辑原子能力SDK内部会创建必须的线程和定时器等。

try {         editor.initEnvironment();    } catch (LicenseException error) {          SmartLog.e(TAG, "initEnvironment failed: " + error.getErrorMsg());             finish();         return;    }

2.2.2添加视频、图片

创建一条视频泳道,然后往泳道上添加图片或者视频素材。图片和视频素材需要通过文件路径添加到泳道上。

// 获取时间线对象  HVETimeLine timeline = editor.getTimeLine();  // 创建视频泳道  HVEVideoLane videoLane = timeline.appendVideoLane();  // 在视频泳道的末尾,添加视频资源  HVEVideoAsset videoAsset = vidoeLane.appendVideoAsset("test.mp4");  // 在视频泳道的末尾,添加图片资源  HVEImageAsset imageAsset = vidoeLane.appendImageAsset("test.jpg");

3 AI着色集成

AI着色支持图片和视频资源,视频大小限制为100M。

// 添加AI着色特效 videoAsset.addColorAIEffect(new HVEAIProcessCallback() {         @Override         public void onProgress(int progress) {         // AI着色处理进度         }          @Override         public void onSuccess() {         // AI着色处理成功         }          @Override         public void onError(int errorCode, String errorMessage) {         // AI着色处理失败         }     });  // 移除AI着色特效 videoAsset.removeAIColorEffect();

Demo演示

集成开发过程中,您有任何问题都可以在线提单,将有专人为您解答。

了解更多详情>>

访问华为开发者联盟官网
获取开发指导文档
华为移动服务开源仓库地址:GitHubGitee

关注我们,第一时间了解 HMS Core 最新技术资讯~

No comments:

Post a Comment