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

2.9 KiB

sidebar_position
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

export function activate(context) {
  const peerIds = context.api.p2p.connectedPeers();

  context.api.logger.info('Connected peers', { peerIds });
}

Broadcast Data

export function activate(context) {
  context.api.p2p.broadcastData('soundboard:played', {
    soundId: 'airhorn-short',
    label: 'Airhorn',
    playedBy: 'Alice',
    playedAt: 1777473600000
  });
}

Send Data to One Peer

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

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

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

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

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.