Android MediaPlayer read from an InputStream - android

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.

Related

Processing a file with Oboe

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.

how to download PDF file from server.

I am trying to download a file from server, what I have in mind to get filename in json response and the content and write same in assets or on sdcard. should i go and implement same, or there can be some other way we can achieve the same.
Actually you know you control the way you expose the content from the server - you can just make the file itself (its bytes) exposed at certain url. If you need to keep the name of the file posting as json seems to be good solution.
However, there is one trick here: I don't know how big the file you refer to is and also how reliable the network will be. For every bigger file I will recommend to implement resumable upload via byte serving. You can read about the byte serving client consumer in Android in this thread. Then just go and see on how to implement byte serving server side - it definitely depends on the platform in the only case in which I used such mechanism I actually had to mimic the byte-serving with my custom url parameter. If you need further help on server side write back and I will extend my answer.

Android: BufferedOutputStream necessary when saving file to internal data?

I wanted to save a string to a file and read it back, so I followed those two examples:
developer.android.com example
anddev.org example
However, in both of them, no BufferedOutputStream wrapper is used, while the docu of FileOutputStream recommends it.
Was this done to have an easier example or is it really not necessary on Android? And does whatever the answer is also apply to the InputStream?
Regards,
jellyfish
In this case, the authors of the examples know the size of the output data to be small ahead of time. You really only need the Buffered version if you have "large" amounts of data to write (which you usually don't know for absolute certainty ahead of time).
The JavaDocs for BufferedOutputStream highlights this well...
Expensive interaction with the
underlying input stream is minimized,
since most (smaller) requests can be
satisfied by accessing the buffer
alone.

Create mediaplayer with inputstream in android

How to I create mediaplayer instance with inputstream?
I see only 4 function for setDataSource. And there is no function getting inputstream ?
is it a must to use FileDescriptor to mediaplayer ? It seems so basic. but, I couldnot find a way. In j2me, there is a function that Manager.createPlayer(InputStream). And you can use inputstream to create a media player. Is there a way to create a mediaplayer like j2me ?
How about making a HTTP server on the recieveing side (a thread on the phone) that outputs the data from the InputStream on any HTTP request to the OutputStream of the Socket and provide MediPlayer with URI http 127.0.0.1 : a port? THAT IS UGLY (but it should work)
it is also possible to play PCM uncompressed audio from an InputStream in android. goole it. if you can do decoding in software with JLayer or something and output it as PCMto the audio interface that should do the trick too but without hardware acceleration.
Pick your poison I guess. I chose option B.
One approach can be to write your stream to a File and then give it to the MediaPlayer for playback.
I'm looking into this right now (in order to send encrypted movie files to the MediaPlayer). Am I wrong in assuming the FileInputStream.getFD() is the solution to this? If you can get a FileDescriptor from a FileInputStream (unless you specifically need InputStream and not FileInputStream) then it seems like that can be passed right on to the MediaPlayer.
EDIT: Okay, so FileInputStream is created using a path or URL, making it useless.
You are correct, MediaPlayer will not take a stream parameter directly as its data source. The four overloaded versions of setDataSource() allow the data to come from a file (using the file path OR a FileDescriptor) or a Uri (web location or local content:// uri).
In addition, to static create() method can create a media player from a raw resource (R.raw.something) or the same style Uri as above.
Where are you sourcing the audio/video from other than either a file location or the web?
for now, I copy the InputStream to a temp file and give it to mediaplayer. but, you know, it s not good solution. because, it s slow solution. if data is big, player must wait too much.
my source is changing. for example, it s come from database. if I will not find solution, I convert my code to getting file. but, for now I desing the system to getting inputstream and play it. like, j2me function of MediaPlayer.createPlayer(InputStream,String)
I think you can get the file descriptor from your input stream and feed that to your setDataSource.

How to download only the first part of a .csv file on Android?

In my app, I have to present a few numbers from a .csv file that's accessible from the web. Now, this .csv is quite big. I don't want to download and process the whole thing, there's no point. My numbers are always in the beginning of the file, in well specified positions - lets say position 5 to 10.
Could you give me some tips on how to implement this? I know how to download the whole thing, but don't know how to download only a part of it.
Thanks.
Psuedo:
BufferedReader br = new BufferedReader (new InputStreamReader(remoteStream));
String sFirstLine = br.readLine();
remoteStream is the stream of the connection to the remote server. Getting a handle to the stream is not the same as actually downloading. Only the BufferedReader.readLine() actually downloads anything
Do you have access to the server the file is on? You could do your processing on the server.
For example, if the file is at /myfile.csv, you could open a stream to mycsvfile.php on the server, which does the processing and returns the positions you're interested in. Of course you'd also have to write the PHP code (or whatever) to do this.
You don't say what protocol the file is served under, but assuming something standard like an http or ftp there should be nothing to stop you from starting the download and then aborting it once you've gotten as much of the file as you need, provided that you implement the android end of the protocol yourself rather than using one of the built in mechanisms (unless you find the built in mechanism also gives you the ability to abort).
I don't believe the implementation of a simple http downloader in java or ndk to be too complicated. Doing it on android should not be uniquely challenging as you have all of the normal java and underlying linux network sockets mechanisms readily available.

Categories

Resources