2024 抖音欢笑中国年(三):编辑器技巧与实践

前言

本次春节活动中,我们大部分场景使用内部的 SAR Creator互动方案来实现。

SAR Creator 是一款基于 TypeScript 的高性能、轻量化的互动解决方案,目前支持了Web和字节内部跨端框架平台,服务于字节内部的各种互动业务,包括但不限于抖音春节、抖音直播礼物、抖音UG活动等。

c77ecd1f40b0c06260f89cf4784504e4.png

SAR Creator 编辑器支持了图形化界面,提供了各类完善的系统(光照、动画、脚本等)供用户快速便捷的搭建一个高质量的互动场景,集成了场景搭建、资源配置、预览调试等功能,并提供了打包构建等工程化插件,可配合业务定制高效2D、3D内容生产工作流。

本文将就本次春节活动中编辑器的工作流程、开发常用功能、以及配套的工程配置方案等进行介绍。

工作流程

目前编辑器的工作流程能极大的提升开发效率,在于研发和设计能够极好的解耦工作。对于设计同学来说,不仅能在研发同学在线编辑器上协作,也能独立制作通过Asset Package包进行资产的交付;而对于开发来说,编辑器能够可视化的进行大部分场景搭建以及资产配置,能直观的检查资产信息。

906f200aa59bd0fea91368bc9377b237.png

资产制作

由于设计同学本地没有开发环境,为了方便设计同学脱离研发单独使用SAR Creator制作美术资产,我们提供了SAR Creator Launcher工具供美术使用,使用 Sar Creator Launcher 可以管理 Sar Creator 编辑器的多个版本安装创建新项目快速启动项目查看编辑器版本的更新信息等功能。

5bdcf9795be11c1e902ef83dca3350c4.png

设计同学使用Launcher搭建一个项目之后,可以将他从PS、Blender、Spine制作的资源导入到SAR Creator当中进行组合到场景当中,并导出成预制体资源,例如春节活动以下场景就是由设计同学制作然后交付给研发使用。

42c8bedec92635dee467484046d9d986.png

动效预览

设计同学产出的资源可以直接导入到SAR Creator中进行播放预览以及调整,美术可以确保最终交付给研发的动画资源是符合预期的。

beb956a77fcc67b760305144d5b31a23.png

目前支持的动画有 lottie、spine、帧动画、模型动画、组合动画以及帧差动画。

资产导出

设计同学最终的导出产物一般为prefabs资源,因为设计和研发的项目不互通,需要一种更快捷的方式同步资源,设计同学可以在创建的预制体右键导出资源包,此功能会将预制体依赖的所有资源导出为一个asset压缩包,设计同学可以直接将此压缩包发送给研发同学导入

16caf2707223d84e81e608d2ff08b768.png

d146610c67261366b5d1083f75eaf9a8.png

研发同学直接在game目录上右键选择导入资源包,即可选择设计同学交付的文件将资源导入

810e15a6cbcd6cb3f83205499629451f.png

68ed939d7073af76af9e84fba21c0ea5.png

功能介绍

画布适配

画布适配是指调整互动区域的视觉输出以适应不同的屏幕尺寸和分辨率,这样可以确保互动区域在不同分辨率的设备上看起来运行都正常。

57a549f6b30d397d6513061effb77ecc.png

SAR Creator 提供了简单的解决方案,首先需要指定设计的宽度和高度,它们定义了游戏将以何种分辨率进行开发,通过设定这些值可以确保互动区域在所在目标设备上正确缩放并保持一致的视觉呈现。

除此之外除了为了进一步增强画布的适配功能,我们提供了根据特定需求的各种适配策略。这些策略包括:

  • FixedWidth(固定宽度):在此策略中,互动区域保持其设计宽度,高度根据纵横比自动调整。这确保互动区域始终占据屏幕的整个宽度,没有重要信息被裁剪掉。

  • FixedHeight(固定高度):与固定宽度策略类似,互动区域保持其设计高度,而宽度则根据纵横比调整。这可以确保互动区域始终垂直填充屏幕,并在各种设备上提供一致的体验。

  • Auto(自动适应):此策略将互动区域按比例缩放以适应可用屏幕空间的宽度和高度。取决于设备的纵横比,两侧或上下可能会出现一些空白区域,但整个互动区域内容都是可见的且无失真。

2D&3D混合开发

互动场景的编辑中,经常需要2D和3D元素相互结合才能创造出更好的交互体验,3D模型的移动经常能带来更逼真的效果,2D元素经常应用于背景图或者UI元素。

a1f0813a0a41728626e639d7cedc62e7.png

通过使用SAR Creator编辑器,可以很轻松的在同一场景中同时添加2D和3D对象。而且SAR Creator编辑器还允许自由调整这些对象之间的层级关系、渲染顺序以及视觉表现。此外,还可以为场景设置多种灯光和相机效果,进一步丰富场景表现力。

使用2D用来编辑器场景UI,对比使用前端技术编写UI界面逻辑,可视化拖拽编辑能大大提升开发速度,拿之前的一个项目举例:

  • 左下界面UI是使用前端技术方案代码编写界面,耗时3天。

  • 右下UI是使用SAR Creator 2D场景制作,耗时0.5天。

33d910c66f505a8e98a9dba26a4bd1d1.png

302a32eb4a2790c0432b075de532089a.png

Bundle分包

在项目开发过程中,资源管理和加载优化是至关重要的。随着互动内容变得越来越丰富,会出现资源体积庞大、加载速度缓慢等问题。为了解决这些问题,SAR Creator编辑器提供了Bundle分包能力,帮助开发者轻松地对游戏资源进行分组、管理和优化。

1692c2955f530f2565c1d5a24064b968.png

a0a90849f89e1c2da3a37bdf393fba84.png

21e1b28e24e87e265afe96ea0ec6ec41.png

Bundle分包使用起来非常简便,只需要选中文件夹,然后如左上图所示,勾选上配置为Bundle,就可以在构建的时候将这个文件夹内的资源拆分为独立的Bundle包,分组选项中有三种资源合并类型,功能介绍如下

  • 无:不做任何优化;

  • 合并依赖:将Bundle中相互依赖的资源二进制文件合并在一起,从而减少运行时加载请求次数;

  • 全部合并:将Bundle中所有资源二进制文件合并为一个,最大化减少请求数量,但可能会增加单个资源加载时间。

用户可以根据自己bundle包的资源情况合理选择分组方式。使用Bundle分包可以让开发者按需加载分包资源,无需项目初始化时就加载所有资源,这样不仅能减少项目首包的大小,还能提升游戏的启动速度和运行效率。

图片分级

图片资源的大小不仅影响着项目最终的包体大小,分辨率大的图片同样会占用设备更多的内存以及性能,而不同的设备的性能是不一样的,为了达到最好的显示效果又要满足用户设备的性能要求,SAR Creator编辑器对图片提供了分级功能,可以使不同性能的设备加载不同分辨率级别的图片,这在春节活动中得到了广泛使用。

0a7fccb3b4bba98a024d55e0f976b925.png

当勾选去掉禁用分级后,构建的时候会生成normal、medium、low三个级别的文件资源,其中medium、low的图片分辨率会低于原始图片,会根据用户手机的性能评分下发不同等级的图片资源,而无需研发同学关心下发的内容。

f3be30d8d1b6b1c0092012e2b9b08805.png

e3c8be38cd10a08b463efe68bc2ca33e.png

需要注意的是,在使用图片分级时,实际上是会修改图片的分辨率大小,而当我们使用spine或者序列帧这类动画文件时,图片资源为图集,如果降低了图片的分辨率,它们就无法在图集上获取正确的像素数据,导致动画播放异常,因此针对图集文件或者动画文件的图片资源,我们需要禁用分级。

压缩纹理

压缩纹理,是一种 GPU 能直接读取并显示的格式,使得图像无需在 CPU 侧解压成 bitmap 即可直接传入 GPU 进行渲染,节约大量的显存开销,而在移动端即内存开销。

在图片的检查器中,勾选上使用压缩纹理即可开启使用,压缩纹理在运行时会根据运行环境自动判断是否使用压缩纹理,使用时用户无需关注。

f8e8832c32ef505b8eeff49261484f60.png

4c69f4ee3e6b4fc1a9808b0910fa4ff3.png

启动图片上的压缩纹理配置后,可以配置选择etc、astc类型的压缩纹理,并通过排序决定运行时加载的优先级。同时可以配置压缩纹理的压缩质量、是否翻转等属性。

另外需要注意的是

  • 压缩纹理不能翻转纹理,即 flipY 表现始终为 false

  • 压缩纹理不能生成 mipmap,即 generateMipmaps 始终为 false

  • 为了适配不兼容压缩纹理的机型,图片资源仍然会被打进包体当中,所以包体会存在图片和图片的压缩纹理资源,包体体积会变得更大

透明像素扩边

在Canvas中绘制图片纹理时,图片边缘的像素会比较难处理,当我们选择边缘像素插值方式为linear时,虽然边缘会更光滑,但是由于插值方式的原因,图片的像素边缘会有一圈黑边,如下左图所示:

b4605170bc145ebfd8817242ad3a9706.jpeg

7865be46c5ae46a3d3aaedd97218aa2c.jpeg

因此,为了解决这个问题,SAR Creator编辑器提供了透明像素扩边的能力,我们可以通过图片配置勾选上透明像素扩边,将图片的边缘增加一圈纯白像素,使插值的像素可以不为黑色,如果扩边单个像素为白色不明显时,我们也可以选择扩全部像素,将透明像素图片的所有透明像素点填充为通过插值计算的带有颜色透明度的像素点,避免边缘渲染时产生黑边。

b87b8c2c6ebc881fee0937e0ac273048.png

841eeff679e2ede36f59935e836ef493.png

不过透明像素扩边同样存在着一些问题,经过扩边操作的图片因为会修改原先的图片文件,所以会导致图片体积增大,具体的增大情况要看最终的图片产物。

工程配置

配置文件

SAR Creator的配置文件主要分为两块:

  • SAR Creator项目的配置文件,其指定了项目的路径、入口文件等基础信息以及SAR Creator中预览的一些基础配置,方便运行项目的时候找到项目的位置。

  • SAR Creator项目构建插件的配置,因为SAR Creator可以适配各种平台,因此SAR Creator的构建流程通过插件的形式嵌入到不同平台的构建流程当中,并可以在插件中深度集成平台的相关能力。

SAR Creator项目配置文件通常叫做sar.config.js,这边以春节的摇签项目配置举例,项目的配置文件如下所示:

const path = require('path');
module.exports = {
  // 指定入口文件目录
  projectRoot: path.resolve(__dirname, 'game'),
  previewConfig: {
    previewDevtool: true,
    resolve: {
      alias: {
        // 别名,脚本中使用@lottery代替绝对路径,用来避免sar creator报错
        '@lottery': path.resolve(__dirname, './')
      }
    }
  }
};

插件通常在平台的配置文件中引入,因此插件的配置通常也在平台的配置文件中,此次春节活动是基于字节内的跨端框架平台开发,所以接下来会结合跨端框架平台做插件配置的功能介绍。

分包配置

跨端框架平台的项目会主动下发资源到用户手机,但是为了提高资源包下发的成功率,单包的限制通常在5M,因为如果我们的项目资源大于5M时,就需要进行拆包,在上面我们已经介绍过了Bundle分包,其能很好的将互动资源进行拆分并动态加载,但是一个Bundle包不一定有5M,因此为了让资源包收益最大化,一个资源包可以由几个Bundle包组成,这个拆分手动的话会很麻烦,因此我们通过工程配置在,构建完成后进行分包,配置信息如下:

const lotterySarConfig = {
  // ......
  /** 分包策略,构建才会生效 **/
  subPackages: {
    // 可以过滤掉一些包,比如测试包需要被剔除
    excludeBundles: ['test'],
    // 组合bundle包为gecko包的规则
    combineBundleRules: [
      {
        // 拆分到的gecko包名
        channelName: 'pitaya-lottery-game-2',
        // bundle包匹配符合条件的正则规则
        test: [/mascot/]
      },
      {
        channelName: 'pitaya-lottery-game',
        test: [/main-scene/, /resources/],
        preload: true,
        preloadPriority: 96
      }
    ]
  }
};

内联配置

在Bundle包中,会存在各种config或者json配置文件,文件数量较多时,每次访问都需要请求一个链接地址,为了减少请求次数,我们可以通过配置插件构建,将每个Bundle包中的json文件合并成一个二进制文件,减少请求的次数和资源的大小,并且为了防止单个二进制文件太大,我们仍可以限制合并的二进制的文件大小,以确保不影响请求资源下载的速度,配置如下:

const lotterySarConfig = {
  // ....
  ejectOptions: {
    // bundle的config文件不生成
    disableGenConfigWhenInline: true,
    // group分组配置信息
    groupConfig: {
      // 针对 bundle 下 group 的体积限制,优先级更高
      groupPackingSizeLimitBundleConfig: {
        // 名为mascot的 bundle 下单个group限制400k大小 
        mascot: 400,
        // 同上
        resources: 400
      }
    },
    // 内置bundle文件的config配置到entry.ts里
    inlineConfig: {
      'main-scene': true,
      resources: true,
      mascot: true
    }
  },
}

预加载配置

跨端框架平台支持资源的预加载,为了配合平台特性,我们还可以在构建生成游戏的时候就配置Bundle里的资源支持预加载,然后在构建完成后就可以生成预加载的配置文件,可以使用户在打开容器时就可以让容器提前加载好配置文件里的资源,使项目内加载到资源的时候,能更快的加载资源,其配置如下:

const lotterySarPreloadUrlList = [];
const lotterySarConfig = {
  // ......
  // 
  preload: {
    // 预加载资源前缀
    publicPath: `https://${CDN_DOMAIN}${GECKO_PREFIX}/pitaya-lottery-main/`,
    // 限制预加载资源个数
    limit: 300,
    // 限制预加载文件总体积, 默认就是3M
    sizeLimit: 3 * 1024, 
    // 配置文件输出目录
    outputDir: 'merge-js/lottery',
    // 过滤资源的规则
    asset: {
      rules: [
        {
          // 匹配规则
          test: /.*/,
          // 可以匹配重写该资源是否加入 preload.json,返回 { enableMemory, url, priority } 或 null
          rewrite: (item) => {
            if (
              item.url.endsWith('.png') ||
              item.url.endsWith('.jpg') ||
              item.url.endsWith('.jpeg') ||
              // 已经加入的不再次加入preload
              lotterySarPreloadUrlList.includes(item.url)
            ) {
              // 不写入预加载配置
              return;
            }
            lotterySarPreloadUrlList.push(item.url);
            item.enableMemory = true;
            // 写入预加载配置
            return item;
          }
        }
      ]
    }
  }
}

最后预加载的配置文件如下所示:

{
    // 跨端框架页面路径
    "***/index/template.js": {
        "image": [
            {
                // 是否开启内存缓存
                "enableMemory": true,
                // 资源加载路径
                "url": "***/resource/image/back.bcd0a82e.png",
                // 资源大小
                "size": 280
            },
            // ....
        ],
        "other": [
            {
                "enableMemory": true,
                "url": "***/main-scene/g_0.cc991.group",
                "priority": 96,
                "size": 143296,
                "assetBundleType": "group"
            },
            // ......
        ]
    }
}

依据跨端框架的页面路径,来预加载配置的URL链接以及优先级,能够在页面打开前就提前加载好资源内容。

开发实践

脚本编写

在资产平台右键我们可以创建默认脚本,脚本格式如下所示

a39feb4cb45bf606b323286cd4b93f21.png
// newscript.ts 脚本文件

import { Script, ScriptUtil } from '@sar-creator/toolkit/engine/core';

@ScriptUtil.Register('NewScript')
export default class NewScript extends Script {
  onStart() {
    const scene = this.world.getEntitiesByName('Scene')[0];
    if (scene) {
      // TODO:
    }
  }
}

SAR Creator 脚本的生命周期分为以下几个阶段:

  • onAwake:节点挂载时执行一次

  • onDestroy:节点销毁时执行

  • onPause:暂停时执行

  • onResume:恢复时执行

  • onStart:第一次帧动画开始前执行一次

  • onUpdate:每帧开始时执行

  • onLateUpdate:每帧结束时执行

我们常用的生命周期有onStartonUpdateonResume这个三个生命周期。

onStart是在节点首帧时激活一次,表明游戏已经可以开始运行,我们一般在此阶段动态加载资源,将获取到的资源添加到场景中,或者获取场景的某些节点实例。因为我们的项目是SAR Creator + 跨端框架组合,所以在跨端框架阶段初始化引擎的时候,我们会同步去获取服务端数据,当满足onStart触发以及数据获取成功两个条件时,我们一般会在脚本内依据数据初始化场景内容。

onUpdate会在节点的每帧渲染前触发一次,由requestAnimationFrame驱动,当我们需要变换场景中的元素的时候,就可以依靠每帧触发修改微小的变量,达到最终看起来连贯变换的样子,例如在摇签玩法中我们会依据陀螺仪的数据来确定签筒的状态,因此我们在此阶段每帧获取陀螺仪的数据,然后对其操作同步转换签筒的状态,让签筒有一种跟手的感觉。

onResume会在游戏暂停后重启时触发,一般来说当我们有些定时操作会在暂停阶段销毁,在恢复阶段触发,除此之外,当节点隐藏恢复时也会触发此阶段,当一个节点启动时播放动画,播放完成后隐藏,当恢复时需要重置动画状态并播放就可以在这个阶段进行。

预制体制作

当我们将层级面板中的节点拖拽到资产面板中就会自动生成预制体资产,预制体资产储存了这个节点的所有的数据以及依赖的资源信息。

aa49991b785f383f18cb353c4079af64.png

双击预制体资源,我们仍可以对预制体进行二次编辑等操作。

b1062bd3002fc95f22ce7c86b71cdfca.png

使用预制体资源可以帮我们可视化的预设大量的节点数据,我们可以通过直接加载制作的预制体,节省大量的实体修改参数配置等操作,从而提高我们的开发速度。

另外将场景中的非必要资源拆成预制体加载,可以有效提升主场景的加载速度,并渐进式加载其他装饰节点预制体到场景当中,并且可以依据用户手机性能,选择性加载不同复杂程度的预制体到场景当中。

例如在摇签玩法中,我们预设了不同的背景烟花以及签筒的预制体,使用时我们依据时机判断加载不同的烟花到场景当中,以及依据用户的手机性能,选择性加载要求更高性能的签筒还是性能要求更低的签筒。

c8683dfd43742295aef5fc4f47e83295.png

动态加载

在项目搭建中我们已经介绍了Bundle的配置方式,用户可以将文件夹配置成动态资源包,那么加载动态资源包我们提供了资源管理器assetManager挂载在world上,例如加载一个预制体资源如下所示:

const { 
  bundle, 
  error: bundleError
} = await this.world.assetManager.loadBundle('resources');

if(!bundle || errror) throw bundleError

const {
  asset,
  error: prefabError
} = await bundle.load<Entity>(`prefabs/fireworks/${prefabName}.prefab`);

 if (!asset?.get?.() || prefabError) throw prefabError;
 
 const entity = asset.get() as Entity

我们需要先使用loadBundle获取到这个Bundle包的实例,loadBundle支持传入Bundle的名称或者链接,拿到Bundle实例后,我们按照资源在bundle包中的路径加载,就可以获得到一个asset资产对象,asset调用get方法可以获取当前加载资产的实例,例如加载预制体获取到Entity实例。

另外当我们加载图片资源时,我们从资产面板可以看到图片的texture虚拟资产Texture对象,如果我们想要直接加载图片的Texture对象时,就可以在加载图片的路径中拼接上index.texture,例如下所示:

bf02cc73a1a56cebb3522554db65a6b8.png

const { 
  bundle, 
  error: bundleError
} = await this.world.assetManager.loadBundle('resources');

if(!bundle || errror) throw bundleError

const {
  asset,
  error: textureError
} = await bundle.load<Texture>(`texture/lamp/rect.png/index.texture`);

 if (!asset?.get?.() || textureError) throw textureError;
 
 const texture = asset.get() as Texture


fda486398ea9723832b83f1a2de896ea.png
const { 
  bundle, 
  error: bundleError
} = await this.world.assetManager.loadBundle('resources');

if(!bundle || errror) throw bundleError

const {
  asset,
  error: textureError
} = await bundle.load<Texture>(`texture/lamp/rect.png/index.texture`);

 if (!asset?.get?.() || textureError) throw textureError;
 
 const texture = asset.get() as Texture

未来展望

在过去的一年中,我们的SAR Creator产品经历了三个重要的大版本更新,分别是1.0、1.1、以及1.2,三个版本的迭代都是我们基于用户需求并不断优化用户体验推出来的阶段性版本。

在三个版本的迭代中,我们满足了研发同学的一些重要需求,例如脚本配置、bundle分包、性能优化等;增添了一些新功能,例如动画编辑器、VFX Particle、SAR Creator Launcher等;优化了SAR Creator的使用体验,例如多语言版本、材质属性分组、资产预览面板等。

基于过去一年的迭代,SAR Creator为春节的活动的开发带来了稳定的功能支持,在2024年中,SAR Creator将会持续优化引擎性能以及编辑器的易用性。

除此之外动画将是编辑器能力的核心,在2024年中我们将会不断扩展动画编辑器的能力,使用SAR Creator能够实现更加丰富的动画编辑功能,简单的动画元素将直接可以使用编辑器完成开发和预览。

团队介绍

我们是抖音前端架构-互动体验技术团队,主要为字节跳动业务提供互动技术解决方案。技术产品包含面向互动 / 小游戏研发场景的 SAR Creator、高性能动效渲染引擎 Simple Engine、互动场景端能力套件 AnnieX 互动容器

在这些技术建设与业务落地上,和抖音前端-互动创作团队跨端框架团队、开放平台小游戏团队、用户增长-激励前端团队一同推进,不断探索字节跳动应用生态下的创新业务形态。

下期预告

下期主题为渲染技术与实践,为了满足视觉和性能的两个要求,我们在渲染能力上提供了多种方法在适合的场景使用,最终达到了极为优秀的效果,敬请期待。

往期回顾

2024 抖音欢笑中国年(一):招财神龙互动技术揭秘

2024 抖音欢笑中国年(二):AnnieX互动容器创新玩法解析

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/530162.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

C++string类的实现

string类 string不属于STL,早于STL出现 看文档 C非官网(建议用这个) C官网 文章目录 string类一.为什么学习string类&#xff1f;1.C语言中的字符串2. 两个面试题(暂不做讲解) 二.标准库中的string类1. string类(了解)2. string类的常用接口说明&#xff08;注意下面我只讲解…

echarts 如何设置(dataZoom)多个图形的数据区域一起联动缩放响应

数据区域联动缩放需要用到 dataZoom 的专属事件 dispatchAction 实现多个数据区域联动缩放功能 <div style"width:100%;height:320px;" id"test01"></div> <div style"width:100%;height:320px;" id"test02"></…

JavaScript教程:从基础到发展历程及语法规则的全面介绍

文章目录 一、JavaScript简介二、JavaScript发展历程三、JavaScript基础语法3.1、变量概念3.2、变量命名3.3、变量提升3.4、代码注释3.5、语句3.6、区块 四、总结 一、JavaScript简介 JavaScript 是一种高级的、解释型的编程语言&#xff0c;主要用于为网页添加交互性和动态效…

CSS实现卡片在鼠标悬停时突出效果

在CSS中&#xff0c;实现卡片在鼠标悬停时突出&#xff0c;通常使用:hover伪类选择器。 :hover伪类选择器用于指定当鼠标指针悬停在某个元素上时&#xff0c;该元素的状态变化。通过:hover选择器&#xff0c;你可以定义鼠标悬停在元素上时元素的样式&#xff0c;比如改变颜色、…

绝地求生:三大赛区PGS资格赛冠军已揭晓,2024PCL春季赛临近!

随着工资杯S2落幕&#xff0c;亚太、欧洲、美洲三大赛区的PGS资格赛也已结束&#xff0c;三大赛区冠军队伍分别是CES、TM、FALCONS。欧洲赛区此次竞争非常激烈&#xff0c;冠亚军的分差仅1分&#xff0c;从NAVI转会至TM的xmpl为TM的夺冠起到了非常重要的作用&#xff0c;此地大…

(二)ffmpeg 拉流推流示例

一、搭建流媒体服务器 在这里&#xff0c;选用的流媒体服务器是mediamtx。 下载地址&#xff1a;https://github.com/bluenviron/mediamtx/releases/tag/v1.6.0 系统不同选择的压缩包不同&#xff0c;我用的是ubuntu系统。 下载下来之后进行解压&#xff0c;可以看到里面有三…

抖音评论ID提取工具|视频关键词评论批量采集软件

抖音评论ID提取工具&#xff1a;批量抓取抖音评论 抖音评论ID提取工具是一款功能强大的软件&#xff0c;可以帮助您批量抓取抖音视频下的评论信息。通过输入关键词和评论监控词&#xff0c;即可进行评论的抓取&#xff0c;并提供评论昵称、评论日期、评论内容、命中关键词以及所…

SecureCRT通过私钥连接跳板机,再连接到目标服务器(图文教程)

文章目录 1. 配置第一个session&#xff08;跳板机&#xff09;2. 设置本地端口3. 设置全局firewall4. 配置第二个session&#xff08;目标服务器&#xff09; 服务器那边给了一个私钥&#xff0c;现在需要通过私钥连接跳板机&#xff0c;再连接到目标服务器上 &#x1f349; …

使用lv_micropython

想要在ESP32-C3使用Micropython开发GUI&#xff0c;所以需要编译lv_micropython&#xff0c;当前github上的版本是9.1.0。 一、开发环境 因为编译lv_micropython需要在linux系统下&#xff0c;但是我的电脑是windows系统&#xff0c;所以我在windows系统上安装了VMware虚拟机&…

微软对其基于Arm的Windows系统终将超越苹果充满信心

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…

Flutter仿Boss-6.底部tab切换

效果 实现 图片资源采用boss包中的动画webp资源。Flutter采用Image加载webp动画。 遇到的问题 问题&#xff1a;Flutter加载webp再次加载无法再次播放动画问题 看如下代码&#xff1a; Image.asset(assets/images/xxx.webp,width: 40.w,height: 30.w, )运行的效果&#xf…

【Liunx】什么是make和makefile?

&#x1f490; &#x1f338; &#x1f337; &#x1f340; &#x1f339; &#x1f33b; &#x1f33a; &#x1f341; &#x1f343; &#x1f342; &#x1f33f; &#x1f344;&#x1f35d; &#x1f35b; &#x1f364; &#x1f4c3;个人主页 &#xff1a;阿然成长日记 …

抖音电商小店短视频直播年度运营规划方案

【干货资料持续更新&#xff0c;以防走丢】 抖音电商小店短视频直播年度运营规划方案 部分资料预览 资料部分是网络整理&#xff0c;仅供学习参考。 PPT可编辑&#xff08;完整资料包含以下内容&#xff09; 目录 年度运维方案的详细整理和规划。 一、行业分析洞察 - 市场增…

运行gitHub中的vue项目,遇到三个报错解决方案

报错1&#xff1a;解决npm run serve启动报错npm ERR Missing script:"serve" 启动项目的时候用npm run serve发现报了以下的错误 npm ERR! Missing script: "serve" npm ERR! npm ERR! To see a list of scripts, run: npm ERR! npm runnpm ERR! A co…

ubuntu下NTFS分区无法访问挂载-解决办法!

Ubuntu系统下&#xff0c;有的时候发现&#xff0c;挂载的NTFS文件系统硬盘无法访问。点击弹出类似问题&#xff1a; Error mounting /dev/sda1 at /media/root/新加卷: Command-line mount -t "ntfs" -o "uhelperudisks2,nodev,nosuid,uid0,gid0" "/…

为什么电脑越用越慢!

电脑随着时间推移逐渐变慢是一个常见的现象,其背后涉及多种原因。以下是导致电脑运行速度变慢的几个主要因素: 系统资源消耗增加 软件更新与新增应用:随着软件版本的更新和新应用程序的安装,它们往往对硬件资源的需求更高,尤其是对处理器、内存和硬盘的要求。这些新软件可…

LeetCode 53. 最大子序和

解题思路 相关代码 class Solution {public int maxSubArray(int[] nums) {//f[i]是以nums[i]结尾的连续子数组的最大和。int f[] new int[100010];f[0] nums[0];int resnums[0];for(int i1;i<nums.length;i){f[i] Math.max(f[i-1]nums[i],nums[i]);res Math.max(res,f…

(WSI分类)WSI分类文献小综述 2024

2024的WSI分类。 Multiple Instance Learning Framework with Masked Hard Instance Mining for Whole Slide Image Classification &#xff08;ICCV2024&#xff09; 由于阳性组织只占 Gi- gapixel WSI 的一小部分&#xff0c;因此现有的 MIL 方法直观上侧重于通过注意力机…

算法——倍增

. - 力扣&#xff08;LeetCode&#xff09; 给你一棵树&#xff0c;树上有 n 个节点&#xff0c;按从 0 到 n-1 编号。树以父节点数组的形式给出&#xff0c;其中 parent[i] 是节点 i 的父节点。树的根节点是编号为 0 的节点。 树节点的第 k 个祖先节点是从该节点到根节点路径…

关于ansible的模块 ⑤

转载说明&#xff1a;如果您喜欢这篇文章并打算转载它&#xff0c;请私信作者取得授权。感谢您喜爱本文&#xff0c;请文明转载&#xff0c;谢谢。 继《关于Ansible的模块 ①》、《关于Ansible的模块 ②》、《关于Ansible的模块 ③》与《关于Ansible的模块 ④》之后&#xff0c…