智能生产制作提供专业在线的直播剪辑能力,针对时效性内容,您可以同时进行直播和剪辑。通过阅读本文,您可以了解如何接入直播剪辑Web SDK。
使用说明
本文中引入的直播剪辑Web SDK的版本号1.1.2仅供参考。获取最新的版本,请参见直播剪辑工程——帮助信息。
操作步骤
引入直播剪辑Web SDK。
在项目前端页面文件中的
<head>
标签处引入直播剪辑Web SDK的CSS文件,如下所示:<head> <link rel="stylesheet" href="https://g.alicdn.com/thor-server/live-editing-websdk/1.1.2/index.css"> </head>
在
<body>
标签处添加一个用以挂载剪辑界面的<div>
节点,并在<body>
标签末尾添加引入Web SDK的JS文件,同时添加一个用以调用Web SDK的<script>
节点。<body> <div id="aliyun-live-editor" style="height:700px"></div> // 您可以根据需要改变 container 高度 <script src="https://g.alicdn.com/thor-server/live-editing-websdk/1.1.2/index.js"></script> <script> // 调用 SDK 的代码放在这里 </script> </body>
初始化直播剪辑Web SDK。
window.AliyunLiveEditor.init(config);
参数
config
为对象,对象中的属性说明请参见config属性说明。初始化函数
init()
示例请参见init()示例代码。
config属性说明
参数 | 类型 | 必填 | 描述 | 引入版本 |
locale | string | 否 | 界面语言,取值:
| 1.0.0 |
container | Element | 是 | Web SDK生成界面挂载的DOM节点。 | 1.0.0 |
projectId | string | 是 | 直播剪辑工程ID。 | 1.0.0 |
onBackButtonClick | () => void; | 否 | 左上角返回按钮响应函数,如果不传,则不显示此按钮。 | 1.0.0 |
updateEditingProject | (req: { ProjectId: string; Title: string }) => Promise<void>; | 否 | 修改剪辑工程标题,如果不传,则不允许修改,参数及返回值详情请参见UpdateEditingProject。 | 1.0.0 |
getEditingProject | (req: { ProjectId: string }) => Promise<Response<GetEditingProjectRsp>>; | 是 | 获取剪辑工程的元信息,例如:工程标题、保存路径等信息,参数及返回值详情请参见GetEditingProject。 | 1.0.0 |
getEditingProjectMaterials | (req: { ProjectId: string }) => Promise<Response<GetEditingProjectMaterialsRsp>>; | 是 | 获取直播工程关联的直播流和片段,参数及返回值详情请参见GetEditingProjectMaterials。 | 1.0.0 |
getLiveEditingIndexFile | (req: { ProjectId: string; DomainName: string; AppName: string; StreamName: string }) => Promise<Response<{ IndexFile: string }>>; | 是 | 获取直播录制流的播放地址,参数及返回值详情请参见GetLiveEditingIndexFile。 | 1.0.0 |
describeLiveDomainConfigs | (req: { DomainName: string; FunctionNames: string }) => Promise<Response<DomainConfigs>>; | 是 | 查询直播域名配置,参数及返回值详情请参见DescribeLiveDomainConfigs。 | 1.0.0 |
submitLiveEditingJob | (req: SubmitLiveEditingJobReq) => Promise<Response<{ MediaId: string }>>; | 是 | 提交合成片段任务,参数及返回值详情请参见SubmitLiveEditingJob。 | 1.0.0 |
getMediaInfo | (req: { MediaId: string }) => Promise<Response<{ MediaInfo: MediaInfo }>>; | 是 | 查询合成片段的状态,参数及返回值详情请参见GetMediaInfo。 | 1.0.0 |
onExport | (segments: Segment[]) => void; | 是 | 右上角导出到视频剪辑功能响应函数,segments为您选中的片段数组。 | 1.0.0 |
getDescribeLiveSnapshotConfig | (req: { DomainName: string; AppName: string }) => Promise<Response<GetDescribeLiveSnapshotConfigList>>; | 否 | 查询直播截图配置,参数及返回值详情请参见DescribeLiveSnapshotConfig。 | 1.1.0 |
getDescribeLiveStreamSnapshotInfo | (req: { DomainName: string; AppName: string; StreamName: string; StartTime: string; EndTime: string; Limit: number; Order: string }) => Promise<Response<LiveStreamSnapshotInfoList>>; | 否 | 查询截图内容,参数及返回值详情请参见DescribeLiveStreamSnapshotInfo。 | 1.1.0 |
batchGenOSSUrlWithSign | (req: { signList: SnapshotOssInfo[] }) => Promise<Response<SignedUrl[]>>; | 否 | 批量生成带鉴权串的OSS地址,即SignedUrl。 说明 如果截图配置的存储位置为私有Bucket,您需要在自己的服务端实现接口(用于批量生成带临时访问凭证的OSS资源地址),同时需要注意过期时间。具体操作,请参见签名版本1。 | 1.1.2 |
数据结构说明:
Segment
interface Segment { title: string; // 片段的标题 mediaId: string; // 片段的媒资ID coverUrl: string | null; // 片段的封面图地址,可能为 null duration: number; // 片段的时长,单位为毫秒 }
SnapshotOssInfo
interface SnapshotOssInfo { region: string; // 接入区域 bucketName: string; // OSS存储 Bucket 名称 objectName: string; // OSS存储的文件名,path/to/object.* }
init()示例代码
Web SDK只负责界面交互,不会发起请求,您需要通过Web SDK调用请求逻辑。请求本身应该先发送给您自己的服务端,您自己的服务端再根据AccessKey信息(AccessKey ID和AccessKey Secret)转发给相关的阿里云OpenAPI。
// 注意,WebSDK 本身并不提供 request 这个方法,这里仅作为示例,您可以使用您喜欢的网络请求库,如 axios 等
const projectId = 'exampleId';
window.AliyunLiveEditor.init({
locale: 'zh-CN',
container: document.getElementById('aliyun-live-editor'),
projectId,
onBackButtonClick: () => {
// 跳转回列表页
window.location.href = '/mediaEdit/list/live';
},
updateEditingProject: req => {
return request('UpdateEditingProject', req);
},
getEditingProject: req => {
return request('GetEditingProject', req);
},
getEditingProjectMaterials: req => {
return request('GetEditingProjectMaterials', req);
},
getLiveEditingIndexFile: req => {
return request('GetLiveEditingIndexFile', req);
},
describeLiveDomainConfigs: req => {
return request('DescribeLiveDomainConfigs', req);
},
submitLiveEditingJob: req => {
return request('SubmitLiveEditingJob', req);
},
getMediaInfo: req => {
return request('GetMediaInfo', req);
},
getDescribeLiveSnapshotConfig: req => {
return request('DescribeLiveSnapshotConfig', req);
},
getDescribeLiveStreamSnapshotInfo: req => {
return request('DescribeLiveStreamSnapshotInfo', req);
},
batchGenOSSUrlWithSign: req => {
return request('multiGenerateOSSURLWithSign', req); // https://help.aliyun.com/document_detail/31952.htm
},
onExport: async segments => {
const { ProjectMaterials = [] } = await request('GetEditingProjectMaterials', {
ProjectId: projectId
}).then(res => res.data);
let videoEditingProjectId;
if (ProjectMaterials.length) {
// 已经有绑定的视频剪辑工程
videoEditingProjectId = ProjectMaterials[0];
} else {
// 创建新的普通剪辑工程
const { Project } = await request('CreateEditingProject', {
Title: `直播剪辑视频_${projectId}`,
}).then(res => res.data);
// 绑定直播剪辑工程和普通剪辑工程
await request('AddEditingProjectMaterials', {
ProjectId: projectId,
MaterialMaps: JSON.stringify({ editingProject: Project.ProjectId })
});
videoEditingProjectId = Project.ProjectId;
}
const mediaIds = segments.map(s => s.mediaId);
await handleBindingMaterials(mediaIds, videoEditingProjectId);
// 打开普通剪辑工程的页面
window.open(`/mediaEdit/detail/${videoEditingProjectId}`);
},
});
// 因为新增素材绑定接口有一次请求最多绑定10条的限制,故分批操作
async function handleBindingMaterials(MediaIds, ProjectId) => {
const promiseGroup = [];
const addTimes = Math.ceil(MediaIds.length / 10);
for (let i = 0; i < addTimes; i++) {
const newMap = {};
const videoList = MediaIds.slice(i * 10, (i + 1) * 10);
if (videoList.length) {
newMap.video = videoList.join(',');
}
promiseGroup.push(
request('AddEditingProjectMaterials', {
ProjectId,
MaterialMaps: JSON.stringify(newMap)
})
);
}
await Promise.all(promiseGroup);
};
相关接口说明: