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 チェック メカニズムが有効になって戻ってくる理由が少しわかりません。私の小切手が有効に戻った理由を誰かが見て、より確実な方法でステータスを確認する方法を提案してもらえますか?
補足: 一部のファイアウォールが「ブロックされた」ページで応答する可能性があると考えていました。その場合、ヘッダーの取得は機能しません。ただし、ここではそうではありません。