@youka / sdk
优卡API的官方Node.js SDK。
使用这个包从Node.js创建卡拉ok视频:上传音频或视频,同步或转录歌词,创建卡拉ok项目,渲染最终视频,并下载MP4。
安装
npm install @youka/sdk
API密匙
创建一个API密钥 online.youka.io /账户 下 API密钥.
将密钥保存在源代码之外:
export YOUKA_API_KEY="yk_..."
制作卡拉ok视频
import { AlignmentModel, YoukaClient } from "@youka/sdk";
const client = new YoukaClient({
apiKey: process.env.YOUKA_API_KEY!,
});
const operation = await client.projects.create({
source: {
type: "path",
path: "./song.mp3",
},
lyricsSource: {
type: "align",
lyrics: "Line one\nLine two\nLine three",
},
title: "Artist - Song",
});
const { project } = await client.projects.wait(operation);
const exportOperation = await client.exports.create(project.id, {
resolution: "1080p",
quality: "high",
});
const finalized = await client.exports.wait(exportOperation);
await client.exports.download(finalized, {
output: "./karaoke.mp4",
});
自动转录歌词
使用转录时,你还没有歌词文本:
const operation = await client.projects.create({
source: { type: "path", path: "./song.mp3" },
lyricsSource: { type: "transcribe" },
title: "Artist - Song",
});
当 syncModel 省略时,优卡使用ElevenLabs Scribe。ElevenLabs
每个用户都可以使用转录;AudioShake, MusicAI和Whisper
转录需要付费访问。
使用ElevenLabs Scribe
选择ElevenLabs Scribe单词计时转录没有提供的歌词:
import { AlignmentModel } from "@youka/sdk";
const operation = await client.projects.create({
source: { type: "path", path: "./song.mp3" },
lyricsSource: {
type: "transcribe",
syncModel: AlignmentModel.ElevenLabsTranscription,
},
title: "Artist - Song",
});
如果你已经有歌词,把它们作为可选的转录指导:
const operation = await client.projects.create({
source: { type: "path", path: "./song.mp3" },
lyricsSource: {
type: "transcribe",
syncModel: AlignmentModel.ElevenLabsTranscription,
lyrics: "Line one\nLine two\nLine three",
},
title: "Artist - Song",
});
Scribe总是返回自己的单词文本和时间。提供歌词提高词汇识别;它们不会强制输出与提供的文本匹配。
使用托管媒体URL
您还可以从托管媒体URL创建卡拉ok视频:
const operation = await client.projects.create({
source: {
type: "url",
url: "https://example.com/song.mp4",
},
lyricsSource: {
type: "align",
lyrics: "Line one\nLine two",
},
});
URL帮助程序在第一次使用时自动确保本地下载二进制文件。支持的托管站点依赖于yt-dlp: https://github.com/yt-dlp/yt-dlp/blob/master/supportedsites.md
处理错误
import { YoukaRequestError, YoukaTaskError } from "@youka/sdk";
try {
const operation = await client.projects.create({
source: { type: "path", path: "./song.mp3" },
lyricsSource: { type: "transcribe" },
});
await client.projects.wait(operation);
} catch (error) {
if (error instanceof YoukaRequestError) {
console.error(error.code, error.status, error.message);
} else if (error instanceof YoukaTaskError) {
console.error(error.code, error.status, error.message);
} else {
throw error;
}
}
文档
- Node.js SDK指南: https://docs.youka.io/en/sdk
- 原始HTTP快速入门: https://docs.youka.io/en/api/quickstart
- CLI指南: https://docs.youka.io/en/cli
模型发现和歌词视频
使用 await client.capabilities.get() 要发现支持的模型、工作流、
输入要求、语言政策和帐户资格。每一个支持
模型表示;隔离声音模型仅限于兼容的工作流。
引用和创建执行相同的规则。
const operation = await client.projects.create({
kind: "lyric-video",
source: { type: "path", path: "./reference.wav" },
title: "Lyric overlay",
lyricsSource: {
type: "transcribe",
syncModel: AlignmentModel.ElevenLabsTranscription,
lyrics: "Optional recognition hints",
languageHintMode: "auto",
},
});
const { project } = await client.projects.wait(operation);
抒情视频跳过分离和拒绝 splitModel。省略了 kind 保存
卡拉ok的行为。使用 lyricsSource: { type: "align", lyrics: "...", syncModel }
用于提供的文本对齐或 lyricsSource: null 跳过歌词处理。
projects.quote() 接受相同的源/工作流配置。
正确的时间安排和重用版本
const list = await client.projects.alignments.list(project.id);
const current = await client.projects.alignments.get(
project.id,
list.alignments[0]!.id,
);
const corrected = structuredClone(current.alignment);
corrected.items[0]!.start = 1.25;
corrected.items[0]!.end = 1.75;
await client.projects.alignments.update(project.id, current.id, {
alignment: corrected,
expectedRevision: current.revision,
select: true,
expectedSelectionRevision: current.selectionRevision,
});
const versions = await client.projects.versions.list(project.id);
const versionId = versions[0]!.id;
const settings = await client.projects.getSettings(project.id, { versionId });
await client.projects.updateSettings(project.id, {
versionId,
settings: settings.settings,
});
const fresh = await client.projects.get(project.id);
await client.exports.create(project.id, {
target: "local",
versionId,
transparent: true,
stemVolumes: Object.fromEntries(fresh.stems.map((stem) => [stem.id, 0])),
outputPath: "./overlay.mov",
});
计时替换使用完整的、绝对的小数秒计时。保存id,
索引、歌手和翻译元数据。无效的范围被拒绝并且过期
修订返回冲突;重试前请重新获取并调和。选择独自一人
使用 projects.alignments.select(projectId, alignmentId, { expectedRevision, expectedSelectionRevision })。这两个操作都不会启动AI任务。
本地透明导出使用ProRes 4444。静音茎意味着静音输出;它 不承诺删除音频流。本地出口开始没有付费渲染 或重新调整工作,并保留现有的功能资格。行期待 layout-dependent;它不是固定的每行显示保证。
这些方法要求在实例之前部署匹配的服务器端点 发布SDK新版本。参见存储库的capability-parity指南 推出和验收需求。