Skip to main content

Murf BVC for LiveKit Agents

Background voice cancellation for voice agents. Murf BVC keeps the person talking to your agent and removes everyone and everything else (TV, other people in the room, street and office noise) before your agent's VAD, turn detection and speech-to-text see the audio. Fewer false interruptions, fewer transcripts of someone else's words.

It runs on CPU inside your agent process, like LiveKit's own noise-cancellation plugin. No GPU and no extra services; audio never leaves your process.

Requirements

  • Python 3.10+ and livekit-agents 1.2+
  • Linux (glibc 2.28+: Ubuntu 20.04+, Debian 10+, RHEL/Rocky/Alma 8+, Amazon Linux 2023) on x86_64 or aarch64, or macOS 11+ (Apple Silicon) / 10.15+ (Intel)
  • x86_64 CPUs need AVX2 and FMA (Intel Haswell / 2013 or newer, any AMD Zen); on ARM, AWS Graviton2 or newer, or any Apple Silicon Mac
  • A Murf API key with BVC enabled, or an offline license key for on-premise and air-gapped deployments (contact Murf)

Install

pip install livekit-plugins-murf-bvc

Quick start

Pass murf_bvc.BVC(...) with your key as the noise cancellation for the room's audio input:

from livekit.agents import Agent, AgentSession, JobContext, WorkerOptions, cli, room_io
from livekit.plugins import murf_bvc


async def entrypoint(ctx: JobContext):
    session = AgentSession(...)  # your STT, LLM, TTS, VAD, turn detection
    bvc = murf_bvc.BVC(api_key=load_murf_api_key())  # from your secrets manager

    await session.start(
        room=ctx.room,
        agent=Agent(instructions="You are a helpful assistant."),
        room_options=room_io.RoomOptions(
            audio_input=room_io.AudioInputOptions(noise_cancellation=bvc),
        ),
    )


if __name__ == "__main__":
    cli.run_app(WorkerOptions(entrypoint_fnc=entrypoint))

That's all most agents need. The defaults are what we recommend for production. On-premise or air-gapped, pass license_key="mbvc1...." (an offline license from Murf) instead of api_key.

Keys

Pass the key in code, as above, rather than through the environment. The key then applies only to that BVC value and the streams it creates, never enters LiveKit's options, and is not inherited by subprocesses or visible in the process environment, where crash reporters and debugging tools often collect it. A BVC() created without a key is not licensed by another one's key.

Key How it is checked
api_key: Murf API key The plugin exchanges it with Murf for a short-lived license (a lease, valid for an hour) and renews every 15 minutes, reporting how many minutes of audio it processed. A key you revoke on Murf stops working within the hour. Needs outbound HTTPS to api.murf.ai.
license_key: offline license (mbvc1....) Checked locally (signature and expiry); no network access. For on-premise and air-gapped deployments.

Without a key argument, BVC() falls back to the environment: MURF_BVC_LICENSE, then MURF_API_KEY.

Any code running in your agent process (other plugins included) can read memory it shares with the agent, so no way of passing a key hides it from them. Treat the BVC key like the agent's other API keys.

Options: when to change them

murf_bvc.BVC(api_key=None, license_key=None, restore=True, normalize=True, native=True)
Option Default Change it when
api_key MURF_API_KEY Pass it: see Keys.
license_key MURF_BVC_LICENSE You run on-premise or air-gapped with an offline license from Murf. Takes precedence over api_key.
restore True Leave on. While only the caller is talking, it gives back anything the model removed, so the caller's own voice is never thinned and STT accuracy holds up on clean calls. It runs a speaker check every 0.5 s of speech. Set False only if you'd rather have maximum removal at all times, or need to save that bit of CPU.
normalize True Leave on. It levels quiet and loud callers before the model so both get the same quality. There is no production reason to turn it off.
native True Leave on. It runs BVC inside LiveKit's audio pipeline. It falls back to a Python processor on its own if your livekit version predates audio-filter plugins, so you only set False when debugging.

Rooms with several participants

Nothing to change: one BVC() value serves every participant, each with its own independent state.

If you use native=False (or BVCProcessor directly), each processor handles one track, so pass a selector instead:

noise_cancellation=lambda params: murf_bvc.BVC(native=False)

What to expect

  • Latency: 10 ms at 16 kHz, about 13.6 ms at 24 or 48 kHz (resampling included).
  • CPU: about 3% of one core per active participant on an AWS AMD EPYC instance, plus a speaker check every 0.5 s of speech while caller restore is on. Processing is single-threaded per stream, so it scales with the number of concurrent calls.
  • Audio: any sample rate LiveKit delivers (8–96 kHz); stereo input is mixed to mono.

License behaviour

Without a valid license BVC does not stop your agent: it logs an error and passes audio through unchanged, delayed by the same few milliseconds, so calls keep working and a license expiring mid-call never knocks audio out of sync.

With an API key, the first BVC(api_key=...) in a process waits up to 5 s for its first lease (later ones return at once). If Murf cannot be reached, processing continues on the current lease for at least 45 minutes; after it expires audio passes through until a renewal succeeds, then processing resumes on its own.

Check a key at startup:

assert murf_bvc.licensed(api_key=key)   # or license_key=...; the reason is logged if not

Troubleshooting

You see Meaning
murf_bvc: no license: pass BVC(license_key=...) or BVC(api_key=...) No key was passed and neither MURF_BVC_LICENSE nor MURF_API_KEY is set.
murf_bvc: HTTP 401 invalid_api_key ...; lease renewal stopped The Murf API key is wrong or revoked.
murf_bvc: HTTP 403 not_entitled ...; lease renewal stopped The key's Murf account does not include BVC; contact Murf.
murf_bvc: lease request failed (...); retrying Murf can't be reached (outbound HTTPS blocked, or an outage). Processing continues until the current lease expires.
murf_bvc: no lease after 5 s The first lease is slow to arrive; audio passes through until it does.
murf_bvc: license for '...' has expired Renew the key with Murf.
this license does not carry a model key; reissue it An older-format key; ask Murf for a reissued one.
Illegal instruction when the agent starts The CPU lacks AVX2/FMA (very old x86, or some emulated/virtualized CPUs). Use a newer instance type.
pip finds no matching distribution Python older than 3.10, an unsupported platform, or glibc older than 2.28.

Metadata

Release files for livekit-plugins-murf-bvc 0.2.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Built distributions (wheels)

Table of built distributions (wheels) for livekit-plugins-murf-bvc 0.2.0
File Actions
livekit_plugins_murf_bvc-0.2.0-py3-none-manylinux_2_28_x86_64.whl Python 3 none Linux glibc 2.28+ x86-64 Details for livekit_plugins_murf_bvc-0.2.0-py3-none-manylinux_2_28_x86_64.whl
livekit_plugins_murf_bvc-0.2.0-py3-none-manylinux_2_28_aarch64.whl Python 3 none Linux glibc 2.28+ ARM64 Details for livekit_plugins_murf_bvc-0.2.0-py3-none-manylinux_2_28_aarch64.whl
livekit_plugins_murf_bvc-0.2.0-py3-none-macosx_11_0_arm64.whl Python 3 none macOS 11.0+ ARM64 Details for livekit_plugins_murf_bvc-0.2.0-py3-none-macosx_11_0_arm64.whl
livekit_plugins_murf_bvc-0.2.0-py3-none-macosx_10_15_x86_64.whl Python 3 none macOS 10.15+ x86-64 Details for livekit_plugins_murf_bvc-0.2.0-py3-none-macosx_10_15_x86_64.whl

Total release size: 157.1 MB

Release files / livekit_plugins_murf_bvc-0.2.0-py3-none-manylinux_2_28_x86_64.whl

Download URL livekit_plugins_murf_bvc-0.2.0-py3-none-manylinux_2_28_x86_64.whl
Size 39.2 MB
Tags Linux glibc 2.28+ x86-64 Python 3
SHA-256 checksum
How to use checksums
f60053e3c36f4af9445c1fced85759d70405dd8a05d738fe090d32f6091b8956
BLAKE2b-256 checksum
How to use checksums
34a4e98456e2d2643a72e4628c5e0c7b6b27634f297fa08b7b26729dad8b198d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 6, 2026.

Transparency log

Release files / livekit_plugins_murf_bvc-0.2.0-py3-none-manylinux_2_28_aarch64.whl

Download URL livekit_plugins_murf_bvc-0.2.0-py3-none-manylinux_2_28_aarch64.whl
Size 39.2 MB
Tags Linux glibc 2.28+ ARM64 Python 3
SHA-256 checksum
How to use checksums
2eb26a4f87110099740a6d586824a1d7c4859baf64001d935f21706fec5d1eef
BLAKE2b-256 checksum
How to use checksums
8811940d560ba2b88b0bf0886aa7c32f1ff938e9da479cce4e4003ce9a70a75b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 6, 2026.

Transparency log

Release files / livekit_plugins_murf_bvc-0.2.0-py3-none-macosx_11_0_arm64.whl

Download URL livekit_plugins_murf_bvc-0.2.0-py3-none-macosx_11_0_arm64.whl
Size 39.5 MB
Tags Python 3 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
97d77311224d163ce4f5f4b90b2131c9db474ba2d0e10bb160ce2b2a81eb18ec
BLAKE2b-256 checksum
How to use checksums
2c9c1c3dc65a000e93c6af40d7e7d10ec8f91767edeb9575eead216399d90e1c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 6, 2026.

Transparency log

Release files / livekit_plugins_murf_bvc-0.2.0-py3-none-macosx_10_15_x86_64.whl

Download URL livekit_plugins_murf_bvc-0.2.0-py3-none-macosx_10_15_x86_64.whl
Size 39.2 MB
Tags Python 3 macOS 10.15+ x86-64
SHA-256 checksum
How to use checksums
ece435c9fcec67f1e0226559d4c0f44801781e386f3f56ca6a8552b171b02fe9
BLAKE2b-256 checksum
How to use checksums
d1efa6236e5b206345e593b771052a61f54045effd46250da49b521f690898a4
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 6, 2026.

Transparency log

Security for livekit-plugins-murf-bvc 0.2.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 4 files in this release have been uploaded with provenance metadata.

Select from 4 files

Attestation for livekit_plugins_murf_bvc-0.2.0-py3-none-manylinux_2_28_x86_64.whl

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 6, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page