# useSystemAudio

> Capture system or tab audio through the browser's screen-share picker.

```npm
npx shadcn-svelte@latest add @audiocn-svelte/use-system-audio
```

## Usage

```svelte
<script lang="ts">
	import { Button } from "#lib/components/ui/button/index.js";
	import { useAudioAnalyser } from "#lib/hooks/use-audio-analyser.svelte.js";
	import { useSystemAudio } from "#lib/hooks/use-system-audio.svelte.js";

	const system = useSystemAudio();
	const analyser = useAudioAnalyser(() => system.stream, { channels: "stereo" });
</script>

<Button disabled={!system.isSupported} onclick={system.start}>Capture system audio</Button>
```

Call it during component setup. `stream`, `status` and `error` are getters, so read them from the returned object. Unmounting the component stops the capture, since starting it again needs a new user gesture.

The browser shows its screen-share picker. The user must choose a screen, window or tab and tick the option to share audio. The video track is dropped immediately; only audio is kept.

<Callout type="warning" title="Browser support varies">

What can be captured depends on the browser and operating system. Chromium browsers can share tab audio everywhere and whole-system audio on some platforms. Other browsers may offer no audio at all. Always handle the `no-audio` and `unsupported` states.

</Callout>

## Options

<PropsTable
	rows={[
		[
			"systemAudio",
			"boolean",
			"true",
			"Ask for the whole system's audio where the browser allows it.",
		],
		["preferCurrentTab", "boolean", "false", "Offer the current tab first in the picker."],
	]}
/>

The options can be an object or a getter. `start()` reads them when it opens the picker.

## Returns

<PropsTable
	rows={[
		["isSupported", "boolean", null, "The browser can capture display media at all."],
		["stream", "MediaStream | null", null, "The captured audio."],
		[
			"status",
			'"idle" | "prompting" | "active" | "no-audio" | "denied" | "ended" | "unsupported"',
			null,
			"no-audio means the user shared without audio; ended means they stopped sharing.",
		],
		["error", "Error | null", null, "The last error."],
		["start", "() => Promise<void>", null, "Open the picker. Call it from a user gesture."],
		["stop", "() => void", null, "Stop capturing."],
	]}
/>
