veza/apps/web/src/features/player/components/WaveformDisplay.stories.tsx
senke 73533bea77 feat(v0.501): Sprint 2 -- HLS production-ready
- S1-01: Add multi-bitrate streaming profiles (128k, 256k, 320k)
- S1-02: Update master.m3u8 endpoint with 3-tier quality system
- S1-03: Integrate hls.js with ABR + useHLSPlayer hook
- S1-04: Add Cache-Control headers on HLS segments and manifests
- S1-05: Create WaveformService with async generation (FFmpeg + audiowaveform)
- S1-06: Add GET /tracks/:id/waveform endpoint with Redis cache
- S1-07: Create WaveformDisplay component with story
- S1-08: Add 4 Prometheus metrics for streaming monitoring
2026-02-22 18:16:37 +01:00

109 lines
2.2 KiB
TypeScript

import type { Meta, StoryObj } from '@storybook/react';
import { WaveformDisplay } from './WaveformDisplay';
import { http, HttpResponse } from 'msw';
const mockWaveformData = {
version: 2,
channels: 1,
sample_rate: 800,
samples_per_pixel: 1,
bits: 32,
length: 200,
data: Array.from({ length: 200 }, (_, i) =>
Math.sin(i * 0.1) * 0.5 + Math.sin(i * 0.05) * 0.3 + Math.random() * 0.2
),
};
const meta: Meta<typeof WaveformDisplay> = {
title: 'Player/WaveformDisplay',
component: WaveformDisplay,
parameters: {
layout: 'padded',
msw: {
handlers: [
http.get('*/tracks/:trackId/waveform', () => {
return HttpResponse.json(mockWaveformData);
}),
],
},
},
decorators: [
(Story) => (
<div className="w-full max-w-2xl bg-background p-4 rounded-lg">
<Story />
</div>
),
],
};
export default meta;
type Story = StoryObj<typeof WaveformDisplay>;
export const Default: Story = {
args: {
trackId: 'mock-track-1',
currentTime: 0,
duration: 180,
},
};
export const WithProgress: Story = {
args: {
trackId: 'mock-track-1',
currentTime: 90,
duration: 180,
},
};
export const Seekable: Story = {
args: {
trackId: 'mock-track-1',
currentTime: 45,
duration: 180,
onSeek: (time: number) => console.log('Seek to', time),
},
};
export const Loading: Story = {
args: {
trackId: 'loading-track',
currentTime: 0,
duration: 180,
},
parameters: {
msw: {
handlers: [
http.get('*/tracks/:trackId/waveform', async () => {
await new Promise((resolve) => setTimeout(resolve, 999999));
return HttpResponse.json(mockWaveformData);
}),
],
},
},
};
export const Error: Story = {
args: {
trackId: 'error-track',
currentTime: 60,
duration: 180,
},
parameters: {
msw: {
handlers: [
http.get('*/tracks/:trackId/waveform', () => {
return new HttpResponse(null, { status: 404 });
}),
],
},
},
};
export const CustomHeight: Story = {
args: {
trackId: 'mock-track-1',
currentTime: 30,
duration: 120,
height: 80,
},
};