> For the complete documentation index, see [llms.txt](https://docs.theopenpresenter.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.theopenpresenter.com/plugins/developing-a-plugin/audio.md).

# Audio

### Playing Audio

Browsers have a limitation where you can't play audio until the user interacts with the tab. An attempt to play audio anyway will result in an error thrown.

To work with this limitation, we provide a React hook that will tell you whether the renderer can play audio or not. If playing video, you could use this flag to indicate when to unmute the video.

Example usage:

```typescript
const canPlay = pluginApi.audio.useCanPlay({ skipCheck: !isPlaying });
```

Calling this function by default will:

1. Periodically check the renderer for a status change
2. Show a warning to the user that audio is blocked

We recommend passing a **skipCheck** property that will only start performing these side effects when the value is false. See the example usage above for clarity.

### Audio Volume

If making a volume fader, please keep in mind that by default, HTML audio scales linearly. This is not ideal since human perception of loudness is not linear.

See more: <https://www.dr-lex.be/info-stuff/volumecontrols.html>

Example library to use: <https://github.com/discord/perceptual>

### Showing to user that Audio is playing

If your plugin plays audio, you'll want to indicate that to the user to reduce confusion.

For example, we display an icon next to the scene so that the user knows where the audio comes from. Browser tabs use the same UI to notify this to the user.

Here's how it looks like in our platform:

<div align="left"><figure><img src="/files/bXfeMmFI8g7d2WSQXeeY" alt=""><figcaption></figcaption></figure></div>

To set this state, you need to set the `__audioIsPlaying` property in your renderer data to either true or false. See the Typescript type **PluginRendererState** for all possible states.&#x20;

{% embed url="<https://github.com/Vija02/TheOpenPresenter/blob/main/packages/base-plugin/src/types.ts>" %}

**Example**

```typescript
const onRendererDataLoaded: RegisterOnRendererDataLoaded<PluginRendererData> = (
  rendererData,
) => {
  const yjsWatcher = new YjsWatcher(rendererData as Y.Map<any>);
  yjsWatcher.watchYjs(
    (x: PluginRendererData) => x.isPlaying,
    () => {
      // Watch the isPlaying property and sync it to __audioIsPlaying
      rendererData.set("__audioIsPlaying", rendererData.get("isPlaying"));
    },
  );

  return {
    dispose: () => {
      yjsWatcher.dispose();
    },
  };
};
```

More info about this here: [Renderer](/plugins/developing-a-plugin/plugin-api/yjs/renderer.md)

### Showing to user that Audio is being recorded

Similarly to above, you can show to the user that audio is currently being recorded by setting the `__audioIsRecording` variable.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.theopenpresenter.com/plugins/developing-a-plugin/audio.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
