kipphi-player
v2.1.2
Published
A Phigros Chart Player, designed with the philosophy of stateless-rendering. Very friendly for editors since it's high-performance.
Downloads
445
Readme
Kipphi Player - An editor-friendly Phigros Chart Player
奇谱播放器为奇谱发生器的子项目,用于在编辑器中播放Phigros谱面(RPE或KPA格式)。基于Kipphi。
Kipphi Player is a subproject of Kipphi, which is a Phigros chart player for editor. Based on Kipphi.
使用
最简单用例:
import { Player, AudioProcessor, Images, Respack } from "kipphi-player";
import { Chart } from "kipphi";
await Images.loadAndOptimize({
anchor: "Anchor.png", // 标识判定线锚点,若不需要可用全透明图片
below: "Below.png", // 标识一个Note为判定线下方,若不需要可用全透明图片
});
// 需自备Phira格式的资源包
const respack = Respack.loadFromPhira(async (filename) => {
// 自行实现获得资源包内文件的逻辑
// 最简单的方法是,直接把解压好的资源包放在一个文件夹内,然后在此函数中用fetch获得它们
return ...
})
// AudioProcessor,包装了AudioContext的对象。
// 仅打击音效用AudioContext控制,曲目播放仍然用<audio>标签播放
const audioProcessor = new AudioProcessor()
await audioProcessor.init({
tap: "Tap.wav",
drag: "Drag.wav",
flick: "Flick.wav"
});
// 如果资源包里已经有音效了,可以用这个方法直接创建
const audioProcessor = AudioProcessor.fromRespack(respack);
const name = "qualia";
const audio = new Audio(`charts/${name}/music.mp3`);
// Images.loadImage要load事件触发才会完成Promise,无需担心只加载一部分的问题
const background = await createImageBitmap(await Images.loadImage(`charts/${name}/illustration.jpg`));
const canvas = document.getElementById("canvas") as HTMLCanvasElement;
// 也可以渲染RPE谱面,自己选择
const chart = Chart.fromKPAJSON(await (await fetch(`charts/${name}/chart.json`)).json());
const player = new Player(canvas, audioProcessor, audio, background);
player.receive(chart, async (textureName) => {
// 自行实现纹理加载逻辑(在前端,需要的是Blob)
// 不需要纹理的话返回undefined或者null即可
return ...
})
document.onclick = () => {
player.play();
};
// 进度、音量等可自行控制
// 打击特效的音量
player.audioProcessor.volume = 2.0;
用于后端
得益于 skia-canvas,奇谱播放器也可用于Node.js或Bun等后端运行环境。
安装后端版本:npm install kpp-render 或 bun add kpp-render。(其实我还没上传这个包)
在拯救者Y7000P(i7 14650,GeForce 5060)上的测试,干跑物量1000左右谱面的渲染,速度平均能有1000多fps。渲染Sildild的Singularity谱面(物量84488),平均速度30多fps。峰值内存占用约2GiB。
但是以上是干跑渲染。如果使用ffmpeg(为了在单进程中尽量零拷贝,本项目使用了 node-av)收集并合成视频,则会受到编码及封装的速度限制。本人不太会玩视频合成,无法尽可能压榨 ffmpeg 性能,欢迎优化。
export async function renderChartFast(
chart: Chart,
illustrationBlobOrBuffer: Blob | Buffer,
textureFetcher: (name: string) => Promise<Buffer>,
audioBuffer: Buffer,
range?: [number, number]
): Promise<{
out: Buffer;
duration: number;
fps: number;
}>;