/*$Id$*/
package nicobrowser;
+import java.net.URI;
import java.net.URISyntaxException;
import java.util.Set;
import java.util.TreeMap;
import nicobrowser.util.Result;
import nicobrowser.util.Util;
import org.apache.commons.io.FilenameUtils;
+import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.http.HttpEntity;
import org.apache.http.cookie.Cookie;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;
+import org.apache.http.impl.client.RedirectLocations;
import org.apache.http.message.BasicNameValuePair;
+import org.apache.http.protocol.BasicHttpContext;
+import org.apache.http.protocol.HttpContext;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
* @throws java.io.IOException ファイル取得失敗. 権限の無いファイルを取得しようとした場合も.
*/
public VideoInfo getVideoInfo(String videoId) throws IOException {
- final GetRealVideoIdResult res = getRealVideoId(videoId);
+ final GetRealVideoIdResult res = accessWatchPage(videoId);
final String realVideoId = res.videoId;
String accessUrl = GET_FLV_INFO + realVideoId;
}
/**
- * watchページへアクセスし, ビデオIDを取得する.
- * soXXXXなど, 実際のビデオIDと異なる場合がある.
- * @param videoId 取得したいビデオのビデオID.
- * @return 実際のビデオID.
- * @throws IOException
- */
- private GetRealVideoIdResult getRealVideoId(String videoId) throws IOException {
- GetRealVideoIdResult res = accessWatchPage(videoId);
- final String realId = res.videoId;
-
- // ステータスコード302など、リダイレクトが必要な場合
- if (!videoId.equals(realId)) {
- res = getRealVideoId(realId);
- }
- return res;
- }
-
- /**
* WATCHページへアクセスする. getflvを行うためには, 必ず事前にWATCHページへアクセスしておく必要があるため.
- * @param videoId ビデオID.
- * @return
- * @throws IOException
+ * WATCHページ参照時にリダイレクトが発生する(so動画ではスレッドIDのWATCHページにリダイレクトされる)場合には
+ * そちらのページにアクセスし、そのスレッドIDをrealIdとして返します.
+ * @param videoId 取得したいビデオのビデオID.
+ * @return 実際のアクセスに必要なIDと、タイトル. タイトルはいんきゅばす互換用です.
+ * @throws IOException アクセスに失敗した場合. 有料動画などがこれに含まれます.
*/
private GetRealVideoIdResult accessWatchPage(String videoId) throws IOException {
String realId = videoId;
String title;
String watchUrl = WATCH_PAGE + videoId;
logger.debug("アクセス: " + watchUrl);
- http.getParams().setBooleanParameter(ClientPNames.HANDLE_REDIRECTS, false);
+ final HttpGet get = new HttpGet(watchUrl);
+ final HttpContext context = new BasicHttpContext();
+ final HttpResponse response = http.execute(get, context);
try {
- HttpGet get = new HttpGet(watchUrl);
- HttpResponse response = http.execute(get);
- try {
- if (response.containsHeader("Location")) {
- realId = response.getFirstHeader("Location").getValue().replace("/watch/", "");
+ final RedirectLocations rl = (RedirectLocations) context.getAttribute(
+ "http.protocol.redirect-locations");
+ // 通常の動画(sm動画など)はリダイレクトが発生しないためnullになる
+ if (rl != null) {
+ final List<URI> locations = rl.getAll();
+ logger.debug("リダイレクト数: " + locations.size());
+
+ // so動画はスレッドIDのページへリダイレクトされる
+ if (locations.size() == 1) {
+ realId = locations.get(0).toString().replace(WATCH_PAGE, "");
+ } else if (locations.size() > 1) {
+ throw new IOException("有料動画と思われるため処理を中断しました: " + ArrayUtils.toString(locations));
}
- title = getTitleInWatchPage(response.getEntity().getContent());
- } finally {
- response.getEntity().consumeContent();
}
+
+ title = getTitleInWatchPage(response.getEntity().getContent());
} finally {
- http.getParams().setBooleanParameter(ClientPNames.HANDLE_REDIRECTS, true);
+ response.getEntity().consumeContent();
}
return new GetRealVideoIdResult(realId, title);
}