Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Live audio stream #2526

Open
xXxNIKIxXx opened this issue Oct 19, 2024 · 9 comments
Open

Live audio stream #2526

xXxNIKIxXx opened this issue Oct 19, 2024 · 9 comments
Labels

Comments

@xXxNIKIxXx
Copy link

What do you need help with?

Is there or will there be a possibility to just feed an pyaudio stream to stream.stream_file?
This is to get the stream:

# Parameters
FORMAT = pyaudio.paInt16
CHANNELS = 1
RATE = 44100
CHUNK = 1024

# Initialize PyAudio
p = pyaudio.PyAudio()

# Open stream
stream = p.open(format=FORMAT,
                channels=CHANNELS,
                rate=RATE,
                input=True,
                frames_per_buffer=CHUNK)
@postlund
Copy link
Owner

That's not something I have considered implementing. But you can pass an up.BufferedIOBase, maybe you can write an adapter that supports pyaudio through that?

@xXxNIKIxXx
Copy link
Author

I had the same Idea but always get mediafile.FileTypeError: 'stream': not in a recognized format.
Here is the function i use

import pyaudio
import threading
import io

# Parameters
FORMAT = pyaudio.paInt16
CHANNELS = 1
RATE = 44100
CHUNK = 1024

class BufferedAudioStream(io.BufferedIOBase):
    def __init__(self, format, channels, rate, chunk):
        self.p = pyaudio.PyAudio()
        self.stream = self.p.open(format=format,
                                  channels=channels,
                                  rate=rate,
                                  input=True,
                                  frames_per_buffer=chunk)
        self.chunk = chunk
        self.buffer = bytearray()
        self.lock = threading.Lock()
        self.running = True

    def read(self, size=-1):
        with self.lock:
            if size == -1:
                size = len(self.buffer)
            data = self.buffer[:size]
            self.buffer = self.buffer[size:]
            return bytes(data)

    def update_buffer(self):
        while self.running:
            data = self.stream.read(self.chunk)
            with self.lock:
                self.buffer.extend(data)

    def close(self):
        self.running = False
        self.stream.stop_stream()
        self.stream.close()
        self.p.terminate()



# Initialize BufferedAudioStream
audio_stream = BufferedAudioStream(FORMAT, CHANNELS, RATE, CHUNK)

# Start the buffer update thread
buffer_thread = threading.Thread(target=audio_stream.update_buffer)
buffer_thread.start()
            
await atv.stream.stream_file(audio_stream)

@xXxNIKIxXx
Copy link
Author

i have also tried using lameenc to convert the stream into mp3 format. But this also didn't work.

@postlund
Copy link
Owner

Metadata detection is failing (for some reason). Try passing some bogus metadata to see if that helps (it will disable auto detection).

https://pyatv.dev/development/stream/#custom-metadata

@xXxNIKIxXx
Copy link
Author

Unfortunately this didn't work for me

@postlund
Copy link
Owner

Can you provide a more detailed exception of what is happening?

@xXxNIKIxXx
Copy link
Author

Yes. When I use the code above, I get the following error:
mediafile.FileTypeError: 'stream': not in a recognized format.

This is probably because the stream doesn't have any header information to indicate what format it is. Then I tried using it as a stream reader, but I got the same error.

With the library lameenc, I tried to convert the stream into an MP3 stream, but it didn't work because the MP3 information was provided in every frame, not just once. I also tried using the metadata to set the information, but that didn’t work either.

@xXxNIKIxXx
Copy link
Author

Do you have an idea how to implement this? Or have an idea what the problem is?

@postlund
Copy link
Owner

I believe you are on to the problem already. pyatv expects a proper container format (e.g. mp3 or ogg) and cannot decode raw PCM frames at the moment. That could probably be implemented in some intricate way, but I can't say how I would do it right now. I will have to think about it a bit.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants