Is there any way to intercept or just-read the audio output in android device?
I need to read the whole audio output in PCM from inside myActivity, including media player application in background, voice from calls, MediaPlayer istances inside myACtivity, etc., everything that's going to played by speakers. Actually, if it was possible to read them separately, would be great as well.
I tried with AudioRecord, giving it as audioSource parameter every constant found in MediaRecorder.AudioSource with no luck, should I try different audioSources?
Is it a so low-level task that has to be handled within native layer?
The visualizer class is helpful. I use it to playback immediately played audio here.
This audio comes in very low quality, however, so it's only really good for visualization.
Related
Let me refraise my question, I wrote it in a hurry.
Current situation:
I have set up a digital video recorder to record broadcasts provided via DVB-C. It is running on a raspberry 3B using TVHeadend and jetty/cling to provide UPnP and other possibilities to access media files. For watching recordings, I wrote an android player app using IJKPlayer, which runs on smartphones, FireTV and AndroidTV.
One hassle when playing media files which are currently beeing recorded is, that IJKPlayer doesn not support timeshifting. Means, when I start playing a currently recording file, I can only watch the length which is known by the player at that moment. Anything which is recorded afterwards can not be played. I need to exit the player activity and start it again. I have resolved that issue by "simulating" a completed recoding using a custom servlet implementation. Since the complete length of the recording is already known, I can use ffmpeg to accomplish this.
Future situation:
I plan to move away from IJKPlayer to ExoPlayer, because it supports hardware playback and is much faster when playing h.264 media. I can of course use the same solution like above, but as far as I have found out yet, ExoPlayer can support media files which are currently being recorded by using the Timeline class. However, I don't seem to find neither a usefull documentation nor any good example. Hence, I would appreciate any help with the timeline object.
Regards
Harry
Looks like my approach won't work. At least, I didn't find a solution. Problem is, that the server returns the stream size as it is during player-start-time. I didn't find a method to update the media duration for "regular" files.
However, I can solve the problem by changing the server side. Instead of accessing a regular file, I convert the file to m3u8 in realtime, using ffmpeg. I then throw the m3u8 URI onto the player and it updates the duration of the stream (while playing) without the need to create any additional code on the client side.
I am looking for a way to mix an audio into an already-playing mixed audio stream. For example, when a sound is being played half way through, I want to add in another sound to play together without interrupting the first sound to continue. I would also like to have an ability to withdraw a playing sound stream from the mixed playing stream. Going through Android's relevant document, I think that the only possible solution is to use native OpenSL ES via JNI to develop my own library where I can programmatically mix in/take out an audio stream from mixed audio streams. I would like to hear if anyone has a way to achieve it with less effort.
Thank you
Chris
Have you considered SoundPool?
http://developer.android.com/reference/android/media/SoundPool.html
The android audio manager has a large number of different audio streams available, including DTMF, SYSTEM, RING etc.
Not that I'm saying its a good idea, but is there any significant disadvantage to playing audio on a stream other than MUSIC? The standard appears to be to play on the MUSIC stream, but if, for example, I want to use the ringer volume, is there any disadvantage to just playing on the RING stream instead?
There are a number of cases where playing on streams other than music offer some advantages in addition to the case I provided above, but I don't want to risk breaking more important functionality if I can help it.
I'd be curious to hear whether anyone has any experience playing on and/or manipulating other streams, and what side affects, if any, they've encountered (or incurred...)
Why do you need it? I think media stream is enough for any of your purposes.
Look, for example you use ring stream. And for example your program controls it volume. He sets "no volume" => it means that he goes into "vibrate mode" and he cant hear incoming rings because of your application
I'm currently implementing a sound effect mixing on Android via OpenSL. I have an initial implementation going, but I've encountered some issues.
My implementation is as follows:
1) For each sound effect I create several AudioPlayer objects (one for each simultaneous sound) that uses an SLDataLocator_AndroidFD data source that in turn refers to an OGG file. For example, if I have a gun firing sound (lets call it gun.ogg) that is played in rapid succession, I use around 5 AudioPlayer objects that refer to the same gun.ogg audio source and also the same outputmix object.
2) When I need to play that sound effect, I search through all the AudioPlayer objects I created and find one that isn't currently in the SL_PLAYSTATE_PLAYING state and use it to play the effect.
3) Before playing a clip, I seek to the start of it using SLPlayItf::SetPosition.
This is working out alright so far, but there is some crackling noise that occurs when playing sounds in rapid succession. I read on the Android NDK newsgroup that OpenSL on Android has problems with switching data sources. Has anyone come across this issue?
I'm also wondering if anyone else seen or come up with a sound mixing approach for OpenSL on Android. If so, does your approach differ from mine? Any advice on the crackling noise?
I've scoured the internet for OpenSL documentation and example code, but there isn't much out there with regards to mixing (only loading which I've figured out already). Any help would be greatly appreciated.
This is probably not the best approach (creating many instances of audio players). Unfortunately the Android version (2.3) of OpenSL ES doesn't support SLDynamicSourceItf. Which would be similar to OpenAL's source binding interface. One approach would be to create multiple stream players. You would then search for a stream player that isn't currently playing and start streaming your sound effect to it from memory. It's not ideal but it's doable.
You should probably not use the ogg format for sound effects either. You're better off with WAV (PCM) as it won't need to be decoded.
Ogg is fine for streaming background music.
I see that MediaRecorder allows you to record from the Microphone, or a phone call.
I'm using write() on an AudioTrack to produce sounds out of basic frequencies. Multiple AudioTracks actually.
I would have thought that there would be a MediaRecorder.AudioSource setting that captured whatever sounds the system was sending to the speakers.
I tried DEFAULT but it didn't work.
Unfortunately there is no loop back audio source for recording sounds generated by the device, just from external audio sources.