Metadata-Version: 2.4
Name: livekit-simple-audio-source-streaming
Version: 0.1.2
Summary: A Python library for streaming audio to LiveKit voice channels using FFmpeg
Home-page: https://github.com/ANBAL534/livekit-simple-audio-source-streaming
Author: Aníbal Muñoz
Author-email: Aníbal Muñoz <anbal.mc@hotmail.com>
License: MIT License
        
        Copyright (c) 2024 MCausc78
        
        Permission is hereby granted, free of charge, to any person obtaining a copy
        of this software and associated documentation files (the "Software"), to deal
        in the Software without restriction, including without limitation the rights
        to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
        copies of the Software, and to permit persons to whom the Software is
        furnished to do so, subject to the following conditions:
        
        The above copyright notice and this permission notice shall be included in all
        copies or substantial portions of the Software.
        
        THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
        IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
        FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
        AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
        LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
        OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
        SOFTWARE.
        
        ------------------------------------------------------------------------------
        
        This project includes code from https://github.com/Rapptz/discord.py, which is
        available under the MIT license:
        
        The MIT License (MIT)
        
        Copyright (c) 2015-present Rapptz
        
        Permission is hereby granted, free of charge, to any person obtaining a
        copy of this software and associated documentation files (the "Software"),
        to deal in the Software without restriction, including without limitation
        the rights to use, copy, modify, merge, publish, distribute, sublicense,
        and/or sell copies of the Software, and to permit persons to whom the
        Software is furnished to do so, subject to the following conditions:
        
        The above copyright notice and this permission notice shall be included in
        all copies or substantial portions of the Software.
        
        THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
        OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
        FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
        AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
        LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
        FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
        DEALINGS IN THE SOFTWARE.
        
Project-URL: Homepage, https://github.com/ANBAL534/livekit-simple-audio-source-streaming
Project-URL: Repository, https://github.com/ANBAL534/livekit-simple-audio-source-streaming
Keywords: livekit,audio,streaming,ffmpeg,voice,stoat,stoatchat,revolt,bot
Classifier: Intended Audience :: Developers
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: Topic :: Multimedia :: Sound/Audio
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: livekit>=1.1.2
Provides-Extra: dev
Requires-Dist: stoat.py>=1.2.1; extra == "dev"
Requires-Dist: ruff>=0.1.0; extra == "dev"
Requires-Dist: mypy>=1.0.0; extra == "dev"
Dynamic: author
Dynamic: home-page
Dynamic: license-file
Dynamic: requires-python

# LiveKit Audio Source Streaming

A Python library for streaming audio to LiveKit voice channels using FFmpeg.

## Overview

This library provides a simple way to play audio files (MP3, WAV, OGG, streaming URLs, etc.) into LiveKit voice channels. It uses FFmpeg to decode audio and streams the raw PCM data to LiveKit's audio infrastructure.

### Features

- **Multiple audio format support** - Play any audio format supported by FFmpeg (MP3, WAV, OGG, FLAC, AAC, streaming URLs, etc.)
- **High-quality audio** - Configurable sample rate (default 48kHz) and channel count (mono/stereo)
- **Multiple simultaneous sources** - Play multiple audio sources simultaneously with named identifiers
- **Easy API** - Simple async/await API for playing and stopping audio
- **Proper cleanup** - Graceful handling of FFmpeg processes and track publication

## Requirements

- Python 3.10+
- FFmpeg installed on the system
- LiveKit SDK (`livekit`)

## Installation

### From PyPI

```bash
pip install livekit-simple-audio-source-streaming
```

### From source

```bash
git clone https://github.com/ANBAL534/livekit-simple-audio-source-streaming.git
cd livekit-simple-audio-source-streaming
pip install -e .
```

## Quick Start

See: [example.py](example.py)

## API Reference

### VoiceClient

The main class for managing audio playback in a LiveKit room.

#### Constructor

```python
VoiceClient(room: Room)
```

**Parameters:**
- `room` (Room): A connected LiveKit Room instance. <https://docs.livekit.io/python/livekit/rtc/room.html#livekit.rtc.room.Room>

#### Methods

##### play(source: str, name: str = 'audio') -> FFmpegAudio

Play audio from a source and publish it to the room.

**Parameters:**
- `source` (str): URL or file path to the audio source.
- `name` (str): Identifier for this audio source (default: 'audio'). Used to reference
  the source when stopping.

**Returns:**
- FFmpegAudio: The audio source instance.

**Example:**
```python
# Play a simple audio file
audio = await voice_client.play("music.mp3")

# Play from a URL with custom name
background = await voice_client.play(
    "https://example.com/background.mp3",
    name="background"
)
```

##### stop(name: str = 'audio') -> None

Stop playing audio from a specific source.

**Parameters:**
- `name` (str): Name of the audio source to stop (default: 'audio').

**Example:**
```python
await voice_client.play("music.mp3", name="music")
await asyncio.sleep(10)
await voice_client.stop("music")
```

##### stop_all() -> None

Stop all currently playing audio sources.

**Example:**
```python
await voice_client.play("music.mp3", name="music")
await voice_client.play("sfx.mp3", name="sfx")
await voice_client.stop_all()
```

##### disconnect() -> None

Stop all audio and disconnect from the room.

**Example:**
```python
await voice_client.disconnect()
```

### FFmpegAudio

Audio source class that streams audio using FFmpeg.

#### Constructor

```python
FFmpegAudio(
    source: str,
    sample_rate: int = 48000,
    num_channels: int = 1
)
```

**Parameters:**
- `source` (str): URL or file path to the audio source.
- `sample_rate` (int): Output sample rate in Hz (default: 48000).
- `num_channels` (int): Number of audio channels (default: 1 for mono).

**Example:**
```python
audio = FFmpegAudio(
    source="music.mp3",
    sample_rate=48000,
    num_channels=1  # 1 = mono, 2 = stereo
)
```

#### Methods

##### create_track() -> LocalAudioTrack

Create a LiveKit audio track from this audio source.

**Returns:**
- LocalAudioTrack: A LiveKit local audio track.

##### start() -> None

Start streaming audio from FFmpeg to LiveKit.

**Note:** Must be called after the track is published to a room.

##### stop() -> None

Stop the FFmpeg process and audio streaming.

##### close() -> None

Close and clean up the FFmpeg audio source.

### Using with Stoat Bot Libraries

This library is to be integrated with Stoat bot libraries that support LiveKit:

```python
import stoat  # or your preferred library (In the example: stoat.py lib)

# Get the LiveKit room from your bot
room = await channel.connect(node=node_name)

# Use VoiceClient to play audio
voice_client = VoiceClient(room)
await voice_client.play("notification.mp3")
```

## Requirements

### System Requirements

- **FFmpeg**: Must be installed on the system. Install via:
  - Ubuntu/Debian: `sudo apt install ffmpeg`
  - macOS: `brew install ffmpeg`
  - Windows: Download from ffmpeg.org or use a package manager

### Python Dependencies

See: [requirements.txt](requirements.txt)

## Error Handling

The library raises exceptions for various error conditions:

```python
try:
    audio = await voice_client.play("invalid-file.mp3")
except Exception as e:
    print(f"Failed to play audio: {e}")
    # Handle the error appropriately
```

Common exceptions:
- `RuntimeError`: If the audio source is already closed
- `asyncio.TimeoutError`: If track publication times out
- Various FFmpeg errors if the audio file is invalid

## Logging

The library uses Python's standard logging module. Enable debug logging for detailed information:

```python
import logging

logging.basicConfig(level=logging.DEBUG)

# Now you'll see detailed logs about FFmpeg operations
voice_client = VoiceClient(room)
```

## License

MIT License - See LICENSE file for details.

## Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

Keep in mind that this is a very simple library to enable the creation of quick voice bots such as Youtube Music bots, etc.

Other use cases as audio consumption, multi-channel, etc. are out-of-scope of this project.

## Support

- Issues: https://github.com/ANBAL534/livekit-simple-audio-source-streaming/issues
- Discussions: https://github.com/ANBAL534/livekit-simple-audio-source-streaming/discussions
