Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unexpected status line: ICY 200 OK for URL openStream() method?

According to changes for kitakt 4.4 there were some problems with playing shoutcast streams (those returning "ICY" instead of "HTTP/1.x" response).

So solution for kitkat was to reregister "icy" protocol prefix in JVM once before we opened a stream by this:

try {
        java.net.URL.setURLStreamHandlerFactory( new java.net.URLStreamHandlerFactory(){
            public java.net.URLStreamHandler createURLStreamHandler( String protocol ) {
                Log.d( LOG, "Asking for stream handler for protocol: '" + protocol + "'" );
                if ("icy".equals( protocol )) return new com.spoledge.aacdecoder.IcyURLStreamHandler();
                return null;
            }
        });
}
catch (Throwable t) {
        Log.w( LOG, "Cannot set the ICY URLStreamHandler - maybe already set ? - " + t );
}

I have problem with open audio stream to make it register. After I call url.opnestream(stream) I got exception:

java.net.ProtocolException: Unexpected status line: ICY 200 OK

How could I fix it?


Here is sample of registering audio, so far what I did..

try {
    URL url = null;
    url = new URL(u);
    inputStream = url.openStream();

    startTime = System.currentTimeMillis();

    Boolean isSDPresent = android.os.Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED);

    String fileName = File.separator + "radio_" + "recording_" + channelMetadata.replaceAll("\\W", "") + System.currentTimeMillis();

    if(isSDPresent)
    {
        outputSource = Environment.getExternalStorageDirectory() + fileName;
    }
    else
    {
        outputSource = Environment.getDataDirectory() + fileName;
    }

    if(contentType.equals("audio/aacp"))
        fileOutputStream = new FileOutputStream(outputSource  + ".acc");
    else if(contentType.equals("audio/mpeg"))
        fileOutputStream = new FileOutputStream(outputSource + ".mp3");
    else
        fileOutputStream = new FileOutputStream(outputSource + ".nieznany_format");

    int bytesRead = 0;
    int bytes;
    while (((bytes = inputStream.read()) != -1) && isRecording) {

        fileOutputStream.write(bytes);
        bytesRead++;

        stopTime = System.currentTimeMillis();

        long seconds = (Math.abs(startTime-stopTime));
        int minutes = 1000 * 60 * 60;

        if(minutes<=seconds)
        {
            Log.d("xxx", "recording task exceed stopped");
            break;
        }
    }

    inputStream.close();
    fileOutputStream.close();

} catch (IOException e) {
    e.printStackTrace();
    isRecording = false;
}

isRecording = false;
return null;
like image 797
deadfish Avatar asked Feb 16 '14 14:02

deadfish


2 Answers

Various changes were made for Android 4.4, and it seems that the non-standard ShoutCast ICY header is not supported by Android.

It seems though that the good people of OkHttp fixed the issue (issue 1 and issue 2) already a few days ago.
What you can do, is simply use OkHttp lib directly in your application and by that you'll use the newer OkHttp version (the one with the fix) and not the one shipped with Android (where you'll have to wait for an OS update).
This will also fix it for your application running on other devices that might suffer from that issue.

like image 135
Assaf Gamliel Avatar answered Nov 06 '22 16:11

Assaf Gamliel


The answer of Assaf Gamliel worked for me. For those not familiar with this, you have to download the last .jar from okHttp and the .jar from the dependency okio . Add them to your libs directory and connect like this :

OkHttpClient client = new OkHttpClient();
 Request request = new Request.Builder()
 .url(mediaUrl)
 .build();

 Response response = client.newCall(request).execute();
 InputStream stream = response.body().byteStream();
like image 41
Star Platinum Avatar answered Nov 06 '22 16:11

Star Platinum