feat(call): add streaming voice call experience
This commit is contained in:
@@ -0,0 +1,57 @@
|
||||
import { afterEach, describe, expect, it, vi } from "vitest";
|
||||
|
||||
import { VoiceCallPlayer } from "@/app/call/voice-call-player";
|
||||
|
||||
describe("VoiceCallPlayer", () => {
|
||||
afterEach(() => {
|
||||
vi.unstubAllGlobals();
|
||||
});
|
||||
|
||||
it("schedules decoded sentence audio on one continuous Web Audio timeline", async () => {
|
||||
const starts: number[] = [];
|
||||
const sources: Array<{ onended: (() => void) | null }> = [];
|
||||
const context = {
|
||||
state: "running",
|
||||
currentTime: 0,
|
||||
destination: {},
|
||||
resume: vi.fn(async () => undefined),
|
||||
close: vi.fn(async () => undefined),
|
||||
decodeAudioData: vi.fn(async () => ({ duration: 1 })),
|
||||
createBufferSource: vi.fn(() => {
|
||||
const source = {
|
||||
buffer: null,
|
||||
onended: null as (() => void) | null,
|
||||
connect: vi.fn(),
|
||||
disconnect: vi.fn(),
|
||||
stop: vi.fn(),
|
||||
start: vi.fn((at: number) => starts.push(at)),
|
||||
};
|
||||
sources.push(source);
|
||||
return source;
|
||||
}),
|
||||
};
|
||||
vi.stubGlobal("AudioContext", function AudioContextMock() {
|
||||
return context;
|
||||
});
|
||||
|
||||
const player = new VoiceCallPlayer();
|
||||
const gaps: number[] = [];
|
||||
player.onGap = (milliseconds) => gaps.push(milliseconds);
|
||||
const meta = {
|
||||
callId: "call-1",
|
||||
turnId: "turn-1",
|
||||
index: 0,
|
||||
mimeType: "audio/mpeg",
|
||||
byteLength: 3,
|
||||
};
|
||||
|
||||
player.enqueue(meta, new Uint8Array([1, 2, 3]).buffer);
|
||||
player.enqueue({ ...meta, index: 1 }, new Uint8Array([4, 5, 6]).buffer);
|
||||
|
||||
await vi.waitFor(() => expect(starts).toHaveLength(2));
|
||||
expect(starts).toEqual([0.025, 1.025]);
|
||||
expect(gaps).toEqual([0]);
|
||||
expect(sources).toHaveLength(2);
|
||||
player.dispose();
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user