예를 들어, http://v.youku.com/v_show/id_XNDM2Mjc0MzAw.html 비디오를 다운로드하고 싶습니다. 여기서 얻고자 하는 것은 비디오의 ID, 즉 XNDM2Mjc0MzAw 부분입니다. 이는 비디오에 고유하므로 구문 분석 시 반드시 사용됩니다.
Youku 비디오의 재생 과정을 명확하게 보려면 아래와 같이 Firefox 플러그인 Firebug를 사용하여 웹 페이지를 추적할 수 있습니다.
우리가 찾고 있는 것은 이 ID를 매개변수로 갖는 GET이어야 합니다. 아래에서 이 링크를 찾을 수 있습니다.
http://v.youku.com/player/getPlayList/VideoIDS/XNDM2Mjc0MzAw/timezone/+08/version/5/source/video?ran=3545&password=&n=3
이것은 재생 목록을 가져오고 해당 응답을 여는 youku의 GET입니다. 필요한 콘텐츠는 시드, 스트림 파일 ID 및 세그먼트입니다. Segs에는 비디오의 분할 키가 포함되어 있고 streamfileids는 잘못된 문자로 이루어진 문자열이며 시드를 사용하여 디코딩해야 합니다. 아래에서는 디코딩 프로세스를 설명하기 위해 다운로더의 일부를 가로채었습니다. json-lib-2.4-jdk15는 json을 구문 분석하는 데 사용됩니다.
다음과 같이 코드 코드를 복사합니다.
List<Video> 비디오 = new ArrayList<Video>();
JSONObject 데이터;
//json은 방금 얻은 응답이며 유형은 String입니다.
data = JSONObject.fromObject(json).getJSONArray("data").getJSONObject(0);
이중 시드 = Double.valueOf(data.getString("seed"));
문자열 제목 = data.getString("제목");
String fileid = data.getJSONObject("streamfileids").getString("flv");//mp4 형식으로 다운로드하려는 경우
String realFileid = getFileID(fileid, seed); //flv를 mp4로 변경합니다(이 노드가 존재하는 경우).
String fileid1 = realFileid.substring(0, 8);//디코딩된 id는 두 부분으로 나뉘며, 중간에 비디오 세그먼트를 삽입해야 합니다.
String fileid2 = realFileid.substring(10);
JSONArray segs = data.getJSONObject("segs").getJSONArray("flv");//세그먼트의 부분 구문 분석
for (반복자 iterator = segs.iterator(); iterator.hasNext();) {
JSONObject 객체 = (JSONObject) iterator.next();
int order = object.getInt("no");
문자열 크기 = object.getString("size");
int 초 = object.getInt("초");
문자열 키 = object.getString("k");
String no = String.format("%1$02x", order);
문자열 youUrl = "http://f.youku.com/player/getFlvPath/sid/" + "00_"
+ 아니요 + "/st/flv/fileid/" + fileid1 + no + fileid2 + "?K="
+ 키;
videos.add(새 동영상(순서, 초, youUrl, 크기, 키, 제목));
}
youUrl은 우리가 원하는 비디오 주소입니다. 예를 들어 위 비디오의 첫 번째 단락은 다음과 같습니다.
http://f.youku.com/player/getFlvPath/sid/134434081131213125530_00/st/flv/fileid/030001 090050201D77EDBC04650AC2DD6027D5-ED5F-27F6-8E73-DEF478121887&K=b499f3d5df944cfc2827e2ec
파란색은 무작위로 생성되며 00으로 대체 가능합니다.
flv는 다운로드할 비디오 형식을 나타내며, 가능한 경우 mp4를 선택할 수도 있습니다.
두 개의 노란색 00은 16진수 세그먼트 코드입니다. 예를 들어 첫 번째 세그먼트는 00, 두 번째 세그먼트는 01, 15번째 세그먼트는 0f입니다.
다음은 fileid인데, 이것은 seed와 streamfileids를 통해 크랙되어야 합니다. 이는 모든 비디오에서 동일합니다.
마지막 K는 세그먼트별로 얻어지며, 크랙할 필요가 없으며 각 비디오가 다릅니다.
두 가지 디코딩 기능은 다음과 같습니다.
다음과 같이 코드 코드를 복사합니다.
private String getFileID(String fileid, 이중 시드) {
문자열 혼합 = getFileIDMixString(seed);
String[] ids = fileid.split("//*");
StringBuilder realId = new StringBuilder();
int idx;
for (int i = 0; i < ids.length; i++) {
idx = Integer.parseInt(ids[i]);
realId.append(mixed.charAt(idx));
}
realId.toString()을 반환합니다.
}
개인 문자열 getFileIDMixString(이중 시드) {
StringBuilder 혼합 = 새로운 StringBuilder();
StringBuilder 소스 = 새 StringBuilder(
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ///:._-1234567890");
int 인덱스, len = source.length();
for (int i = 0; i < len; ++i) {
시드 = (시드 * 211 + 30031) % 65536;
index = (int) Math.floor(seed / 65536 * source.length());
Mixed.append(source.charAt(index));
source.deleteCharAt(index);
}
혼합.toString()을 반환합니다.
}
코드는 최종적으로 비디오 유형 목록을 가져옵니다. 비디오의 순서는 비디오 번호, 초는 시간 길이, 크기는 바이트 길이, youUrl은 실제 비디오 주소 및 비디오 제목입니다. json에서 얻을 수 있는 다른 내용도 있습니다.