意外的状态行:URL openStream()方法的ICY 200 OK?

时间:2014-02-16 14:29:29

标签: android inputstream aac android-audiorecord

根据kitakt 4.4的变化,播放shoutcast流有些问题(那些返回“ICY”而不是“HTTP / 1.x”响应)。

因此,kitkat的解决方案是在我们打开流之前在JVM中重新注册“icy”协议前缀:

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 );
}

我有打开音频流的问题,使其注册。在我调用url.opnestream(stream)后,我得到了异常:

  

java.net.ProtocolException:意外的状态行:ICY 200 OK

我该如何解决?


以下是注册音频的示例,到目前为止我做了什么..

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;

3 个答案:

答案 0 :(得分:9)

针对Android 4.4进行了各种更改,似乎Android不支持非标准ShoutCast ICY标头。

似乎OkHttp好人在几天前已经解决了这个问题(issue 1issue 2)。 您可以做的是,只需在您的应用程序中直接使用OkHttp lib,然后您将使用较新的OkHttp版本(带有修复程序的版本)而不是Android附带的版本(您必须等待操作系统)更新)。
这也将修复您在其他可能遇到此问题的设备上运行的应用程序。

答案 1 :(得分:4)

Assaf Gamliel的答案为我工作。对于那些不熟悉此问题的人,您必须从okHttp下载最后一个.jar,从依赖项okio下载.jar。将它们添加到libs目录并按如下方式连接:

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

 Response response = client.newCall(request).execute();
 InputStream stream = response.body().byteStream();

答案 2 :(得分:-1)

最简单的解决办法。 这是100%为我工作, 对于shoutcast,请更改您的URL。 “http://192.168.1.1:9292”to“icy://192.168.1.1:9292” 你会没事的。