I'd like to build something a little like the LiveEffect sample in the Google/Oboe library.
However, I want to affect the audio selected from a file chosen by the user rather than the microphone input. I do not need the input.
There's no example in the Google/Oboe repo of how to operate on a file.
Does anyone have an example or guidance so I can let the user choose a file from their local storage, then (and this is the bit I'm missing) pass the audio across the JNI bridge to my oboe app?
I do the need low-latency capability of Oboe as I'm going to affect the audio in response to motion data.
Any guidance gratefully recieved.
For anyone passing by in search of a similar solution, here's how I solved this
On the Java/Kotlin side pick up the audio file (i used a WAV in this
case) with an intent
Use a contentResolver on the audio file to create an inputStream
read the data from the inputStream into a byteArray
pass the byteArray over the JNI bridge to the native code
wrap the byteArray in a MemInputStream from the PARSELIB example
wrap the MemInputStream in a WavStreamReader, also from the PARSELIB example
create a SampleBuffer, from the IOLIB example, and load the WavStreamReader into it
create SampleSource, from the IOLIB example, and give it the SampleBuffer
give the SampleSource and SampleBuffer to the SimplePlayer from the IOLIB example
do the processing in the SampleSource's mixAudio() method bearing in mind all the rules for real-time processing in Oboe.
I also needed to do this on the block because I have a fixed window operation. to do this, I adapted the SampleBuffer class to add a method that would pull block data into mixAudio(), but that's only specific to some cases.
I hope that helps someone in the future.
Related
I'm trying to receive RTSP stream (playback) to android device and get access to video/audio tracks byte buffer pre/post decode.
Is there a way to achieve that?
RTSP is not exactly handling the streams of data itself. It is more like controlling things for the protocols that actually handle data, like RTP/RTCP for example. RTSP acts for, say exchange SDP informations, start/stop playing, fast forward etc...
So if you want to access the raw content data, you should try to get deeper into those "content" layers.
If you try to use some library to fetch RTSP data, they probably rely on low level native (NDK) implementations or libs, and the transport data is most probably compressed or encrypted.
Which makes it very unlikely to get the content data easily, or should I say possible.
You still have the possibility to implement your own RTSP client (not too difficult, you need to implement the basics of https://www.rfc-editor.org/rfc/rfc7826), then handle the management of the data to some other libs whom you get source code, such as FFMPEG, and dive into the source, write the necessary (native) code to hook and get the data, recompile and add to your project.
Far less easy.
I need to implement a video DASH client for Android.
At this time I haven't find any solution except write the InputStream in a temp file and then read the file. Of course this solution is not efficient at all. I thought to use an OutputStream to use its FileDescriptor as the data source. But I'm not able to use a valid FileDescriptor without creating an existing file...
Because of the DASH protocol, the client has the charge of getting all the (little) segments, so I really need to find a way to read the media directly from the memory. Maybe the only solution is to use the JNI but I don't really know how.
To resume I'm open to every suggestions. The only constraints are :
At first I have an InputStream
Here it can be any intermediate operations but the more efficient as possible
Get a valid input to feed a MediaPlayer
That seems pretty basic but I can't found any way to achieve that. Thanks.
Derzu is correct that a local proxy can do this. See my answer here. Feel free to ask any questions.
I am creating one application in Android. My application record audio and store it on SD card
and show in list format. I do this all but i need to edit this audio like suppose i open recording
then i need to start this recording again from ending and able to append audio in that recording.
Like: Suppose my recoding "MyRecord01" time is 04.06 sec and i want to add more audio in the recording
then it must start from 04.07 and add some audio.
I search lot of but didn't find anything relative. Please direct me to any link or any reference.
Or give me any hint.
Thanks in advance.
Here is the code you need. Hope it works for you.
If I identified your problem wrong, feel free to comment and tell me.
This is not too difficult. The key is to understand how the audio you've recorded is formatted. It's easiest if you use an uncompressed format, like WAV or AIFF. Here is one (of many) explanations of the WAV file formats: https://ccrma.stanford.edu/courses/422/projects/WaveFormat/
Most WAV files can be easily appended to if the data chunk is last (this may be a requirement of the format, I can't recall for sure). If it is not last, you'll first have to copy the file and modify it such that the data chunk is last. This can be a time-consuming step if the file is large.
Once that's done, you simply append new audio data to the data chunk and update a few pieces of data elsewhere in the file, such as the data chunk size (in the the data chunk), the chunk size (in the RIFF descriptor) and the Subchunk1 size (in the fmt chunk). (That will all make more sense to you once you read the explanation.) You may want to do something with those data while you are appending so that it is easy to fix in case your app crashes durring the append -- you don't want to corrupt the user's data.
The process is similar for AIFFs, but there are differences in the details.
For MP3s, I am not 100% sure off the top of my head how this would work. If memory serves the process is conceptually easier because MP3 files are structured as a series of independent chunks, and each chunk has its own mini header. Theoretically, you can just append more chunks. In practice it is going to be more complex, though, because of the compression and things like ID3 tags.
I'm attempting to stream from a URL using Android's built in MediaPlayer class. However, I also need to send a special header along with the URL. Is this possible without having to rewrite the whole steaming process?
If it's not possible to send a header, I would need to stream the file manually. However, it appears that the MediaPlayer class locks the file you are writing to when it begins reading the file. This means you cant just simply continue writing to the file while reading from it. I've seen the 'double buffer' method however that results in choppy playback. Any suggestions?
I asked a question recently about alternatives to the double buffer method you mentioned:
is-there-a-better-way-to-save-streamed-files-with-mediaplayer
I guess you could act as a proxy in a thread, handle your header and forward the rest to the media player? Or if you control the server pass the extra data in a different request...
Short version: What is the best way to get data encoded in an MP3 (and ideally in an
AAC/Ogg/WMA) into a Java array or ByteBuffer that I can then
manipulate?
I'm putting together a program that has slowing down and speeding up
sound files as one of its features. This works fine for WAV files,
which are a header plus the exact binary data that needs to be sent to
the speaker, and now I need to implement it for MP3 (ideally, this
would also support AAC, Ogg, and WMA, but since those are less popular
formats this is not required). Android does not expose an interface
to decode the MP3 without playing it, so I need to create that
interface.
Three options present themselves, though I'm open to others:
1) Write my own decoder. I already have a functional frame detector
that I was hoping to use for option (3), and now should only need to
implement the Huffman decoding tables.
2) Use JLayer, or an equivalent Java library, to handle the
decoding. I'm not entirely clear on what the license ramifications
are here.
3) Connect to the libmedia library/MediaPlayerService. This is what
SoundPool does, and the amount of use of that service make me believe
that while it's officially unstable, that implementation isn't going
anywhere. This means writing JNI code to connect to the service, but
I'm finding that that's a deep rabbit hole. At the surface, I'm
having trouble with the sp<> template.
I did that with libmad and the NDK. JLayer is way to slow and the media framework is a moving target. You can find info and source code at http://apistudios.com/hosted/marzec/badlogic/wordpress/?p=231
I have not tried it, but mp3transform is LGPL.