AI视频生成实战:Codex与Remotion编程式视频制作全解析 最近在技术社区和视频创作圈里Codex 这个名字被频繁提及与之相关的 Remotion、HyperFrames 等技术也引发了大量讨论。很多朋友尤其是从事视频剪辑、内容创作的朋友都在问一个尖锐的问题Codex 这类 AI 视频工具真的会让剪辑师失业吗作为一名长期关注开发工具和技术演进的博主我深入体验了 Codex 及其相关生态并尝试将其集成到实际的开发与内容生产流程中。我的结论是Codex 不是剪辑师的“失业通知书”而是效率的“倍增器”和创意的“新画笔”。它正在重塑视频制作的工作流将从业者从大量重复、机械的劳动中解放出来转而聚焦于更高价值的创意构思、艺术指导和叙事把控。本文将从一个开发者和技术应用者的角度为你彻底拆解 Codex 及其相关技术栈如 Remotion、HyperFrames。我们不只停留在概念讨论而是通过完整的实战教程手把手带你从零搭建环境、编写代码到最终生成一个 AI 驱动的动态视频。无论你是想了解 AI 视频生成原理的开发者还是寻求效率突破的内容创作者都能在本文中找到可落地的方案和代码。1. Codex 与 AI 视频生成核心概念与生态解读在深入实战之前我们必须厘清几个容易混淆的核心概念。网络上“Codex”一词可能指向不同事物这里我们主要讨论的是与AI 视频生成和编程式视频编辑相关的 Codex 生态。1.1 什么是 Codex本文语境下的定义在 AI 视频生成领域Codex通常指的是一类能够理解自然语言或代码指令并自动生成或编辑视频内容的 AI 模型或平台。它可能不是一个单一产品而是一个技术范畴。根据网络热词和社区讨论其能力可能涵盖脚本/提示词生成视频输入一段文字描述AI 自动生成匹配的视频片段。智能剪辑自动识别视频素材中的精彩片段、进行粗剪、添加转场。程序化视频合成通过编写代码如使用 Remotion来定义视频的每一帧实现数据驱动、批量生成的视频。重要区分此“Codex”需与 OpenAI 的 Codex 模型用于代码生成区分开。本文聚焦于视频生成领域的工具和框架。1.2 Remotion编程式视频制作的革命性框架Remotion是一个基于 React 和 TypeScript 的框架允许你用代码创建视频和动态图形。这是理解“Codex 的 Remotion”这一热词的关键。核心思想将视频的每一帧视为一个 React 组件渲染的结果。你可以使用熟悉的 React 语法、状态State、属性Props来动态控制视频内容。与 AI 结合点Codex 类 AI 可以生成 Remotion 所需的代码或 JSON 配置从而自动化视频的生成过程。例如AI 分析脚本后输出一个描述场景、文字动画、图片位置的 Remotion 项目结构。优势高度可编程、可批量生成、版本可控、易于与数据 API 集成。非常适合制作数据可视化视频、个性化营销视频、教育课件等。1.3 HyperFrames (by HeyGen) 与 OpenMontageAI 视频工作流HyperFrames通常指 HeyGen 等平台提供的功能能够将静态图片如 PPT或长文本快速转换为带有视觉动态、配音和字幕的讲解视频。它代表了端到端 AI 视频生成的一种成熟应用。OpenMontage从热词看这是一个旨在打通 AI 视频生成、配音、剪辑全链路的工具或平台。它解决了传统流程中需要在不同软件间切换、操作繁琐的痛点。生态关系CodexAI能力可以作为引擎驱动 Remotion编程框架或 HyperFrames/OpenMontage集成化应用来生产视频。开发者更常接触的是 Remotion 这条技术路径。2. 环境准备构建你的 Codex Remotion 开发环境我们将选择Remotion作为实战平台因为它开源、免费且最能体现“用代码创造视频”的精髓也与“Codex”的自动化生成理念紧密结合。2.1 系统与工具要求操作系统Windows 10/11, macOS, 或 Linux (本文示例以 macOS/Windows 为主)。Node.js版本 16 或更高推荐 LTS 版本。这是运行 Remotion 的基础。包管理器npm 或 yarn。本文使用 npm。代码编辑器Visual Studio Code (VSCode) 是绝佳选择拥有丰富的插件生态。FFmpegRemotion 依赖 FFmpeg 进行视频和音频的编码。这是必须安装的系统级依赖。2.2 安装 Node.js 与 FFmpeg1. 安装 Node.js访问 Node.js 官网 下载并安装 LTS 版本。安装后在终端验证node --version npm --version2. 安装 FFmpegmacOS (使用 Homebrew):brew install ffmpegWindows (使用 Chocolatey):choco install ffmpegWindows (手动安装):访问 FFmpeg 官网 下载 Windows 构建版本。解压到一个目录例如C:\ffmpeg。将该目录的bin文件夹路径如C:\ffmpeg\bin添加到系统的环境变量Path中。Linux (Ubuntu/Debian):sudo apt update sudo apt install ffmpeg安装后在终端验证ffmpeg -version2.3 初始化 Remotion 项目Remotion 官方提供了极简的模板让我们快速开始。打开终端进入你希望创建项目的目录。使用 npm 创建新项目npx create-videolatest这个命令会启动一个交互式命令行工具。根据提示选择Select a template: 选择Hello World最基础的模板。Enter a name for your new video: 输入项目名例如my-ai-video。工具会自动创建文件夹并安装依赖。进入项目并启动cd my-ai-video npm run start如果一切顺利浏览器会自动打开http://localhost:3000你将看到 Remotion 的播放器界面和一个示例视频。这证明你的基础环境已配置成功。项目结构速览my-ai-video/ ├── node_modules/ ├── public/ ├── src/ │ ├── index.tsx # 项目入口注册可合成的视频组件 │ ├── Root.tsx # 视频的根组件定义全局样式、尺寸等 │ ├── HelloWorld/ # 示例视频组件 │ │ ├── index.tsx │ │ └── schema.ts │ └── Compositions.tsx # 所有视频组合Compositions的列表 ├── package.json ├── remotion.config.ts # Remotion 配置文件 └── tsconfig.jsonComposition是 Remotion 的核心概念代表一个可被渲染的视频实体定义了时长、帧率、尺寸等元数据。3. 核心原理与语法拆解用 React 组件思维做视频理解 Remotion 的关键在于转换思维从时间线拖拽变为编写声明式组件。3.1 一个最简单的 Composition打开src/HelloWorld/index.tsx你会看到类似下面的代码import { AbsoluteFill, useCurrentFrame } from “remotion”; export const HelloWorld: React.FC () { const frame useCurrentFrame(); // 获取当前帧号 const opacity frame / 30; // 根据帧数计算不透明度30帧后完全显现 return ( AbsoluteFill style{{ backgroundColor: ‘white’ }} div style{{ opacity, fontSize: 100, textAlign: ‘center’ }} Hello World! Frame {frame} /div /AbsoluteFill ); };useCurrentFrame(): 这是一个 Remotion Hook用于获取当前正在渲染的帧的编号从0开始。frame / 30: 这是一个动画逻辑。在第0帧opacity为0完全透明在第30帧opacity为1完全不透明。这就实现了一个淡入效果。AbsoluteFill: 一个 Remotion 提供的布局组件它会填满整个视频画布。在src/Compositions.tsx中这个组件被注册为一个Compositionimport { HelloWorld } from “./HelloWorld”; export const RemotionRoot: React.FC () { return ( Composition id“HelloWorld” // 唯一标识符 component{HelloWorld} // 关联的React组件 durationInFrames{60} // 视频总时长帧数 fps{30} // 帧率 width{1920} // 视频宽度 height{1080} // 视频高度 / / ); };这意味着一个名为 “HelloWorld”、时长2秒60帧 / 30fps、分辨率1080p的视频被定义好了。3.2 动态内容与数据驱动Remotion 的强大之处在于视频内容可以由数据动态决定。假设我们有一个 API 返回每日数据我们可以生成每日报告视频。示例生成一个简单的数据图表动画// src/DataChart/index.tsx import { AbsoluteFill, interpolate, useCurrentFrame } from “remotion”; // 模拟一周的数据 const weeklyData [12, 19, 3, 5, 2, 15, 9]; const days [‘Mon’, ‘Tue’, ‘Wed’, ‘Thu’, ‘Fri’, ‘Sat’, ‘Sun’]; export const DataChart: React.FC () { const frame useCurrentFrame(); const durationPerBar 10; // 每个柱状图动画持续的帧数 return ( AbsoluteFill style{{ backgroundColor: ‘#f0f0f0’, padding: 50 }} h1 style{{ textAlign: ‘center’ }}Weekly Performance/h1 div style{{ display: ‘flex’, alignItems: ‘flex-end’, height: 400, gap: ’20px’, justifyContent: ‘center’ }} {weeklyData.map((value, index) { // 计算当前柱子的动画进度 const animationStartFrame index * durationPerBar; const animationProgress Math.min(Math.max((frame - animationStartFrame) / durationPerBar, 0), 1); // 使用 interpolate 实现缓动效果 const height interpolate(animationProgress, [0, 1], [0, value * 15]); return ( div key{index} style{{ display: ‘flex’, flexDirection: ‘column’, alignItems: ‘center’ }} div style{{ width: 40, height: ${height}px, backgroundColor: ‘#4f46e5’, borderRadius: ‘5px 5px 0 0’, transition: ‘height 0.2s’, // 注意CSS transition在逐帧渲染中无效这里仅示意 }} / div style{{ marginTop: 10 }}{days[index]}/div div style{{ fontSize: 12, marginTop: 5 }}{value}/div /div ); })} /div div style{{ textAlign: ‘center’, marginTop: 30, fontSize: 20 }} Current Frame: {frame} /div /AbsoluteFill ); };在这个组件中我们根据frame动态计算每个柱状图的高度实现了数据图表依次增长的动画效果。interpolate是 Remotion 提供的一个非常有用的函数用于在不同输入范围间进行平滑映射。3.3 音频、序列与时间控制复杂的视频需要精确控制不同元素出现的时间。Remotion 提供了Sequence组件。import { AbsoluteFill, Sequence, Audio } from “remotion”; import { HelloWorld } from “./HelloWorld”; import { DataChart } from “./DataChart”; import audioSource from “./assets/background-music.mp3”; export const MyVideo: React.FC () { return ( AbsoluteFill {/* 从第0帧开始播放背景音乐 */} Audio src{audioSource} volume{0.5} / {/* 序列1从第0帧开始持续60帧显示HelloWorld */} Sequence from{0} durationInFrames{60} HelloWorld / /Sequence {/* 序列2从第45帧开始与序列1有15帧重叠持续90帧显示DataChart */} Sequence from{45} durationInFrames{90} DataChart / /Sequence {/* 可以添加更多序列... */} /AbsoluteFill ); };通过组合Sequence你可以构建出复杂的时间线这与传统非线性编辑软件NLE的轨道思维类似但完全由代码控制。4. 完整实战构建一个 AI 驱动的动态新闻简报视频现在我们将综合运用以上知识创建一个实战项目一个自动化的每日新闻简报视频。其工作流是脚本可由 AI 生成 - 解析为数据结构 - Remotion 代码生成视频。4.1 项目设计与数据结构假设我们有一个 AI 服务比如调用大语言模型 API它每天生成一份 JSON 格式的新闻摘要。数据结构如下// news-data.json { “date”: “2023-10-27”, “headline”: “科技前沿速递”, “stories”: [ { “title”: “Remotion 发布新版本”, “summary”: “Remotion 3.0 引入了更强大的音频处理API。”, “category”: “科技”, “imageUrl”: “https://example.com/tech-image.jpg” }, { “title”: “AI 辅助创作工具激增”, “summary”: “今年以来超过50款AI视频工具上线。”, “category”: “AI”, “imageUrl”: “https://example.com/ai-image.jpg” }, { “title”: “开源社区活跃度创新高”, “summary”: “GitHub 报告显示开发者协作项目数量增长40%。”, “category”: “开源”, “imageUrl”: “https://example.com/oss-image.jpg” } ] }我们的 Remotion 视频将根据这个 JSON 数据动态生成。4.2 创建新闻简报视频组件创建组件文件src/NewsBriefing/index.tsx编写核心逻辑import { AbsoluteFill, interpolate, useCurrentFrame, spring, Img, Sequence } from “remotion”; import newsData from “./news-data.json”; // 导入模拟数据 export const NewsBriefing: React.FC () { const frame useCurrentFrame(); const { date, headline, stories } newsData; // 1. 标题动画 const titleOpacity interpolate(frame, [0, 30], [0, 1], { extrapolateRight: “clamp” }); const titleScale spring({ frame, fps: 30, from: 0.8, to: 1 }); // 2. 计算每个新闻条目的开始帧 const storyDuration 120; // 每个新闻故事占据的帧数 const titleDuration 60; // 标题展示的帧数 return ( AbsoluteFill style{{ backgroundColor: ‘linear-gradient(to bottom, #1e3a8a, #0f172a)’, color: ‘white’, fontFamily: ‘Arial’ }} {/* 背景装饰 */} div style{{ position: ‘absolute’, top: 0, left: 0, right: 0, bottom: 0, background: ‘radial-gradient(circle at 20% 50%, rgba(120, 119, 198, 0.3) 0%, transparent 50%)’ }} / {/* 主标题区域 */} Sequence from{0} durationInFrames{titleDuration} div style{{ padding: 80 }} div style{{ fontSize: 24, opacity: 0.7, marginBottom: 10 }}{date}/div h1 style{{ fontSize: 72, margin: 0, opacity: titleOpacity, transform: scale(${titleScale}), }} {headline} /h1 /div /Sequence {/* 动态新闻列表 */} {stories.map((story, index) { const startFrame titleDuration index * storyDuration; return ( Sequence key{index} from{startFrame} durationInFrames{storyDuration} NewsStoryComponent story{story} index{index} / /Sequence ); })} {/* 底部滚动字幕 */} Sequence from{titleDuration} durationInFrames{stories.length * storyDuration} div style{{ position: ‘absolute’, bottom: 40, left: 0, right: 0, height: 2, backgroundColor: ‘rgba(255,255,255,0.2)’, }} / div style{{ position: ‘absolute’, bottom: 20, left: ‘100%’, whiteSpace: ‘nowrap’, fontSize: 18, opacity: 0.8, transform: translateX(${interpolate(frame - titleDuration, [0, stories.length * storyDuration], [0, -100])}vw), }} {stories.map(s s.title).join(‘ • ‘)} | Generated with Remotion AI /div /Sequence /AbsoluteFill ); }; // 子组件渲染单个新闻故事 const NewsStoryComponent: React.FC{ story: any; index: number } ({ story, index }) { const frame useCurrentFrame(); // 这个frame是相对于Sequence开始的 const entryProgress spring({ frame, fps: 30, from: 0, to: 1 }); const contentOpacity interpolate(frame, [0, 20], [0, 1]); return ( div style{{ padding: ‘60px 80px’, display: ‘flex’, alignItems: ‘center’, gap: ‘40px’, opacity: contentOpacity, transform: translateX(${interpolate(entryProgress, [0, 1], [100, 0])}px), }} {/* 左侧序号 */} div style{{ fontSize: 48, fontWeight: ‘bold’, opacity: 0.5, minWidth: 60 }}#{index 1}/div {/* 中间内容 */} div style{{ flex: 1 }} div style{{ display: ‘flex’, alignItems: ‘center’, gap: ‘15px’, marginBottom: 15 }} span style{{ backgroundColor: ‘#3b82f6’, padding: ‘5px 15px’, borderRadius: 20, fontSize: 14 }} {story.category} /span h2 style{{ fontSize: 36, margin: 0 }}{story.title}/h2 /div p style{{ fontSize: 24, lineHeight: 1.6, opacity: 0.9 }}{story.summary}/p /div {/* 右侧图片模拟 */} div style{{ width: 200, height: 120, backgroundColor: ‘rgba(255,255,255,0.1)’, borderRadius: 10, display: ‘flex’, alignItems: ‘center’, justifyContent: ‘center’, overflow: ‘hidden’, }} {story.imageUrl ? ( Img src{story.imageUrl} style{{ width: ‘100%’, height: ‘100%’, objectFit: ‘cover’ }} / ) : ( spanImage/span )} /div /div ); };4.3 注册 Composition 并渲染视频在src/Compositions.tsx中注册我们的新闻简报import { NewsBriefing } from “./NewsBriefing”; export const RemotionRoot: React.FC () { return ( {/* ... 其他 Composition ... */} Composition id“NewsBriefing” component{NewsBriefing} durationInFrames{480} // 标题60帧 3个故事*120帧 420帧多留一些 fps{30} width{1920} height{1080} defaultProps{{}} // 可以传递props / / ); };4.4 在浏览器预览与开发运行npm run start在浏览器中打开http://localhost:3000选择 “NewsBriefing” 这个 Composition你就可以实时预览这个动态生成的新闻视频了。你可以随时修改代码保存后预览会热更新。4.5 渲染输出视频文件开发满意后我们需要将 React 组件渲染成真正的视频文件如 MP4。安装渲染所需依赖如果尚未安装npm i remotion/renderer创建渲染脚本在项目根目录创建scripts/render-video.mjs使用 ES 模块。// scripts/render-video.mjs import { bundle } from “remotion/bundler”; import { renderMedia } from “remotion/renderer”; import path from “path”; import { fileURLToPath } from “url”; import { webpackOverride } from “../src/webpack-override.mjs”; // 如果有自定义webpack配置 const __dirname path.dirname(fileURLToPath(import.meta.url)); (async () { // 1. 打包你的Remotion项目 const bundleLocation await bundle({ entryPoint: path.join(__dirname, “../src/index.tsx”), webpackOverride: webpackOverride, // 可选 }); // 2. 定义渲染参数 const compositionId “NewsBriefing”; // 要渲染的Composition ID const outputLocation out/${compositionId}-${Date.now()}.mp4; // 3. 执行渲染 console.log(开始渲染视频: ${compositionId}...); await renderMedia({ compositionId, serveUrl: bundleLocation, codec: “h264”, // 编码格式 outputLocation, inputProps: {}, // 可以传递动态props这里我们用JSON文件静态数据所以为空 onProgress: ({ progress }) { console.log(渲染进度: ${Math.round(progress * 100)}%); }, }); console.log(视频渲染完成保存至: ${outputLocation}); })();运行渲染脚本node scripts/render-video.mjs根据视频复杂度和长度渲染可能需要几秒到几分钟。完成后视频文件将保存在out/目录下。至此一个完整的、数据驱动的 AI 视频生成流程就实现了。你可以将news-data.json的来源替换为真实的 AI API 接口实现全自动化每日视频生成。5. 常见问题与排查思路 (FAQ)在实际使用 Remotion 和构建 AI 视频流水线时你可能会遇到以下问题问题现象可能原因解决思路启动项目时报错或白屏1. Node.js 版本过低。2. 端口冲突。3. 依赖安装不完整。1. 检查 Node.js 版本 (node -v)确保 16。2. 尝试npm run start --port3001更换端口。3. 删除node_modules和package-lock.json重新运行npm install。渲染视频时报错FFmpeg not foundFFmpeg 未安装或未正确添加到系统 PATH。1. 终端运行ffmpeg -version确认安装。2. 如果已安装但 Remotion 找不到可在remotion.config.ts中指定路径setFFmpegExecutable(‘/path/to/ffmpeg’)。渲染出的视频卡顿或掉帧1. 组件渲染逻辑过于复杂每帧计算耗时太长。2. 使用了浏览器不支持的 CSS 属性或复杂滤镜。3. 图片/视频素材过大解码慢。1. 使用useCurrentFrame和interpolate时避免复杂循环或递归。2. 简化动画优先使用transform和opacity。3. 对素材进行预处理压缩、转换格式。使用Img组件并设置合适的尺寸。如何接入 AI 生成脚本不清楚如何将 AI API 与 Remotion 结合。1.设计阶段定义好视频数据结构的 Schema如之前的 JSON。2.AI 调用编写 Node.js 脚本调用 OpenAI GPT、Claude 或国内大模型 API让其按 Schema 输出 JSON。3.集成在渲染前将 AI 生成的 JSON 作为inputProps传递给 Remotion 组件或在构建时写入静态文件。“Codex 桌面版安装”相关问题概念混淆。可能指的是某个具体名为 Codex 的客户端软件。1. 明确需求如果需要的是编程式视频生成应学习 Remotion。2. 如果指的是集成化 AI 视频工具应搜索 “HeyGen HyperFrames” 或 “OpenMontage” 了解其官方安装方式。3. 警惕来路不明的“安装包”优先从官方 GitHub、官网或 npm 获取工具。渲染内存不足或崩溃视频分辨率过高、时长过长或特效太复杂。1. 尝试降低渲染分辨率 (width,height)。2. 分段渲染最后用 FFmpeg 拼接。3. 升级硬件或使用云渲染服务。6. 最佳实践与工程化建议将 CodexAI Remotion编程框架用于生产环境需要遵循一些工程最佳实践。6.1 项目结构与代码组织按功能模块划分将不同的视频场景如NewsBriefing,ProductIntro,DataViz放在独立的文件夹中。共享组件库创建src/components/目录存放可复用的 UI 组件如AnimatedText,FadeInBox。工具函数创建src/utils/目录存放动画缓动函数、数据格式化工具等。资源管理将字体、音乐、音效等静态资源放在public/或src/assets/下并通过引用使用。6.2 性能优化善用useCurrentFrame和interpolate它们是性能最好的动画方式比在组件内自己管理requestAnimationFrame更高效。图片优化使用 Remotion 的Img组件它内置了缓存和错误处理。预加载关键图片import { staticFile } from “remotion”;然后src{staticFile(“image.jpg”)}。对网络图片确保尺寸合适可使用图片 CDN 并指定宽度参数。避免内联样式对象重复创建对于静态样式应提取到组件外防止每次渲染都创建新对象。// 推荐 const containerStyle: React.CSSProperties { display: ‘flex’, padding: 20 }; const MyComp () div style{containerStyle}.../div; // 避免在频繁渲染的组件中 const MyComp () div style{{ display: ‘flex’, padding: 20 }}.../div;6.3 与 AI 工作流集成定义严格的接口契约AI 模型Codex和视频生成器Remotion之间通过清晰的 JSON Schema 通信。使用zod或joi库验证 AI 返回的数据结构确保渲染过程不会因数据格式错误而崩溃。实现降级方案AI 服务可能不稳定。设计流程时当 AI 生成失败或超时应能回退到使用模板或上一次成功的数据。批量渲染与队列如果需要生成大量个性化视频如给每个用户生成周报需要构建一个渲染队列系统如使用 Bull、RabbitMQ并监控渲染节点的负载。6.4 版本控制与协作代码即资产Remotion 项目本身就是代码应使用 Git 进行版本控制。这比管理.prproj(Premiere) 或.fcpxml(Final Cut) 文件友好得多。Code Review视频的修改可以通过 Pull Request 进行审查清晰地看到每一帧逻辑的变化。CI/CD 渲染可以将视频渲染集成到 CI/CD 流水线中。例如每当数据仓库更新或 AI 模型重新训练后自动触发视频渲染任务生成最新的数据可视化报告。7. 总结剪辑师与开发者的新机遇回到最初的问题Codex 真能让剪辑师失业吗通过本文的深入探讨和实战答案已经非常清晰。以 Remotion 为代表的编程式视频生成以及背后驱动的 AI 能力不是在取代剪辑师而是在进化视频生产的技术栈。对于剪辑师/内容创作者学习基础的代码逻辑尤其是数据驱动和条件判断不再是天方夜谭。掌握像 Remotion 这样的工具意味着你可以将创意从手动操作中解放出来去处理更复杂的叙事、节奏和艺术风格。你的核心价值——审美、叙事和导演能力——变得更为重要。你从“操作员”转变为“导演和系统架构师”。对于开发者这是一片充满机会的新大陆。你可以利用已有的编程技能构建自动化的视频流水线、创建动态数据可视化视频、开发个性化的视频营销工具。视频生成成为了一个新的、可编程的“输出界面”。未来的视频制作团队很可能是由创意策划定义内容和风格、AI 提示工程师将创意转化为结构化数据/指令、视频开发工程师用代码实现动态模板和逻辑和传统剪辑师处理 AI 难以完成的精细剪辑、调色、合成共同组成的混合体。技术的学习路线建议入门掌握 React/TypeScript 基础完成 Remotion 官方教程。进阶深入理解 Remotion 的useCurrentFrame,interpolate,spring,Sequence,Audio等核心 API。学习 FFmpeg 基础命令。集成学习如何调用大语言模型LLMAPI如 OpenAI, DeepSeek并让其输出结构化的视频描述数据。工程化构建完整的 Node.js 后端服务实现从“文本输入”到“视频输出”的全自动化流水线并加入队列、监控、日志。工具永远在变但用技术创造美和效率的初心不变。Codex 和 Remotion 打开了这扇新的大门门后的世界属于愿意拥抱变化的每一个人。