Files
Toju/docs-site/docs/plugin-development/api/p2p-and-media.md
Myx 0a714428f6 docs: improve doucmentation
improve doucmentation and fix small store changes
2026-04-30 01:16:48 +02:00

128 lines
2.9 KiB
Markdown

---
sidebar_position: 9
---
# P2P and Media API
P2P APIs send plugin data to connected peers. Media APIs play audio and contribute custom streams.
## Required Capabilities
| Method | Capability |
| --- | --- |
| `p2p.connectedPeers()` | `p2p.data` |
| `p2p.broadcastData(eventName, payload)` | `p2p.data` |
| `p2p.sendData(peerId, eventName, payload)` | `p2p.data` |
| `media.playAudioClip(request)` | `media.playAudio` |
| `media.addCustomAudioStream(request)` | `media.addAudioStream` |
| `media.addCustomVideoStream(request)` | `media.addVideoStream` |
| `media.setInputVolume(volume)` | `audio.volume` |
| `media.setOutputVolume(volume)` | `audio.volume` |
## Connected Peers
```js
export function activate(context) {
const peerIds = context.api.p2p.connectedPeers();
context.api.logger.info('Connected peers', { peerIds });
}
```
## Broadcast Data
```js
export function activate(context) {
context.api.p2p.broadcastData('soundboard:played', {
soundId: 'airhorn-short',
label: 'Airhorn',
playedBy: 'Alice',
playedAt: 1777473600000
});
}
```
## Send Data to One Peer
```js
export function activate(context) {
context.api.p2p.sendData('peer-muse-laptop', 'private-tool:ping', {
requestId: 'ping-20260429-001',
message: 'Are you receiving plugin data?'
});
}
```
## Play an Audio Clip
```js
export async function activate(context) {
await context.api.media.playAudioClip({
url: 'https://cdn.example.com/metoyou/sounds/chime.wav',
volume: 0.65
});
}
```
## Add a Custom Audio Stream
```js
export async function activate(context) {
const audioContext = new AudioContext();
const oscillator = audioContext.createOscillator();
const gain = audioContext.createGain();
const destination = audioContext.createMediaStreamDestination();
oscillator.type = 'sine';
oscillator.frequency.value = 440;
gain.gain.value = 0.03;
oscillator.connect(gain);
gain.connect(destination);
oscillator.start();
await context.api.media.addCustomAudioStream({
label: 'Tuning tone',
stream: destination.stream
});
setTimeout(async () => {
oscillator.stop();
await audioContext.close();
}, 1000);
}
```
## Add a Custom Video Stream
```js
export async function activate(context) {
const canvas = document.createElement('canvas');
canvas.width = 1280;
canvas.height = 720;
const ctx = canvas.getContext('2d');
ctx.fillStyle = '#111827';
ctx.fillRect(0, 0, canvas.width, canvas.height);
ctx.fillStyle = '#ffffff';
ctx.font = '48px sans-serif';
ctx.fillText('Plugin camera scene', 80, 120);
const stream = canvas.captureStream(15);
await context.api.media.addCustomVideoStream({
label: 'Plugin camera scene',
stream
});
}
```
## Set Volumes
```js
export function activate(context) {
context.api.media.setInputVolume(0.85);
context.api.media.setOutputVolume(0.75);
}
```
Use media APIs with visible controls and clear user consent. Unexpected audio or video is a poor user experience.