本文为您介绍如何将视频剪辑 Web SDK 集成到您的 Web 应用中,并结合视频点播的云端服务,构建一个功能强大的在线视频剪辑器。
在开始前端集成之前,请确保您已完成以下准备工作:
projectId 和 groupId。注意
调用 CreateProject 时:
Space 和 EditParam.Upload.SpaceName 两个参数,且取值相同,确保剪辑工程、剪辑素材和最终产物都归属于同一个点播空间。EditParam.Canvas 的尺寸为 1920x1080 (16:9) 或 1080x1920 (9:16),SDK 当前仅支持这两种画布尺寸。v14.x 或更高版本(推荐使用 LTS 版本)。在您的前端项目 HTML 文件中,通过 CDN 链接引入 SDK 的 CSS 和 JS 文件。
在 <head> 标签内引入 CSS 文件:
<head> <link rel="stylesheet" href="https://lf-unpkg.volccdn.com/obj/vcloudfe/sdk/@byted/veveditor/1.0.1/veveditor.css"> </head>
在 <body> 标签内添加一个用于挂载剪辑器的容器 <div>,并在 </body> 标签前引入 JS 文件:
<body> <div id="editor-container" style="height: 100vh; width: 100vw;"></div> <script src="https://lf-unpkg.volccdn.com/obj/vcloudfe/sdk/@byted/veveditor/1.0.1/veveditor.umd.js"></script> <script> // SDK 初始化代码将写在这里 </script> </body>
在 <script> 标签中,通过 new window.VeVEditor(param) 来实例化剪辑器。您需要传入在前提条件中获取的 projectId 和 groupId。param 对象是初始化的核心,包含挂载点、基础配置、API 代理和事件回调等所有必需信息。详情请见参数说明。
// 从服务端获取或在 URL 参数中获取 const projectId = 'your-project-id'; const groupId = 'your-group-id'; // 构造初始化参数对象 const param = { container: document.getElementById('editor-container'), config: { projectId: projectId, groupId: groupId, region: 'cn-north-1', // ... 其他基础配置 }, actions: { // 关键:在此实现所有与您后端服务通信的 API 调用 describeProject: async (params) => { /* ... */ }, updateProject: async (params) => { /* ... */ }, // ... }, handlers: { // 关键:在此实现事件回调处理 onNavBack: () => { /* ... */ }, onProjectSubmit: () => { /* ... */ }, // ... } }; const veveditor = new window.VeVEditor(param);
VeVEditor 的初始化 param 对象由多个模块组成,用于控制剪辑器的行为、外观和数据通信。
参数 | 类型 | 必填 | 描述 |
|---|---|---|---|
|
| 是 | 用于挂载剪辑器 UI 的 DOM 容器节点。SDK 将在此节点内部渲染整个剪辑器界面。 |
|
| 是 | 基础配置,包含 |
|
| 是 | API 代理配置。SDK 内部所有对视频点播服务端 API 的请求,都会通过您在此处定义的函数发起。您需要在此实现对您后端服务的请求封装。详见 Actions(API 代理)。 |
|
| 是 | 事件回调配置。用于处理剪辑器内部触发的用户行为或状态变化,如点击返回按钮、提交导出任务等。详见 Handlers(事件回调)。 |
配置剪辑器的基础信息和各功能模块。
参数 | 类型 | 必填 | 描述 |
|---|---|---|---|
|
| 是 | 剪辑工程 ID。通过服务端调用 |
|
| 是 | 剪辑工程所属的组 ID。通过服务端调用 |
|
| 是 | 服务地域。当前仅支持 |
|
| 否 | 本地上传媒资后,是否自动调用 UpdateMediaPublishStatus 接口将媒资状态设置为“已发布”。默认为 |
|
| 否 | 配置剪辑器顶部导航栏 UI 的显示/隐藏。详见 Header(顶部导航栏配置)。 |
|
| 否 | 配置素材库页面的功能和行为。详见 Material(素材库页面)。 |
|
| 否 | 配置文字页面。详见 Text(文字页面)。 |
|
| 否 | 配置特效页面。详见 Effect(特效)。 |
|
| 否 | 配置转场页面。详见 Transition(转场)。 |
|
| 否 | 配置滤镜页面。详见 Filter(滤镜)。 |
actions 对象中的每一个函数,都对应一个 SDK 需要调用的视频点播服务端 API。您必须实现所有标记为“是”的函数,在函数内部完成对您自己后端服务的网络请求,并返回服务端 API 响应中的 Result 部分。
函数名 | 对应服务端 API | 必填 | 描述 |
|---|---|---|---|
| 是 | SDK 初始化时调用,用于获取剪辑工程的初始数据结构。 | |
| 是 | 在编辑过程中(如拖拽、删减素材)自动或手动调用,用于保存工程草稿。 | |
| 是 | 用户点击“导出”按钮时调用,用于提交视频剪辑任务。 | |
| 是 | 用户在“从系统导入 > 视频库”中浏览或搜索视频时调用,用于拉取点播空间中的视频列表。 | |
| 是 | 用户在“从系统导入 > 素材库”中浏览或选择素材时调用,用于拉取点播空间中的素材列表。 | |
| 是 | SDK 初始化或切换工程时调用,用于获取当前工程已引用的所有素材列表。 | |
| 是 | 用户从工程中移除素材时调用。 | |
| 是 | 用户向工程中添加素材时调用。 | |
| 是 | 加载特效、转场、滤镜、贴纸、花字等资源列表时调用。 | |
| 是 | 当 | |
|
| 是 | 预览轨道上的视频素材时调用,用于获取视频播放分地址、视频时长等信息。SDK 会传入包含 |
actions.getVideoInfo 函数必须返回一个包含以下字段的 MediaInfo 对象。您需要从服务端 GetVideoPlayInfo 接口的响应中提取并组装这些数据。
参数 | 类型 | 必填 | 描述 | 来源 |
|---|---|---|---|---|
|
| 是 | 音视频资源的播放地址 | 从 GetVideoPlayInfo 响应中的 |
|
| 是 | 音视频资源的封面图地址 | 从 GetVideoPlayInfo 响应中的 |
|
| 是 | 音视频资源的时长 | 从 GetVideoPlayInfo 响应中的 |
|
| 是 | 视频宽度 | 从 GetVideoPlayInfo 响应中的 |
|
| 是 | 视频高度 | 从 GetVideoPlayInfo 响应中的 |
handlers 对象用于监听并响应剪辑器内部的特定事件。
函数名 | 类型 | 必填 | 描述 |
|---|---|---|---|
|
| 是 | 用户点击素材库页面中的“确定上传”按钮时触发。您可以在此回调中唤起您自定义的上传组件或页面。 |
|
| 是 | 用户点击剪辑器右上角的“导出”按钮、成功执行 |
|
| 否 | 当 |
|
| 否 | 用户点击剪辑器左上角的“返回”按钮时触发。您可以在此实现页面返回、弹窗确认等自定义逻辑。 |
|
| 否 | 当轨道上的视频或音频素材因 URL 失效等原因预览失败时触发。您可以在此进行错误上报或给出自定义提示。 |
用于控制剪辑器顶部导航栏各元素的可见性。
参数 | 类型 | 必填 | 默认值 | 描述 |
|---|---|---|---|---|
|
| 否 |
| 是否整体显示顶部导航栏。 |
|
| 否 |
| 是否显示左上角的“返回”按钮。 |
|
| 否 |
| 是否显示右上角的“导出”按钮。 |
|
| 否 |
| 是否允许用户点击并编辑工程名称。 |
用于配置素材库页面的行为。
参数 | 类型 | 必填 | 默认值 | 描述 |
|---|---|---|---|---|
|
| 否 |
| 是否整体显示素材库页面。 |
|
| 否 |
| 是否在素材库页面中启用“从本地上传”功能。若为 |
|
| 否 |
| 用于限制从本地上传的文件类型。
|
|
| 否 |
| 用于限制从系统导入的视频文件类型。支持 mp4、webm、mov。 |
|
| 否 |
| 素材库为空状态时显示的自定义图标的 URL。 |
用于配置文字页面的行为。
参数 | 类型 | 必填 | 默认值 | 描述 |
|---|---|---|---|---|
|
| 否 |
| 是否整体显示文字页面入口。 |
|
| 否 |
| 是否启用文字动画功能。 |
参数 | 类型 | 必填 | 默认值 | 描述 |
|---|---|---|---|---|
|
| 否 |
| 是否整体显示特效页面。 |
参数 | 类型 | 必填 | 默认值 | 描述 |
|---|---|---|---|---|
|
| 否 |
| 是否整体显示转场页面。 |
参数 | 类型 | 必填 | 默认值 | 描述 |
|---|---|---|---|---|
|
| 否 |
| 是否整体显示滤镜页面。 |
var projectId = 'your-project-id'; // 剪辑工程ID var groupId = 'your-group-id'; // 分组 ID var veveditor = new window.VeVEditor({ container: document.getElementById('editor-container'), config: { projectId: projectId, groupId: groupId, region: 'cn-north-1', autoPublish: true, header: { show: true, isNavBackVisible: true, isProjectSubmitVisible: true, isProjectNameEditable: true, }, material: { show: true, enableLocalUpload: true, uploadAccept: 'image/*,.mp3,.mp4,.webm', videoAccept: '.mp4,.webm', }, filter: { show: true }, transition: { show: true }, effect: { show: true }, text: { show: true, enableAnimation: true, }, }, actions: { searchVideo: async (params) => { // 搜索音视频素材 var res = await request('api/SearchVideo', params); return res.Result; }, mGetMaterial: async (params) => { // 查询图片素材 var res = await request('api/MGetMaterial', params); return res.Result; }, describeProject: async (params) => { // 查询剪辑工程信息 var res = await request('api/DescribeProject', params); return res.Result; }, updateProject: async (params) => { // 更新剪辑工程信息 var res = await request('api/UpdateProject', params); return res.Result; }, searchEditMaterial: async (params) => { // 查询剪辑工程已添加素材列表 var res = await request('api/SearchEditMaterial', params); return res.Result; }, getEffectList: async (params) => { // 查询花字、特效、转场、动效、滤镜资源包信息 var res = await request('api/GetEffectList', params); return res.Result; }, submitEditTaskAsync: async (params) => { // 导出剪辑任务 var res = await request('api/SubmitEditTaskAsync', params); return res.Result; }, deleteEditMaterial: async (params) => { // 删除剪辑素材 var res = await request('api/DeleteEditMaterial', params); return res.Result; }, createEditMaterial: async (params) => { // 添加剪辑素材 var res = await request('api/CreateEditMaterial', params); return res.Result; }, updateMediaPublishStatus: async (params) => { // 发布媒资 var res = await request('api/UpdateMediaPublishStatus', params); return res.Result; }, getVideoInfo: async (params) => { const res = await get('/api/GetVideoPlayInfo', params); return { ...res.Result?.VideoDetail?.VideoDetailInfo ?? {}, ...res.Result?.VideoDetail?.VideoDetailInfo?.PlayInfo ?? {}, PlayUrl: res.Result?.VideoDetail?.VideoDetailInfo?.PlayInfo?.MainPlayUrl, }; }, }, handlers: { uploadMaterial: async (file, options) => { // 完整示例见体验Demo }, onNavBack: () => { console.log('用户点击返回按钮'); // 处理返回逻辑,如跳转到上一页 }, onUploadMaterial: (params) => { console.log('用户上传素材', params); // 处理素材上传逻辑 }, onProjectSubmit: () => { console.log('项目提交完成'); // 处理项目提交后的逻辑 } } });
预览失败通常与素材的播放地址或网络环境有关。可按以下步骤排查: