Gagravarr / VorbisJava

A library for working with Ogg Vorbis files
Apache License 2.0
126 stars 26 forks source link

How to decode Opus in a non-blocking way from an OGG stream (code inside) #44

Open stefan-reich opened 2 years ago

stefan-reich commented 2 years ago

Hi, I'm receiving opus audio data (.ogg) as a live stream, and want to decode each packet as it arrives.

So I assume I'll have to patch OggPacketReader to "pause" when no more bytes are available currently.

I could use blocking I/O, but that's really not preferred.

Edit: After looking at the sources, I don't think it's going to be very hard. Just have the InputStream return null when temporarily out of bytes, and rewind the stream when getNextPacket() returns null. Plus make sure OpusFile gets enough initial packets to start up.

Edit 2: I got it done! Demo: https://code.botcompany.de/1032909, main class: https://code.botcompany.de/1032905 (it's in my dialect JavaX, but you can click on "Pure Java Version")

The trick is to have your InputStream simply behave like EOF when it is currently out of bytes, and have the other classes work properly with this.

nick-burch-flec commented 2 years ago

For a streaming, more event-driven case, my idea was that users would use the OggStreamListener and OggStreamReader classes, via the public OggFile(InputStream input, OggStreamListener listener) constructor. That would wait on sufficient data coming in from a stream, then fire off events whenever a whole packet was available. There's no real integration with the audio format classes from that though, as it has never had much use, but it wouldn't be too much work to wire in, eg via OpusPacketFactory.create

Assuming your stream blocks when it is waiting for data, you could always have a worker thread that waits as the data comes in and processes, then eg gives you back a Future you can wait on if you need the whole file available to fully process

ayush-pradhan-bit commented 2 years ago

Hello, I am stuck in similar code but in Python. I am getting data in byte array as shown below:

`b'\x01\x00\x00\t\xa9\x00\x00\x00\x00Z\x1f\x02\xf9\x15q\x9d1$\xd2\xde:\xb44\xaf\x8d]\xd7\xc9-?\xa3\xea\xa4\xfd\xca\xb4J\x94E\x0e\x01^\xe1\xa7Lgh\x82\xf4\xc0\xb5\x84\t\x89\xf4HO\x00U\xec\xaeX\x07\xdbR\x95L*\xa8\xc3\xa4\xae\xfb\x9d\xf9\x04y\xcb\xef\x86\x11\x1f\x93\xe8\xe8\xa3tA\x07JP\xf6@I \x8d)\x1b@+\x11o\x05.Q\xbab\x8f\x85\xa2\xfa\xd8\xd1\xfd\xb1;2 \xec\xees\xf0'

Can someone help me in this, from my understanding we have to divide the code having a comment header and and ID header.

stefan-reich commented 2 years ago

I think this is the wrong place for your question @ayush-pradhan-bit