Question

I have implement AudioStreaming to my application. All code is running well, except on Android 4.4.2, it doesn't work, i got an error message from DDMS on my application :

Unable to initialize the MediaPlayer for fileUrl=http://live.radiorodja.com:80
java.net.ProtocolException: Unexpected status line: ICY 200 OK
E/info.wd.controller.StreamingMediaPlayer$1(28900): Unable to initialize the MediaPlayer for fileUrl=http://live.radiorodja.com:80
E/info.wd.controller.StreamingMediaPlayer$1(28900): java.net.ProtocolException: Unexpected status line: ICY 200 OK
E/info.wd.controller.StreamingMediaPlayer$1(28900):     at com.android.okhttp.internal.http.RawHeaders.setStatusLine(RawHeaders.java:108)
E/info.wd.controller.StreamingMediaPlayer$1(28900):     at com.android.okhttp.internal.http.RawHeaders.fromBytes(RawHeaders.java:308)
E/info.wd.controller.controller.StreamingMediaPlayer$1(28900):  at com.android.okhttp.internal.http.HttpTransport.readResponseHeaders(HttpTransport.java:135)
E/info.wd.controller.StreamingMediaPlayer$1(28900):     at com.android.okhttp.internal.http.HttpEngine.readResponse(HttpEngine.java:644)
E/info.wd.controller.StreamingMediaPlayer$1(28900):     at com.android.okhttp.internal.http.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:347)
E/info.wd.controller.StreamingMediaPlayer$1(28900):     at com.android.okhttp.internal.http.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:296)
E/info.wd.controller.StreamingMediaPlayer$1(28900):     at com.android.okhttp.internal.http.HttpURLConnectionImpl.getInputStream(HttpURLConnectionImpl.java:179)
E/info.wd.controller.StreamingMediaPlayer$1(28900):     at info.wd.controller.StreamingMediaPlayer.downloadAudioIncrement(StreamingMediaPlayer.java:99)
E/info.wd.controller.StreamingMediaPlayer$1(28900):     at info.wd.controller.StreamingMediaPlayer$1.run(StreamingMediaPlayer.java:68)

And this is my downloadAudioIncrement sourcecode:

public void downloadAudioIncrement(String mediaUrl) throws IOException {
    isloading = true;
    URLConnection cn = new URL(mediaUrl).openConnection();

    //connecting
    cn.setReadTimeout(60000);
    cn.connect();
    statusPesan("", "Menghubungkan..");

    //loading
    InputStream stream = cn.getInputStream();
    statusPesan("", "Mohon tunggu...");

    if (stream == null) {
        error = true;
        statusPesan("", "Koneksi bermasalah");
        Log.e(getClass().getName(), "Unable to create InputStream for mediaUrl:" + mediaUrl);
    }

    downloadingMediaFile = new File(Environment.getExternalStorageDirectory()+ "/recradiodakwah/cache/", "streaming.dat");

    //ketika sudah ada, biasanya bakal crash, so delete yang sudah ada.
    if (downloadingMediaFile.exists()) {
        downloadingMediaFile.delete();
    }

    FileOutputStream out = new FileOutputStream(downloadingMediaFile);   
    byte buf[] = new byte[16384];
    int totalBytesRead = 0;
    setIncrementalBytesRead(0);

    do {
        int numread = stream.read(buf);   
        if (numread <= 0)   
            break;   
        out.write(buf, 0, numread);

        if (recordingStatus() == true) {
            recordStream.write(buf, 0, numread);
            totalKbrecord += numread;
            recordSizeMessage(String.format("%.2f",
                    ((float) (totalKbrecord / 1024) / 1024)) + " MB");
            mediaPlayer.setVolume(1, 1);
        } else {
            totalKbrecord = 0;
        }

        if (mediaPlayer != null) {
            if (mediaPlayer.isPlaying() == false) {
                mediaPlayer.seekTo(mediaPlayer.getCurrentPosition());
                mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
                    @Override
                    public void onPrepared(MediaPlayer mp) {
                        dur = mediaPlayer.getDuration();
                        mediaPlayer.start();
                    }
                });
            }
        }

        totalBytesRead += numread;
        setIncrementalBytesRead(getIncrementalBytesRead() + numread);
        totalKbRead = totalBytesRead/1000;

        if (totalKbRead < INTIAL_KB_BUFFER) {
            statusPesan("", "Persiapan...");
        } else {
            statusPesan(radioName, "[ " + String.format("%.2f", ((float) numread) / 128) + " kb ]");
            isloading = false;
        }

        testMediaBuffer();
    } while (validateNotInterrupted());   
        stream.close();
        out.close();
        statusPesan("", "");
    if (validateNotInterrupted()) {
        fireDataFullyLoaded();
    }
}  

StreamingMediaPlayer.java:99 is cn.connect();

Is there best practice to URLConnection on Android KitKat and solve this problem? Thank you.

Was it helpful?

Solution

The apparent problem is that the service you are talking to is sending an HTTP response that does not conform to then HTTP specification. Specifically, it is sending an invalid status line. A valid status line would look like this:

HTTP/1.0 200 OK

or

HTTP/1.1 200 OK

My conclusion is that the service you are talking is not designed to be accessed using the HTTP protocol. URLConnection won't cope with this, and nor will any other spec-conformant HTTP library.

What I think you have encountered here is the ICYCAST protocol.

References:

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top