开发者

Sending buffered data through a socket from Android

I develop the first part of an Android application that allows to broadcast video stream through the network. Currently, I'm sending the vide开发者_如何学运维o in a very direct way, like this:

Socket socket = new Socket(InetAddress.getByName(hostname), port);
ParcelFileDescriptor pfd = ParcelFileDescriptor.fromSocket(socket);
recorder.setOutputFile(pfd.getFileDescriptor());

But unfortunately, it is not very fluid. I want to buffered the data stream before sending it through the socket. One of the way I tried is to write the stream in a file using the Android API for recording media, and to use another thread to stream the file to the server on a conputer.

So my problem is: how can I send by a socket a file which is still under writing? As BufferedInputStream has not a blocking method for reading, I tried to do things like this one, but without any success

while (inputStream.available() >= BUFFER_SIZE) {
  inputStream.read(buffer);
  outputStream.write(buffer);
}
outputStream.flush();

But when i'm doing that, if the network is faster than the datastream, I get quickly out of the loop.

Is there a 'good' way to do that? I though about doing active waiting but it is not a good solution, especially for mobiles. Another way is to do something like this :

while (true) {
  while (inputStream.available() < BUFFER_SIZE) {
    wait(TIME); 
  }
  inputStream.read(buffer);
  outputStream.write(buffer);
}
outputStream.flush();

But it sound quite dirty for me... Is there sleeker solution?


What I do in these situations if simply fill up a byte array (my buffer) until either I've hit the end of the data I'm about to transmit, or the buffer is full. In which case the buffer is ready to be passed to my Socket transmission logic. Admittedly, I do not do this on video or audio though … only on “regular” data.

Something worth noting is this will give a "janky" user experience to the recipient of that data (it might look like the network is stopping for short periods then running normally again ... the time the buffer is using to fill up). So if you have to use a buffered approach on either video or audio be careful on what buffer size you decide to work with.

For things like video it's been my experence to use streaming based logic versus buffered, but you apparently have some different and interesting requirements.


I can't think of a pretty way of doing this, but one option might be to create a local socket pair, use the 'client' end of the pair as the MediaRecorder output fd, and buffer between the local-server socket and the remote-server. This way, you can block on the local-server until there is data.

Another possibility is to use a file-based pipe/fifo (so the disk doesn't fill up), but I can't remember if the Java layer exposes mkfifo functionality.

In any event, you probably want to look at FileReader, since reads on that should block.

Hope this helps,

Phil Lello

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜