- 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
109 lines
2.2 KiB
TypeScript
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,
|
|
},
|
|
};
|