Come see how JAVA implements Youku video address (parsing sample code to share)

I recently made an online video downloader, and need to parse the youku video to get the real video address. Now record the parsing process for reference

An example is better to understand. For example, I am going to download http://v.youku.com/v_show/id_XNDM2Mjc0MzAw.html this video. What we want to get here is the id of the video, which is the part of XNDM2Mjc0MzAw, which is unique to a video, so it will definitely be used when parsing.

In order to see the playback process of youku video clearly, you can use the Firefox plug-in firebug to track the webpage, as shown in the figure below.

image.png

You can see that there are many GETs. What we are looking for should be GET with this id as a parameter. Below we can find this link
http://v.youku.com/player/getPlayList/VideoIDS/XNDM2Mjc0MzAw/timezone/+08 /version/5/source/video?ran=3545&password=&n=3
This is the GET for youku to get the playlist and the response to open it. This is a json. The content we need is seed, streamfileids and segs. The segment key of the video is put in the segs, and the streamfileids are a bunch of garbled codes, which need to be decoded with the seed. Below I have intercepted a part of the downloader to illustrate the decoding process. The parsing json is json-lib-2.4-jdk15.


List<Video> videos = new ArrayList<Video>();
JSONObject data;
//json就是刚获得的响应,类型为String。
data = JSONObject.fromObject(json).getJSONArray("data").getJSONObject(0);
double seed = Double.valueOf(data.getString("seed"));
String title = data.getString("title");
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");//segs部分解析
for (Iterator iterator = segs.iterator(); iterator.hasNext();) {
    JSONObject object = (JSONObject) iterator.next();
    int order = object.getInt("no");
    String size = object.getString("size");
    int seconds = object.getInt("seconds");
    String key = object.getString("k");
    String no = String.format("%1$02x", order);
    String youUrl = "http://f.youku.com/player/getFlvPath/sid/" + "00_"
        + no + "/st/flv/fileid/" + fileid1 + no + fileid2 + "?K="
        + key;          
    videos.add(new Video(order, seconds, youUrl, size, key, title));
}

youUrl is the video address we want. For example, the first paragraph of the video above is:

http://f.youku.com/player/getFlvPath/sid/134434081131213125530_00/st/flv/fileid/030001090050201D77EDBC04650AC2DD6027D5-ED5F-27F6-8E73-DEF478121887&K=b499f3d5df944cfc2827e2ec

The blue one is randomly generated and can be replaced by 00.
flv indicates the video format to be downloaded, or mp4, if available.
The two yellow 00s are segment codes, hexadecimal, for example, the first segment is 00, the second segment is 01, and the fifteenth segment is 0f.
The latter is the fileid, which needs to be cracked by seed and streamfileids, every video is the same.
The last K is obtained in segs and does not need to be cracked. Each video is different.

The two decoding functions are:


private String getFileID(String fileid, double seed) {
    String mixed = 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));
    }
    return realId.toString();
}

private String getFileIDMixString(double seed) {
    StringBuilder mixed = new StringBuilder();
    StringBuilder source = new StringBuilder(
        "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ/\\:._-1234567890");
    int index, len = source.length();
    for (int i = 0; i < len; ++i) {
        seed = (seed * 211 + 30031) % 65536;
        index = (int) Math.floor(seed / 65536 * source.length());
        mixed.append(source.charAt(index));
        source.deleteCharAt(index);
    }
    return mixed.toString();
}

private String getFileID(String fileid, double seed) {
    String mixed = 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));
    }
    return realId.toString();
}

private String getFileIDMixString(double seed) {
    StringBuilder mixed = new StringBuilder();
    StringBuilder source = new StringBuilder(
        "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ/\\:._-1234567890");
    int index, len = source.length();
    for (int i = 0; i < len; ++i) {
        seed = (seed * 211 + 30031) % 65536;
        index = (int) Math.floor(seed / 65536 * source.length());
        mixed.append(source.charAt(index));
        source.deleteCharAt(index);
    }
    return mixed.toString();
}

The code will finally get a List of Video type. The order in Video is the number of the video, seconds is the length of time, size is the length of bytes, youUrl is the real video address, and the title of the video. There are some other content that can be obtained from json.

The latest high-frequency interview questions collected in 2021 (all organized into documents), there are a lot of dry goods, including mysql, netty, spring, thread, spring cloud, jvm, source code, algorithm and other detailed explanations. There are also detailed learning plans and interviews. Questions, etc., friends who need to obtain these content, please add Q Junyang: 547998459

The above is the whole content of this article. If you need more information, please contact me. I hope it will be helpful to everyone's study, and I hope you can support me.

Guess you like

Origin blog.csdn.net/p1830095583/article/details/114527833