6


I want to cache data while playing it in MediaPlayer. As I read, there is one way to do it - create own local http server and set local url to MediaPlayer's setDataSource(String path).

I am using NanoHTTPD as a local server. There is code of serve function:


    @Override
    public Response serve(String uri, Method method, Map headers, Map parms, Map files)
    {
        try
        {
            // delete / character
            URL url = new URL(uri.substring(1));
            URLConnection connection = url.openConnection();
            connection.connect();

            File cacheFolder = new File(Environment.getExternalStorageDirectory(), "TracksFlowCacheNew");
            Log.e("RelayServer", "Cache to file " + Utils.md5(url.toExternalForm()));
            RelayInputStream ris = new RelayInputStream(connection.getInputStream(), new FileOutputStream(new File(cacheFolder, Utils.md5(url.toExternalForm()))));


            return new Response(Response.Status.OK, NanoHTTPD.MIME_DEFAULT_BINARY, ris);
        }
        catch(MalformedURLException e)
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        catch(FileNotFoundException e)
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        catch(IOException e)
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        return null;
    }


RelayInputStream extending InputStream. I am trying to cache data there:


    private class RelayInputStream extends InputStream
    {
        private InputStream mInputStream = null;
        private OutputStream mOutputStream = null;

        public RelayInputStream(InputStream is, OutputStream os)
        {
            mInputStream = is;
            mOutputStream = os;
        }

        @Override
        public int available() throws IOException
        {
            Log.e("available", "available = " + mInputStream.available());
            mInputStream.mark(mInputStream.available());
            return mInputStream.available();
        }

        @Override
        public int read(byte[] buffer) throws IOException
        {
            Log.e("read", "buffer = " + buffer.toString());
            mOutputStream.write(buffer);
            return mInputStream.read(buffer);
        }

        @Override
        public int read(byte[] buffer, int offset, int length) throws IOException
        {
            Log.e("read", "buffer = " + buffer.toString() + "; offset = " + offset + "; length = " + length);
            mOutputStream.write(buffer, offset, length);
            return mInputStream.read(buffer, offset, length);
        }

        @Override
        public int read() throws IOException
        {
            Log.e("read", "no data");
            byte[] b = new byte[1];
            mInputStream.read(b);
            mOutputStream.write(b);
            mInputStream.close();
            mOutputStream.close();
            return b[0] & 0xff;
        }
    }

But RelayInputStream's available returns only few downloaded bytes. So, there is only little part of data cached and returned to the media player. So, what am I doing wrong? How to forward and cache all stream?

Stephan
  • 41,764
  • 65
  • 238
  • 329
hexonxons
  • 845
  • 1
  • 10
  • 19
  • Sorry, but where are you trying to cache something? Please explain your code. – greenapps May 30 '15 at 08:51
  • available() returns the number of bytes you can read. But available() is not correct in many situations as you can see in the help too. You are not caching anything. For caching you would need a buffer. Now it looks if you wanted to cache to file but you are not doing that. You would need at least one thread that reads from original url and saved data to a buffer or file. Then your three read functions could read from that buffer or file. – greenapps May 30 '15 at 09:02
  • @greenapps Cant remember, I was learning android. Seems it shall read data from InputStream use data in MediaPlayer and write it to file. I tried to make music player app(music service client), and trying to find a way to save music stream to storage while playing. But service dies before I finish that app) – hexonxons May 30 '15 at 09:06
  • `mOutputStream.write(buffer);`. You have that statement in two read() functions. But that buffer is empty as read() is a request to fill that buffer. So that statement there is not ok. – greenapps May 30 '15 at 09:06
  • `way to save music stream to storage while playing`. That is something quite different from caching. Please explain better what you want. – greenapps May 30 '15 at 09:09
  • @greenapps I ask that question 2 years ago and now it is not actual, there is errors in code, like writing empty buffer, u told. But the problem: how to cache music for playing. So I wanna to start network stream reading, save 15 sec to file and start to play music from that file. That code was first approach to do that. MediaPlayer need InputStream as source, so I create InputStream where every read method reads data from original network stream, saves data to output and return buffer to MediaPlayer. Smth like that. – hexonxons May 30 '15 at 09:14
  • Ok. You start to play music from that file but after 15 seconds the file is played. How to continue? – greenapps May 30 '15 at 09:18
  • @greenapps so there will be 2 parallel threads as u noticed :) One will load data, another will play. – hexonxons May 30 '15 at 09:21
  • Yes. But you need to add only one thread as i said before. Nano cares for the other. – greenapps May 30 '15 at 09:23
  • @greenapps yep. It was not nano mistake, it was mine – hexonxons May 30 '15 at 09:31
  • @hexonxons did you somehow managed to solve this? – Akash Singh Nov 20 '15 at 10:33
  • @AkashSingh No, I didn't. But there is a major mistake, as noticed above: in `read` methods, except last one, I did `mOutputStream.write(buffer)`, while `buffer` is known to be empty. So maybe you shall swap `mInputStream.read(buffer)` and `mOutputStream.write(buffer)` and it will work.. But idk. – hexonxons Nov 20 '15 at 10:52

0 Answers0