We have recently been receiving reports of audio not playing in our Android apps, on the Samsung Galaxy S4. The app is fine on other devices.
The audio is streamed using the MediaPlayer. It is saved locally using the Android Socket method.
The warning in the Logcat is caused by:
try {
byte[] buffer = httpString.toString().getBytes();
int readBytes = -1;
Log.d(LOG_TAG, "writing to client");
client.getOutputStream().write(buffer, 0, buffer.length);
// Start streaming content.
byte[] buff = new byte[1024 * 64];
while (isRunning && (readBytes = data.read(buff, 0, buff.length)) != -1) {
client.getOutputStream().write(buff, 0, readBytes);
}
}
The stack trace is as follows:
D/StreamProxy(3913): downloaded
D/StreamProxy(3913): downloading...
D/StreamProxy(3913): reading headers
D/StreamProxy(3913): headers done HTTP/1.0 200 OK
D/StreamProxy(3913): Content-Type: audio/mpeg
D/StreamProxy(3913):
D/StreamProxy(3913): writing to client
W/StreamProxy(3913): Broken pipe.
W/StreamProxy(3913): java.net.SocketException: sendto failed: EPIPE (Broken pipe)
W/StreamProxy(3913): at libcore.io.IoBridge.maybeThrowAfterSendto(IoBridge.java:506)
W/StreamProxy(3913): at libcore.io.IoBridge.sendto(IoBridge.java:475)
W/StreamProxy(3913): at java.net.PlainSocketImpl.write(PlainSocketImpl.java:507)
W/StreamProxy(3913): at java.net.PlainSocketImpl.access$100(PlainSocketImpl.java:46)
W/StreamProxy(3913): at java.net.PlainSocketImpl$PlainSocketOutputStream.write(PlainSocketImpl.java:269)
W/StreamProxy(3913): at com.gm.mobile.util.StreamProxy.processRequest(StreamProxy.java:234)
W/StreamProxy(3913): at com.gm.mobile.util.StreamProxy.run(StreamProxy.java:123)
W/StreamProxy(3913): at java.lang.Thread.run(Thread.java:856)
W/StreamProxy(3913): Caused by: libcore.io.ErrnoException: sendto failed: EPIPE (Broken pipe)
W/StreamProxy(3913): at libcore.io.Posix.sendtoBytes(Native Method)
W/StreamProxy(3913): at libcore.io.Posix.sendto(Posix.java:151)
W/StreamProxy(3913): at libcore.io.BlockGuardOs.sendto(BlockGuardOs.java:177)
W/StreamProxy(3913): at libcore.io.IoBridge.sendto(IoBridge.java:473)
W/StreamProxy(3913): ... 6 more
E/(3913): client closing
D/StreamProxy(3913): Proxy interrupted. Shutting down.
The stream plays when I comment out the proxy code, however, it starts playing for a second, then starts buffering for 2-3 seconds, before resuming.
Any solutions would be greatly accepted.
I have found similar issues, but they have not been solved:
I've finally figured out the issue that was causing this. As expected, the media player was doing range requests in an attempt to find the id3 information. On other phones simply setting the header status line to HTTP/1.0 206 OK
would prevent the media player from performing such range requests. However, for some odd reason, this is not true on the S4 (thanks Samsung!).
So in order to fix it, you will just need to handle these range requests. In my case I was only calling socket.accept()
one time. I changed this to be performed in a loop while isRunning
is true in my run()
function. This way, when a new request is done, it is handled properly. A chopped-down version of my code looks like this...
public void run() {
while (isRunning) {
client = socket.accept();
HttpResponse cloudResponse = startCloudRequest();
sendDataToMediaPlayer(cloudResponse);
}
}
Hope this helps.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With