From a5617fa9e8e77cf6016a7613a1ed22bb6f34958c Mon Sep 17 00:00:00 2001 From: yuki Date: Mon, 1 Feb 2010 13:38:34 +0000 Subject: [PATCH] =?utf8?q?VideoInfo=E3=82=AF=E3=83=A9=E3=82=B9=E8=BF=BD?= =?utf8?q?=E5=8A=A0=E3=80=82=20=E3=83=A1=E3=82=BD=E3=83=83=E3=83=89?= =?utf8?q?=E7=B4=B0=E5=88=86=E5=8C=96=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit git-svn-id: http://192.168.11.7/svn/repository/NicoBrowser/branches/dev20100201_comment_download@274 bdf3b611-c98c-6041-8292-703d9c9adbe7 --- src/nicobrowser/NicoHttpClient.java | 99 +++++++++++++++++++------------- src/nicobrowser/VideoInfo.java | 63 ++++++++++++++++++++ test/nicobrowser/NicoHttpClientTest.java | 16 +++++- 3 files changed, 135 insertions(+), 43 deletions(-) create mode 100644 src/nicobrowser/VideoInfo.java diff --git a/src/nicobrowser/NicoHttpClient.java b/src/nicobrowser/NicoHttpClient.java index 6af84a8..6267c92 100644 --- a/src/nicobrowser/NicoHttpClient.java +++ b/src/nicobrowser/NicoHttpClient.java @@ -20,11 +20,12 @@ import java.io.InputStreamReader; import java.io.Reader; import java.io.StringReader; import java.net.URL; -import java.net.URLDecoder; import java.util.ArrayList; import java.util.Arrays; import java.util.Enumeration; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.regex.Pattern; import javax.swing.text.MutableAttributeSet; import javax.swing.text.html.HTML; @@ -69,6 +70,7 @@ public class NicoHttpClient { "https://secure.nicovideo.jp/secure/login?site=niconico"; private static final String LOGOUT_PAGE = "https://secure.nicovideo.jp/secure/logout"; + private static final String WATCH_PAGE = "http://www.nicovideo.jp/watch/"; private static final String MY_LIST_PAGE_HEADER = "http://www.nicovideo.jp/mylist/"; private static final String MOVIE_THUMBNAIL_PAGE_HEADER = @@ -466,13 +468,15 @@ public class NicoHttpClient { * 一度http://www.nicovideo.jp/watch/ビデオIDに一度アクセスする必要があることに * 注意. * (参考: http://yusukebe.com/tech/archives/20070803/124356.html) - * @param videoID ニコニコ動画のビデオID. + * @param videoId ニコニコ動画のビデオID. * @return FLVファイル実体があるURL. * @throws java.io.IOException ファイル取得失敗. 権限の無いファイルを取得しようとした場合も. */ - public URL getFlvUrl(String videoID) throws IOException { - String accessUrl = GET_FLV_INFO + videoID; - if (videoID.startsWith("nm")) { + public VideoInfo getVideoInfo(String videoId) throws IOException { + final String realVideoId = getRealVideoId(videoId); + + String accessUrl = GET_FLV_INFO + realVideoId; + if (realVideoId.startsWith("nm")) { accessUrl += "?as3=1"; } log.debug("アクセス: " + accessUrl); @@ -497,22 +501,53 @@ public class NicoHttpClient { } } - String[] urls = resultString.split("&"); - final String marker = "url="; - for (String url : urls) { - if (url.contains(marker)) { - String result = url.substring(marker.length()); - result = URLDecoder.decode(result, "UTF-8"); + String[] params = resultString.split("&"); +// final String marker = "url="; + Map map = new HashMap(); + for (String param : params) { + String[] elm = param.split("="); + map.put(elm[0], elm[1]); + // if (url.contains(marker)) { + // String result = url.substring(marker.length()); + // result = URLDecoder.decode(result, "UTF-8"); + // + // return new URL(result); + // } + } +// throw new IOException("ダウンロードに失敗しました(削除済みの可能性もあります)。 ID: " + videoID + ", パラメータ:" + resultString); + return new VideoInfo(realVideoId, map); + } - return new URL(result); + private String getRealVideoId(String videoId) throws IOException { + String watchUrl = WATCH_PAGE + videoId; + log.debug("アクセス: " + watchUrl); + http.getParams().setBooleanParameter(ClientPNames.HANDLE_REDIRECTS, false); + try { + HttpGet get = new HttpGet(watchUrl); + HttpResponse response = http.execute(get); + String realID = videoId; + + // ステータスコード302など、リダイレクトが必要な場合 + if (response.containsHeader("Location")) { + realID = response.getFirstHeader("Location").getValue().replace("/watch/", ""); + response.getEntity().consumeContent(); + watchUrl = WATCH_PAGE + realID; + log.debug("アクセス: " + watchUrl); + HttpGet watchGet = new HttpGet(watchUrl); + HttpResponse watchResponse = http.execute(get); + watchResponse.getEntity().consumeContent(); + } else { + response.getEntity().consumeContent(); } + return realID; + } finally { + http.getParams().setBooleanParameter(ClientPNames.HANDLE_REDIRECTS, true); } - throw new IOException("ダウンロードに失敗しました(削除済みの可能性もあります)。 ID: " + videoID + ", パラメータ:" + resultString); } /** * ニコニコ動画から動画ファイルをダウンロードする. - * @param videoID smxxxx形式のビデオID. + * @param videoId smxxxx形式のビデオID. * @param fileName ダウンロード後のファイル名. 拡張子は別途付与されるため不要. * @param nowStatus ダウンロードしようとしている動画ファイルの, 現在のステータス. * @param needLowFile エコノミー動画をダウンロードするのであればtrue. @@ -522,37 +557,19 @@ public class NicoHttpClient { public GetFlvResult getFlvFile(String videoID, String fileName, Status nowStatus, boolean needLowFile) throws IOException, URISyntaxException, HttpException, InterruptedException { - String watchUrl = "http://www.nicovideo.jp/watch/" + videoID; - log.debug("アクセス: " + watchUrl); - http.getParams().setBooleanParameter(ClientPNames.HANDLE_REDIRECTS, false); - HttpGet get = new HttpGet(watchUrl); - HttpResponse response = http.execute(get); - String realID = videoID; - - // ステータスコード302など、リダイレクトが必要な場合 - if (response.containsHeader("Location")) { - realID = response.getFirstHeader("Location").getValue().replace("/watch/", ""); - response.getEntity().consumeContent(); - watchUrl = "http://www.nicovideo.jp/watch/" + realID; - log.debug("アクセス: " + watchUrl); - get = new HttpGet(watchUrl); - response = http.execute(get); - } - http.getParams().setBooleanParameter(ClientPNames.HANDLE_REDIRECTS, true); + VideoInfo vi = getVideoInfo(videoID); - final URL notifierUrl = Util.getNotifierUrl(response.getEntity().getContent()); - log.debug("違反通報ページ: " + notifierUrl); - response.getEntity().consumeContent(); + final URL notifierUrl = vi.getSmileUrl(); String userName = null; if (notifierUrl != null) { - get = new HttpGet(notifierUrl.toString()); - response = http.execute(get); + HttpGet get = new HttpGet(notifierUrl.toString()); + HttpResponse response = http.execute(get); userName = Util.getUserName(response.getEntity().getContent()); response.getEntity().consumeContent(); } - URL url = getFlvUrl(realID); + final URL url = vi.getVideoUrl(); if (nowStatus == Status.GET_LOW || !needLowFile) { if (url.toString().contains("low")) { log.info("エコノミー動画のためスキップ: " + videoID); @@ -560,8 +577,8 @@ public class NicoHttpClient { } } - get = new HttpGet(url.toURI()); - response = http.execute(get); + HttpGet get = new HttpGet(url.toURI()); + HttpResponse response = http.execute(get); String contentType = response.getEntity().getContentType().getValue(); log.debug(contentType); log.debug(fileName); @@ -598,7 +615,7 @@ public class NicoHttpClient { /** * ニコニコ動画から動画ファイルをダウンロードする. - * @param videoID smxxxx形式のビデオID. + * @param videoId smxxxx形式のビデオID. * @param fileName ダウンロード後のファイル名. 拡張子は別途付与されるため不要. * @return この処理を行った後の, 対象ファイルのステータス. * @throws java.io.IOException ファイル取得失敗. 権限の無いファイルを取得しようとした場合も. @@ -611,7 +628,7 @@ public class NicoHttpClient { /** * ニコニコ動画から動画ファイルをダウンロードする. * ファイル名はビデオID名となる. - * @param videoID smxxxx形式のビデオID. + * @param videoId smxxxx形式のビデオID. * @return この処理を行った後の, 対象ファイルのステータス. * @throws java.io.IOException ファイル取得失敗. 権限の無いファイルを取得しようとした場合も. */ diff --git a/src/nicobrowser/VideoInfo.java b/src/nicobrowser/VideoInfo.java new file mode 100644 index 0000000..b0ae4e9 --- /dev/null +++ b/src/nicobrowser/VideoInfo.java @@ -0,0 +1,63 @@ +/* $Id$ */ +package nicobrowser; + +import java.net.URL; +import java.net.URLDecoder; +import java.util.Map; + +/** + * + * @author yuki + */ +public class VideoInfo { + + private final String realVideoId; + private final String threadId; + private final URL videoUrl; + private final URL messageUrl; + private final URL smileUrl; +// private final String userId; + private final int videoLength; + private static final String KEY_THREAD_ID = "thread_id"; + private static final String KEY_URL = "url"; + private static final String KEY_MESSAGE_URL = "ms"; + private static final String KEY_SMILE_LINK = "link"; + private static final String KEY_VIDEO_LENGTH = "l"; + + public VideoInfo(String realVideoId, Map getflvReceivedMap) { + try { + this.realVideoId = realVideoId; + threadId = getflvReceivedMap.get(KEY_THREAD_ID); + videoUrl = new URL(URLDecoder.decode(getflvReceivedMap.get(KEY_URL), "UTF-8")); + messageUrl = new URL(URLDecoder.decode(getflvReceivedMap.get(KEY_MESSAGE_URL), "UTF-8")); + smileUrl = new URL(URLDecoder.decode(getflvReceivedMap.get(KEY_SMILE_LINK), "UTF-8")); + videoLength = Integer.parseInt(getflvReceivedMap.get(KEY_VIDEO_LENGTH)); + } catch (Exception e) { + throw new IllegalArgumentException(e); + } + } + + public String getRealVideoId() { + return realVideoId; + } + + public URL getMessageUrl() { + return messageUrl; + } + + public URL getSmileUrl() { + return smileUrl; + } + + public String getThreadId() { + return threadId; + } + + public int getVideoLength() { + return videoLength; + } + + public URL getVideoUrl() { + return videoUrl; + } +} diff --git a/test/nicobrowser/NicoHttpClientTest.java b/test/nicobrowser/NicoHttpClientTest.java index 2aa0445..ab5db0b 100644 --- a/test/nicobrowser/NicoHttpClientTest.java +++ b/test/nicobrowser/NicoHttpClientTest.java @@ -55,6 +55,7 @@ public class NicoHttpClientTest { /** * Test of login method, of class NicoHttpClient. */ + @Test public void login() throws HttpException, URISyntaxException, InterruptedException { System.out.println("login"); @@ -85,6 +86,7 @@ public class NicoHttpClientTest { assertEquals(true, result); } + @Test public void loadMyList() throws URISyntaxException, HttpException, InterruptedException { System.out.println("loadMyList"); @@ -138,12 +140,13 @@ public class NicoHttpClientTest { } - public void getFlvUrl() throws URISyntaxException, HttpException, InterruptedException, IOException { + @Test + public void getVideoInfo() throws URISyntaxException, HttpException, InterruptedException, IOException { System.out.println("getFlv"); instance.login(OK_MAIL, OK_PASS); try { - URL str = instance.getFlvUrl("sm1359820"); + URL str = instance.getVideoInfo("sm1359820").getVideoUrl(); System.out.println(str); } catch (IOException ex) { fail(); @@ -153,6 +156,15 @@ public class NicoHttpClientTest { } @Test + public void getVideoInfo_Official() throws URISyntaxException, HttpException, InterruptedException, IOException { + System.out.println("getVideoInfo_Official"); + instance.login(OK_MAIL, OK_MAIL); + final String OFFICIAL_VIDEO = "so8799877"; + VideoInfo vi = instance.getVideoInfo(OFFICIAL_VIDEO); + assertNotSame(OFFICIAL_VIDEO, vi.getRealVideoId()); + } + + @Test public void downLoad() throws URISyntaxException, IOException, HttpException, InterruptedException { System.out.println("downLoad"); -- 2.11.0