Skip to content

Commit 360f7d2

Browse files
committed
docs: add best practice
1 parent 4ed3022 commit 360f7d2

File tree

4 files changed

+1079
-37
lines changed

4 files changed

+1079
-37
lines changed

docs/.vitepress/config.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
11
import { resolve } from 'node:path'
22
import { defineConfig } from 'vitepress'
3+
import { withMermaid } from "vitepress-plugin-mermaid";
34

45
// https://vitepress.dev/reference/site-config
5-
export default defineConfig({
6+
export default withMermaid(defineConfig({
67
title: 'Vue Use Media Recorder',
8+
mermaid:{
9+
},
710
description: 'A Vue Composable for MediaRecorder API',
811
base: '/vue-use-media-recorder/',
912
vite: {
@@ -37,6 +40,10 @@ export default defineConfig({
3740
text: 'Components',
3841
link: '/components',
3942
},
43+
{
44+
text: 'Best Practice',
45+
link: '/best-practice',
46+
},
4047
{
4148
text: 'Examples',
4249
link: '/examples',
@@ -47,4 +54,4 @@ export default defineConfig({
4754
{ icon: 'github', link: 'https://github.com/OrbisK/vue-use-media-recorder' },
4855
],
4956
},
50-
})
57+
}))

docs/best-practice.md

Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
---
2+
outline: deep
3+
---
4+
5+
# Best Practice
6+
7+
## Lifecycle
8+
9+
The `useMediaRecorder` composable is a wrapper around the `MediaRecorder` API. It provides a simple interface to start,
10+
pause, resume, and stop recording. The composable is designed to be as close as possible to the native API.
11+
12+
Although `stop()`, `pause()` and `resume()` are synchronous operations, they just trigger some delayed events. The
13+
actual lifecycle of the `MediaRecorder` is "asynchronous".
14+
15+
:::info
16+
You should always wait for the actual event to be triggered before you access the data.
17+
:::
18+
19+
### `start()` without timeslice and `stop()`
20+
21+
If you don't pass a `timeslice` to `start()`, the `MediaRecorder` will record the stream until you call `stop()`.
22+
This does mean that you need to wait for the `onStop` callback to be called before you can access the recorded data.
23+
24+
```ts
25+
const { start, stop } = useMediaRecorder({
26+
onStart: () => console.log('started'),
27+
onStop: () => console.log('stopped')
28+
})
29+
30+
await start()
31+
stop()
32+
```
33+
34+
```mermaid
35+
stateDiagram-v2
36+
[*] --> initial
37+
initial --> starting: start()
38+
starting --> recording: onStart
39+
recording --> ondataavailable: stop()
40+
ondataavailable --> inactive: onStop
41+
inactive --> starting: start()
42+
inactive --> [*]
43+
note right of initial
44+
state: undefined
45+
end note
46+
note right of starting
47+
set data to []
48+
set stream to MediaStream
49+
start MediaRecorder
50+
end note
51+
note right of recording
52+
state: recording
53+
set mime Type
54+
end note
55+
note right of ondataavailable
56+
write recorded chunk to data
57+
end note
58+
note right of inactive
59+
state: inactive
60+
stop all stream tracks
61+
end note
62+
```
63+
64+
### `start()` with timeslice and `stop()`
65+
66+
If you pass a `timeslice` to `start()`, the `MediaRecorder` will record the stream and write the recorded data to the
67+
`data` array every `timeslice` milliseconds. After you call `stop()`, it will call one last `ondataavailable` event and
68+
then call `onStop`. This means you should wait for the `onStop` callback to be called before you can access **all** the
69+
recorded
70+
71+
```ts
72+
const { start, stop } = useMediaRecorder({
73+
onStart: () => console.log('started'),
74+
onStop: () => console.log('stopped')
75+
})
76+
77+
await start(10)
78+
stop()
79+
```
80+
81+
```mermaid
82+
stateDiagram-v2
83+
state "ondataavailable" as ondataavailable2
84+
[*] --> initial
85+
initial --> starting: start()
86+
starting --> recording: onStart
87+
recording --> ondataavailable: timeslice passed
88+
ondataavailable --> recording
89+
recording --> ondataavailable2: stop()
90+
ondataavailable2 --> inactive: onStop
91+
inactive --> starting: start()
92+
inactive --> [*]
93+
note right of initial
94+
state: undefined
95+
end note
96+
note right of starting
97+
set data to []
98+
set stream to MediaStream
99+
start MediaRecorder
100+
end note
101+
note right of recording
102+
state: recording
103+
set mime Type
104+
end note
105+
note right of ondataavailable
106+
write recorded chunk to data
107+
end note
108+
note right of ondataavailable2
109+
write recorded chunk to data
110+
end note
111+
note right of inactive
112+
state: inactive
113+
stop all stream tracks
114+
end note
115+
```
116+
117+
## Limitations
118+
119+
### Reactive `constraints` and `mediaRecorderOptions`
120+
121+
The `constraints` and `mediaRecorderOptions` accept reactive values. **However**, changing these values will not
122+
automatically update the `MediaRecorder`. You need to call `stop()` and `start()` again to apply the new values.
123+
124+
### `mimeType` and `isMimeTypeSupported`
125+
126+
The `mimeType` is set when the `MediaRecorder` is initialized and the stream is available (start has to be called once).
127+
128+
If you set the `mimeType` manually, make sure that the `mimeType` is supported by the browser. You can
129+
check if the `mimeType` is supported via `isMimeTypeSupported`.
130+
131+
```ts
132+
const { mimeType, isMimeTypeSupported } = useMediaRecorder({
133+
mediaRecorderOptions: {
134+
mimeType: 'video/webm;codecs=vp9'
135+
}
136+
})
137+
138+
console.log(mimeType.value, isMimeTypeSupported.value)
139+
```
140+
141+
::: warning
142+
`isMimeTypeSupported` will check your `mediaRecorderOptions.mimeType` and not the actual `mimeType` of the
143+
`MediaRecorder`. **But** `mimeType` will be set to the actual `mimeType` of the `MediaRecorder`.
144+
145+
So it's possible to have `isMimeTypeSupported.value === true` and `mimeType.value === undefined`.
146+
:::

package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,11 +82,13 @@
8282
"globby": "^14.0.2",
8383
"happy-dom": "^15.11.3",
8484
"lint-staged": "^15.2.10",
85+
"mermaid": "^11.4.1",
8586
"nuxt": "^3.14.1592",
8687
"playwright": "^1.49.0",
8788
"typescript": "^5.6.3",
8889
"unbuild": "^2.0.0",
8990
"vitepress": "^1.5.0",
91+
"vitepress-plugin-mermaid": "^2.0.17",
9092
"vitest": "^2.1.5",
9193
"vitest-browser-vue": "^0.0.1"
9294
},

0 commit comments

Comments
 (0)