优酷视频真实地址最新解析方法 2011.11.08有效

最近掌上优酷的老用户说不能播放,那个是用网上公开的API和KEY写的,估计是优酷把那个KEY给封了(优酷没土豆大方,KEY不是普通人能申请得到的).因为优酷之前给各大市场发律师信,要求封杀掌上优酷,所以这里只做技术研究,掌上优酷还是不会再更新.
下面的代码是参考http://3shi.net/analyze-youku-video-address/ 写的,没有采用优酷的API,但是最近优酷又稍稍改了,原文的有些部分已经不适用,取到的地址不能再播放.
这段代码会优先取MP4格式的视频,没有MP4格式才取FLV格式.需要使用org.json


package com.test;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

public class Main
{

	public static void main(String[] args) throws Exception
	{
		String id="XMzE3OTQ0Nzk2";
		String s = Common.getHtml("http://v.youku.com/player/getPlayList/VideoIDS/"+id);
		JSONObject jsobj = new JSONObject(s);
		JSONArray jsonarr = jsobj.getJSONArray("data");
		JSONObject obj1 = jsonarr.getJSONObject(0);
		double seed = obj1.getDouble("seed");
		JSONObject obj2 = obj1.getJSONObject("streamfileids");
		String mp4id = null;
		String flvid = null;
		String format = null;
		try
		{
			mp4id = obj2.getString("mp4");
			format = "mp4";
		} catch (JSONException e)
		{
			System.out.println("没有MP4格式");
			try
			{
				flvid = obj2.getString("flv");
				format = "flv";
			} catch (JSONException e1)
			{
				System.out.println("没有FLV格式");
				return;
			}
		}

		String realfileid = null;
		if (format.equals("mp4"))
		{
			realfileid = getFileID(mp4id, seed);
		} else
		{
			realfileid = getFileID(flvid, seed);
		}
		String idLeft = realfileid.substring(0, 8);
		String idRight = realfileid.substring(10);

		String sid = genSid();
		JSONObject obj3 = obj1.getJSONObject("segs");
		JSONArray mp4arr = obj3.getJSONArray(format);
		for (int i = 0; i < mp4arr.length(); i++)
		{
			JSONObject o = mp4arr.getJSONObject(i);
			String k = o.getString("k");
			String url = "http://f.youku.com/player/getFlvPath/sid/" + sid + "_" + String.format("%1$02X", i) + "/st/" + format
					+ "/fileid/" + idLeft + String.format("%1$02X", i) + idRight + "?K=" + k;
			System.out.println(url);
		}

	}

	private static 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();
	}

	public static String genSid()
	{
		int i1 = (int) (1000 + Math.floor(Math.random() * 999));
		int i2 = (int) (1000 + Math.floor(Math.random() * 9000));
		return System.currentTimeMillis() + "" + i1 + "" + i2;
	}

	private static 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();
	}

}

© 2011, 冰冻鱼. 请尊重作者劳动成果,复制转载保留本站链接! 应用开发笔记