我正在尝试使用 Android 的 MediaPlayer 库流式传输音频。
在某些情况下,流 URL 是一个不寻常的端口。例如,http://203.150.225.77:8400
。如果我尝试从浏览器的防火墙后面访问此流,它会给我一个“糟糕!Google Chrome 无法连接到203.150.225.77:8400
”错误。
从我的 android 设备中的媒体播放器,我得到:MusicStream(1806): Media Player Error: Stream URL Invalid (1) -1004
目前,我只是在处理这个异常。但是,我希望能够在启动 MediaPlayer 之前预先测试 URL 以确定流是否可用。
因此,我创建了一个函数来使用 HttpURLConnection 测试 url,如下所示:
protected int isURLValid(MusicStream streamInstance, String urlString)
{
streamInstance.timeout = 0;
int success = 0;
try
{
URL url;
url = new URL(urlString);
HttpURLConnection urlConnection;
urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setConnectTimeout(1000);
urlConnection.setReadTimeout(1000);
urlConnection.getHeaderFields();
new Thread(new InterruptThread(Thread.currentThread(), urlConnection,streamInstance)).start();
if (streamInstance.timeout == 0)
{
success = 1;
}
}
catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Log.w("MusicStream", "MalformedURLException");
Log.w("MusicStream", e);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Log.w("MusicStream", "IOException");
Log.w("MusicStream", e);
} catch (Exception e) {
this.exception = e;
Log.w("MusicStream", "Exception");
Log.w("MusicStream", e);
}
return success;
}
正如您在上面的代码中看到的,我在 5000 毫秒后启动了一个新线程以超时。这是我的线程:
public class InterruptThread implements Runnable {
Thread parent;
URLConnection con;
MusicStream streamInstance;
public InterruptThread(Thread parent, URLConnection con, MusicStream streamInstance) {
this.parent = parent;
this.con = con;
this.streamInstance = streamInstance;
}
public void run() {
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
}
Log.d("MusicStream", "Timer thread forcing parent to quit connection");
((HttpURLConnection)con).disconnect();
Log.d("MusicStream","Timer thread closed connection held by parent, exiting");
streamInstance.timeout = 1;
}
}
尽管如此,当我引用我的函数时:
if (isURLValid(streamInstance[0],streamURL) == 1){
// Valid URL!
Log.d("MusicStream", "The stream is valid!");
this.ResultString = streamURL;
streamInstance[0].setFirewallError(MusicStream.GONE,streamURL);
}
else{
// Streaming URL invalid.
// Firewall Error
errorCode = MusicStream.FIREWALL_ERROR;
Log.d("MusicStream", "The stream is not valid!");
streamInstance[0].setFirewallError(MusicStream.VISIBLE,streamURL);
}
日志输出如下
A stream has been supplied: http://203.150.225.77:8400
The stream is valid!
MusicStream(1806): Media Player Error: Stream URL Invalid (1) -1004
一旦我将设备从无线切换到 3G,流媒体就可以工作了,所以我有点不知所措,为什么我的 url 检查机制在防火墙后面返回有效。任何人都可以看到为什么我的支票返回有效的任何原因,并可能就我如何以更简单的方式检查状态提出建议?
额外的想法:我在想也许某些防火墙会以“阻止”页面响应,在这种情况下获取标题将不起作用。但是,这里不是这种情况。