Skip to content

Commit

Permalink
docs: add best practice
Browse files Browse the repository at this point in the history
  • Loading branch information
OrbisK committed Dec 2, 2024
1 parent 4ed3022 commit 360f7d2
Show file tree
Hide file tree
Showing 4 changed files with 1,079 additions and 37 deletions.
11 changes: 9 additions & 2 deletions docs/.vitepress/config.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
import { resolve } from 'node:path'
import { defineConfig } from 'vitepress'
import { withMermaid } from "vitepress-plugin-mermaid";

Check failure on line 3 in docs/.vitepress/config.ts

View workflow job for this annotation

GitHub Actions / test

Strings must use singlequote

Check failure on line 3 in docs/.vitepress/config.ts

View workflow job for this annotation

GitHub Actions / test

Extra semicolon

// https://vitepress.dev/reference/site-config
export default defineConfig({
export default withMermaid(defineConfig({
title: 'Vue Use Media Recorder',
mermaid:{

Check failure on line 8 in docs/.vitepress/config.ts

View workflow job for this annotation

GitHub Actions / test

Missing space before value for key 'mermaid'
},
description: 'A Vue Composable for MediaRecorder API',
base: '/vue-use-media-recorder/',
vite: {
Expand Down Expand Up @@ -37,6 +40,10 @@ export default defineConfig({
text: 'Components',
link: '/components',
},
{
text: 'Best Practice',
link: '/best-practice',
},
{
text: 'Examples',
link: '/examples',
Expand All @@ -47,4 +54,4 @@ export default defineConfig({
{ icon: 'github', link: 'https://github.com/OrbisK/vue-use-media-recorder' },
],
},
})
}))
146 changes: 146 additions & 0 deletions docs/best-practice.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
---
outline: deep
---

# Best Practice

## Lifecycle

The `useMediaRecorder` composable is a wrapper around the `MediaRecorder` API. It provides a simple interface to start,
pause, resume, and stop recording. The composable is designed to be as close as possible to the native API.

Although `stop()`, `pause()` and `resume()` are synchronous operations, they just trigger some delayed events. The
actual lifecycle of the `MediaRecorder` is "asynchronous".

:::info
You should always wait for the actual event to be triggered before you access the data.
:::

### `start()` without timeslice and `stop()`

If you don't pass a `timeslice` to `start()`, the `MediaRecorder` will record the stream until you call `stop()`.
This does mean that you need to wait for the `onStop` callback to be called before you can access the recorded data.

```ts
const { start, stop } = useMediaRecorder({
onStart: () => console.log('started'),
onStop: () => console.log('stopped')
})

await start()
stop()
```

```mermaid
stateDiagram-v2
[*] --> initial
initial --> starting: start()
starting --> recording: onStart
recording --> ondataavailable: stop()
ondataavailable --> inactive: onStop
inactive --> starting: start()
inactive --> [*]
note right of initial
state: undefined
end note
note right of starting
set data to []
set stream to MediaStream
start MediaRecorder
end note
note right of recording
state: recording
set mime Type
end note
note right of ondataavailable
write recorded chunk to data
end note
note right of inactive
state: inactive
stop all stream tracks
end note
```

### `start()` with timeslice and `stop()`

If you pass a `timeslice` to `start()`, the `MediaRecorder` will record the stream and write the recorded data to the
`data` array every `timeslice` milliseconds. After you call `stop()`, it will call one last `ondataavailable` event and
then call `onStop`. This means you should wait for the `onStop` callback to be called before you can access **all** the
recorded

```ts
const { start, stop } = useMediaRecorder({
onStart: () => console.log('started'),
onStop: () => console.log('stopped')
})

await start(10)
stop()
```

```mermaid
stateDiagram-v2
state "ondataavailable" as ondataavailable2
[*] --> initial
initial --> starting: start()
starting --> recording: onStart
recording --> ondataavailable: timeslice passed
ondataavailable --> recording
recording --> ondataavailable2: stop()
ondataavailable2 --> inactive: onStop
inactive --> starting: start()
inactive --> [*]
note right of initial
state: undefined
end note
note right of starting
set data to []
set stream to MediaStream
start MediaRecorder
end note
note right of recording
state: recording
set mime Type
end note
note right of ondataavailable
write recorded chunk to data
end note
note right of ondataavailable2
write recorded chunk to data
end note
note right of inactive
state: inactive
stop all stream tracks
end note
```

## Limitations

### Reactive `constraints` and `mediaRecorderOptions`

The `constraints` and `mediaRecorderOptions` accept reactive values. **However**, changing these values will not
automatically update the `MediaRecorder`. You need to call `stop()` and `start()` again to apply the new values.

### `mimeType` and `isMimeTypeSupported`

The `mimeType` is set when the `MediaRecorder` is initialized and the stream is available (start has to be called once).

If you set the `mimeType` manually, make sure that the `mimeType` is supported by the browser. You can
check if the `mimeType` is supported via `isMimeTypeSupported`.

```ts
const { mimeType, isMimeTypeSupported } = useMediaRecorder({
mediaRecorderOptions: {
mimeType: 'video/webm;codecs=vp9'
}
})

console.log(mimeType.value, isMimeTypeSupported.value)
```

::: warning
`isMimeTypeSupported` will check your `mediaRecorderOptions.mimeType` and not the actual `mimeType` of the
`MediaRecorder`. **But** `mimeType` will be set to the actual `mimeType` of the `MediaRecorder`.

So it's possible to have `isMimeTypeSupported.value === true` and `mimeType.value === undefined`.
:::

Check failure on line 146 in docs/best-practice.md

View workflow job for this annotation

GitHub Actions / test

Newline required at end of file but not found
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -82,11 +82,13 @@
"globby": "^14.0.2",
"happy-dom": "^15.11.3",
"lint-staged": "^15.2.10",
"mermaid": "^11.4.1",
"nuxt": "^3.14.1592",
"playwright": "^1.49.0",
"typescript": "^5.6.3",
"unbuild": "^2.0.0",
"vitepress": "^1.5.0",
"vitepress-plugin-mermaid": "^2.0.17",
"vitest": "^2.1.5",
"vitest-browser-vue": "^0.0.1"
},
Expand Down
Loading

0 comments on commit 360f7d2

Please sign in to comment.