@meersagor/wavesurfer-vue 1.0.0 → 2.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -3,17 +3,20 @@
3
3
  [![npm](https://img.shields.io/npm/v/@meersagor/wavesurfer-vue)](https://www.npmjs.com/package/@meersagor/wavesurfer-vue)
4
4
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
5
5
 
6
-
7
-
8
6
  ## Audio Player
9
7
 
10
8
  ![audio player preview](./src/assets/preview.png)
11
9
 
10
+ A Vue 3 component for [wavesurfer.js](http://github.com/katspaugh/wavesurfer.js). This package provides a maintainable, modular architecture with core functionality and individual plugins for WaveSurfer.js.
12
11
 
13
- A Vue 3 component for [wavesurfer.js](http://github.com/katspaugh/wavesurfer.js). This component simplifies the usage of wavesurfer.js in Vue.js, with all familiar wavesurfer options available as Vue props.
14
-
15
- You can subscribe to various [wavesurfer events](https://wavesurfer.xyz/docs/types/wavesurfer.WaveSurferEvents) via props. Simply prepend an event name with 'on', e.g., `ready` -> `@ready`. Each event receives a wavesurfer instance as the first argument.
12
+ ## Features
16
13
 
14
+ - **🎯 Modular Architecture**: Core functionality separated from plugins
15
+ - **🧩 Individual Plugins**: Import only the plugins you need
16
+ - **🔄 Multiple Usage Patterns**: Core + plugins, standalone plugins, or core only
17
+ - **📦 Tree-shaking Friendly**: Smaller bundle sizes
18
+ - **🔧 TypeScript Support**: Full type safety
19
+ - **⚡ Vue 3 Composition API**: Modern Vue 3 patterns
17
20
 
18
21
  ## Installation
19
22
 
@@ -27,9 +30,187 @@ With npm:
27
30
  npm i @meersagor/wavesurfer-vue
28
31
  ```
29
32
 
30
- ## Usage
33
+ ## 🚀 Usage Patterns
34
+
35
+ ### Pattern 1: Core + Individual Plugins (Recommended)
36
+
37
+ ```vue
38
+ <script setup lang="ts">
39
+ import { ref } from 'vue'
40
+ import {
41
+ useWaveSurfer,
42
+ useWaveSurferTimeline,
43
+ useWaveSurferZoom,
44
+ useWaveSurferMinimap
45
+ } from '@meersagor/wavesurfer-vue'
46
+
47
+ const containerRef = ref<HTMLElement | null>(null)
48
+ const timelineContainerRef = ref<HTMLElement | null>(null)
49
+ const minimapContainerRef = ref<HTMLElement | null>(null)
50
+
51
+ const options = ref({
52
+ height: 100,
53
+ waveColor: '#4F4A85',
54
+ progressColor: '#383351',
55
+ barGap: 2,
56
+ barWidth: 3,
57
+ barRadius: 3,
58
+ url: 'https://wavesurfer-js.org/example/media/demo.wav'
59
+ })
60
+
61
+ // Core functionality
62
+ const { waveSurfer, isReady, totalDuration, isPlaying, currentTime } = useWaveSurfer({
63
+ containerRef,
64
+ options: options.value
65
+ })
66
+
67
+ // Individual plugins
68
+ const { timelinePlugin } = useWaveSurferTimeline({
69
+ waveSurfer,
70
+ timelineOptions: {
71
+ container: timelineContainerRef
72
+ }
73
+ })
74
+
75
+ const { zoomPlugin, zoomIn, zoomOut } = useWaveSurferZoom({
76
+ waveSurfer,
77
+ zoomOptions: {
78
+ minPxPerSec: 50,
79
+ scrollParent: true
80
+ }
81
+ })
82
+
83
+ const { minimapPlugin } = useWaveSurferMinimap({
84
+ waveSurfer,
85
+ minimapOptions: {
86
+ container: minimapContainerRef,
87
+ height: 50
88
+ }
89
+ })
90
+ </script>
91
+
92
+ <template>
93
+ <div>
94
+ <!-- Main waveform -->
95
+ <div ref="containerRef"></div>
96
+
97
+ <!-- Timeline -->
98
+ <div ref="timelineContainerRef"></div>
99
+
100
+ <!-- Minimap -->
101
+ <div ref="minimapContainerRef"></div>
102
+
103
+ <!-- Controls -->
104
+ <div class="controls">
105
+ <button @click="waveSurfer?.playPause()">
106
+ {{ isPlaying ? 'Pause' : 'Play' }}
107
+ </button>
108
+ <button @click="zoomIn">Zoom In</button>
109
+ <button @click="zoomOut">Zoom Out</button>
110
+ </div>
111
+
112
+ <div class="info">
113
+ <p>Current Time: {{ formatTime(currentTime) }}</p>
114
+ <p>Duration: {{ formatTime(totalDuration) }}</p>
115
+ </div>
116
+ </div>
117
+ </template>
118
+ ```
119
+
120
+ ### Pattern 2: Standalone Plugins
121
+
122
+ ```vue
123
+ <script setup lang="ts">
124
+ import { ref } from 'vue'
125
+ import {
126
+ useWaveSurferTimelineStandalone,
127
+ useWaveSurferZoomStandalone
128
+ } from '@meersagor/wavesurfer-vue'
129
+
130
+ const containerRef = ref<HTMLElement | null>(null)
131
+ const timelineContainerRef = ref<HTMLElement | null>(null)
132
+
133
+ const options = ref({
134
+ height: 80,
135
+ waveColor: '#FF6B6B',
136
+ progressColor: '#4ECDC4',
137
+ barGap: 1,
138
+ barWidth: 2,
139
+ barRadius: 2,
140
+ url: 'https://wavesurfer-js.org/example/media/demo.wav'
141
+ })
142
+
143
+ // Standalone timeline plugin (creates its own WaveSurfer instance)
144
+ const { waveSurfer, timelinePlugin } = useWaveSurferTimelineStandalone({
145
+ containerRef,
146
+ options: options.value,
147
+ timelineOptions: {
148
+ container: timelineContainerRef
149
+ }
150
+ })
151
+
152
+ // Standalone zoom plugin (creates its own WaveSurfer instance)
153
+ const { waveSurfer: waveSurfer2, zoomPlugin, zoomIn, zoomOut } = useWaveSurferZoomStandalone({
154
+ containerRef,
155
+ options: options.value,
156
+ zoomOptions: {
157
+ minPxPerSec: 30,
158
+ scrollParent: true
159
+ }
160
+ })
161
+ </script>
162
+
163
+ <template>
164
+ <div>
165
+ <div ref="containerRef"></div>
166
+ <div ref="timelineContainerRef"></div>
167
+
168
+ <div class="controls">
169
+ <button @click="waveSurfer?.playPause()">Play/Pause</button>
170
+ <button @click="zoomIn">Zoom In</button>
171
+ <button @click="zoomOut">Zoom Out</button>
172
+ </div>
173
+ </div>
174
+ </template>
175
+ ```
176
+
177
+ ### Pattern 3: Core Functionality Only
178
+
179
+ ```vue
180
+ <script setup lang="ts">
181
+ import { ref } from 'vue'
182
+ import { useWaveSurfer } from '@meersagor/wavesurfer-vue'
183
+
184
+ const containerRef = ref<HTMLElement | null>(null)
31
185
 
32
- As a component:
186
+ const options = ref({
187
+ height: 60,
188
+ waveColor: '#95E1D3',
189
+ progressColor: '#F38181',
190
+ barGap: 3,
191
+ barWidth: 4,
192
+ barRadius: 4,
193
+ url: 'https://wavesurfer-js.org/example/media/demo.wav'
194
+ })
195
+
196
+ // Using core functionality - returns waveSurfer instance and all state
197
+ const { waveSurfer, isReady, totalDuration, isPlaying, currentTime } = useWaveSurfer({
198
+ containerRef,
199
+ options: options.value
200
+ })
201
+ </script>
202
+
203
+ <template>
204
+ <div>
205
+ <div ref="containerRef"></div>
206
+ <button @click="waveSurfer?.playPause()">
207
+ {{ isPlaying ? 'Pause' : 'Play' }}
208
+ </button>
209
+ </div>
210
+ </template>
211
+ ```
212
+
213
+ ### Pattern 4: Component Usage (Legacy)
33
214
 
34
215
  ```vue
35
216
  <script setup lang="ts">
@@ -37,7 +218,6 @@ import { ref } from 'vue'
37
218
  import type WaveSurfer from 'wavesurfer.js'
38
219
  import { WaveSurferPlayer } from '@meersagor/wavesurfer-vue'
39
220
 
40
-
41
221
  const options = ref({
42
222
  height: 48,
43
223
  waveColor: 'gray',
@@ -80,54 +260,54 @@ const readyWaveSurferHandler = (ws: WaveSurfer) => {
80
260
  </template>
81
261
  ```
82
262
 
83
- Alternatively, as a vue composable method:
263
+ ## 🧩 Available Plugins
84
264
 
85
- ```vue
86
- <script setup lang="ts">
87
- import { ref } from 'vue'
88
- import {useWaveSurfer} from '@meersagor/wavesurfer-vue'
89
- const containerRef = ref<HTMLElement | null>(null)
90
- const options = ref({
91
- height: 48,
92
- waveColor: 'gray',
93
- progressColor: 'red',
94
- barGap: 5,
95
- barWidth: 5,
96
- barRadius: 8,
97
- duration: 80,
98
- url: "https://revews-bucket.s3.ap-southeast-1.amazonaws.com/a06mmMU3sgnzuUkH4OiHvyuUgCFdLSnJaDLBao7y.webm",
99
- })
265
+ ### Core Plugins
266
+ - **Timeline** - Adds a timeline display
267
+ - **Zoom** - Provides zoom functionality with methods
268
+ - **Minimap** - Shows a minimap overview
269
+ - **Hover** - Adds hover effects
270
+ - **Envelope** - Audio envelope visualization
271
+ - **Spectrogram** - Frequency spectrum visualization
272
+ - **Regions** - Audio region management
273
+ - **Recorder** - Audio recording functionality
100
274
 
101
- const {waveSurfer, currentTime, totalDuration} = useWaveSurfer({containerRef, options: options.value})
275
+ ### Plugin Usage
102
276
 
103
- const formatTime = (seconds: number):string => [seconds / 60, seconds % 60].map((v) => `0${Math.floor(v)}`.slice(-2)).join(':')
104
- </script>
277
+ Each plugin has two versions:
105
278
 
106
- <template>
107
- <main>
108
- <h1>WaveSurferPlayer Using Composeable Method </h1>
109
- <div ref="containerRef"></div>
110
- <p>currentTime: {{formatTime(currentTime)}}</p>
111
- <p>totalDuration:{{formatTime(totalDuration)}}</p>
112
- <button @click="waveSurfer?.playPause()">
113
- Play
114
- </button>
115
- </main>
116
- </template>
279
+ #### With Existing WaveSurfer Instance
280
+ ```typescript
281
+ import { useWaveSurferTimeline } from '@meersagor/wavesurfer-vue'
282
+
283
+ const { timelinePlugin } = useWaveSurferTimeline({
284
+ waveSurfer, // Existing WaveSurfer instance
285
+ timelineOptions: { container: timelineContainer }
286
+ })
117
287
  ```
118
288
 
119
- ## Audio Recorder
289
+ #### Standalone (Creates Own Instance)
290
+ ```typescript
291
+ import { useWaveSurferTimelineStandalone } from '@meersagor/wavesurfer-vue'
120
292
 
121
- ![audio player preview](./src/assets/recorder.png)
293
+ const { waveSurfer, timelinePlugin } = useWaveSurferTimelineStandalone({
294
+ containerRef, // Container reference
295
+ options, // WaveSurfer options
296
+ timelineOptions: { container: timelineContainer }
297
+ })
298
+ ```
122
299
 
300
+ ## 🎙️ Audio Recorder
123
301
 
302
+ ![audio recorder preview](./src/assets/recorder.png)
124
303
 
125
- ## use useWaveSurferRecorder composable method
304
+ ### useWaveSurferRecorder
126
305
 
127
306
  ```vue
128
307
  <script lang="ts" setup>
129
308
  import { computed, ref } from 'vue'
130
309
  import { useWaveSurferRecorder } from '@meersagor/wavesurfer-vue'
310
+
131
311
  const showAudioRecordButton = ref<boolean>(true)
132
312
  const containerRef = ref<HTMLDivElement | null>(null)
133
313
 
@@ -145,9 +325,9 @@ const options = computed(() => ({
145
325
  const { pauseRecording, startRecording, stopRecording, currentTime, isPauseResume } = useWaveSurferRecorder({
146
326
  containerRef,
147
327
  options: options.value,
148
- recordPluginOptions:{
328
+ recordPluginOptions:{
149
329
  continuousWaveform: true
150
- }
330
+ }
151
331
  })
152
332
 
153
333
  const startAudioRecordHandler = () => {
@@ -176,52 +356,45 @@ const stopHandler = async () => {
176
356
  </div>
177
357
  </template>
178
358
  ```
179
- ## useWaveSurferRecorder: method Return Types
180
- ### `waveSurfer`
181
-
182
- - Type: `Ref<WaveSurfer | null>`
183
- - Description: A ref containing the instance of the `wavesurfer.js` player.
184
-
185
- ### `waveSurferRecorder`
186
-
187
- - Type: `Ref<RecordPlugin | null>`
188
- - Description: A ref containing the instance of the `wavesurfer.js` record plugin.
189
-
190
- ### `currentTime`
191
-
192
- - Type: `ComputedRef<string>`
193
- - Description: A computed ref representing the current recording time in `mm:ss` format.
194
-
195
- ### `isPaused`
196
-
197
- - Type: `ComputedRef<boolean | undefined>`
198
- - Description: A computed ref indicating whether the recording is currently paused.
199
-
200
- ### `isRecording`
201
-
202
- - Type: `ComputedRef<boolean | undefined>`
203
- - Description: A computed ref indicating whether the recording is currently in progress.
204
359
 
205
- ### `startRecording()`
360
+ ### useWaveSurferRecorder Return Types
206
361
 
207
- - Type: `() => void`
208
- - Description: Method to start or resume the recording process. If recording is already in progress, it stops and starts a new recording.
362
+ | Property | Type | Description |
363
+ |----------|------|-------------|
364
+ | `waveSurfer` | `Ref<WaveSurfer \| null>` | WaveSurfer instance |
365
+ | `waveSurferRecorder` | `Ref<RecordPlugin \| null>` | Record plugin instance |
366
+ | `currentTime` | `ComputedRef<string>` | Current recording time in `mm:ss` format |
367
+ | `isPaused` | `ComputedRef<boolean \| undefined>` | Whether recording is paused |
368
+ | `isRecording` | `ComputedRef<boolean \| undefined>` | Whether recording is in progress |
369
+ | `startRecording()` | `() => void` | Start or resume recording |
370
+ | `stopRecording()` | `() => Promise<Blob>` | Stop recording and return blob |
371
+ | `pauseRecording()` | `() => void` | Pause/resume recording |
209
372
 
210
- ### `stopRecording()`
373
+ ## 🏗️ Architecture
211
374
 
212
- - Type: `() => Promise<Blob>`
213
- - Description: Method to stop the recording process and return the recorded audio as a `Blob` object.
375
+ ### Core Functionality
376
+ - **`useWaveSurferInstance`** - WaveSurfer instance management (internal)
377
+ - **`useWaveSurferState`** - State management (internal, used by `useWaveSurfer`)
378
+ - **`useWaveSurfer`** - Main composable combining instance + state (recommended for users)
379
+ - **`useWaveSurferPlugin`** - Base functionality for all plugins (internal)
214
380
 
215
- ### `pauseRecording()`
381
+ ### Plugin System
382
+ - **Individual plugins** - Import only what you need
383
+ - **Standalone versions** - Create own WaveSurfer instances
384
+ - **Tree-shaking friendly** - Smaller bundle sizes
385
+ - **Type-safe** - Full TypeScript support
216
386
 
217
- - Type: `() => void`
218
- - Description: Method to resume a paused recording. If recording is not paused, it toggles between pause and resume.
387
+ ## 📚 Documentation
219
388
 
389
+ - [WaveSurfer.js Documentation](https://wavesurfer.xyz)
390
+ - [Plugin Examples](./examples/)
391
+ - [Architecture Guide](./NEW_ARCHITECTURE.md)
220
392
 
393
+ ## 🤝 Contributing
221
394
 
222
- ## Docs
395
+ If you have any specific preferences or additional changes you'd like, feel free to submit a PR!
223
396
 
224
- https://wavesurfer.xyz
397
+ ## 📄 License
225
398
 
226
- If you have any specific preferences or additional changes you'd like, feel free to PR
399
+ MIT License - see [LICENSE](./LICENSE) for details.
227
400