细说《优酷视频真实地址解析》


  直接链接优酷(youku)的视频地址制作播放器,应该是很吸引人的,同时也有不少麻烦。
  早几天发了一帖,讲了一下基本情况。有兴趣的话,请先看一下。于下。已发的内容、重复的话就不说了。
  http://bbs.voc.com.cn/topic-3803611-1-1.html

  下面的播放器是实际应用。为检验效果,选用了《拳霸1之盗佛线》。
  该视频分割为七“集”,每集又分为三个片段。其中1、2、3、5、6集备有双格式(mp4和flv,即高清和标清),4、7集仅有flv标清格式。这样,各种情况都包括进来了,具有代表性,较能说明问题。



http://f.youku.com/player/getFlvPath/sid/00_00/st/mp4/fileid/
03000803004D9F4390A67E002BCF4E9F3D1FCE-FB5D-561B-1A73-F791EE1DC9B3
?K=3c1817963398751b2827379d
  这是视频文件链接的标准式样。白色字符是需更换的内容。
03000803004D9F4390A67E002BCF4E9F3D1FCE-FB5D-561B-1A73-F791EE1DC9B3
  这一串字符由解密计算得到,“00”处是多片段节目的序号,为16进制。一个页面的节目无论多少段,每段的链接地址中的这一部分是相同的。

http://v.youku.com/v_show/id_XMjU3MzIxOTk2.html
  这是节目所在页面的地址,其中白色字符为节目的“编号”或叫“标志”应该都可以。所有关于节目的信息都是从这里得到的。

http://v.youku.com/player/getPlayList/VideoIDS/XMjU3MzIxOTk2
  
节目的信息文件的地址。贴到地址栏可以看到内容,下载后成为一个文本文件。
  该文件内容为哈希表(json)格式,网上可方便查找到相关资料,flash的帮助里面也有介绍。这里不详述,恐篇幅太大。
  脚本编程中,用地址读入此信息文件的内容,然后根据内容得到或计算(解密)得到需要的东西,最后拼接出完整的视频文件地址。
  信息文件中的内容总是变化的,据网上资料介绍,仅维持一小时(未验证)。

  根据前帖所述资料介绍的方法,未能成功还原出视频地址。经反复尝试,对比,剖析优酷网站播放器的脚本,终于正确解密了地址。优酷网实在是用心良苦。

  下面列出脚本编程关于解密部分的内容。

①加载信息文件,将内容转换为字符串。加载需要时间,此事很容易上当。如果加载未完成,很容易造成后面读不到数据,报错。
stop();
mysongs.load ("http://v.youku.com/player/getPlayList/VideoIDS/" + page[p]);
mysongs.onLoad = function (success)
{
  if (success) {
    jsonstring = mysongs.toString ();
  }
  play ();
};

②更换非正常字符码,利用json类文件,将字符串处理为哈希表格式,以便使用。
jsonstring = jsonstring.split (""").join ('"');
var json:JSON = new JSON ();
var jsonobj:Object = json.parse (jsonstring);    //字符串转哈希表;
var _seed = jsonobj.data[0].seed;        //此值将参与解密计算; 
var _key;                   //省去此值计算,直接读取; 
var len;                    //片段数;
var fileid;                   //此值将参与解密计算; 
var format;                  //视频格式字符;
if (jsonobj.data[0].segs.mp4) {
  _key = jsonobj.data[0].segs.mp4[i].k;
  len = jsonobj.data[0].segs.mp4.length;
  fileid = jsonobj.data[0].streamfileids.mp4;
  format = "mp4";
}
else {
  _key = jsonobj.data[0].segs.flv[i].k;
  len = jsonobj.data[0].segs.flv.length;
  fileid = jsonobj.data[0].streamfileids.flv;
  format = "flv";
}

③解密过程
var mixed:String;
var realId:String;
function getFileID (fileid)
{
  getFileIDMixString ();
  var ids = fileid.split ("*");
  realId = "";
  for (var j = 0; j < ids.length - 1; ++j) {
    realId = realId + mixed.charAt (parseInt (ids[j]));
  }
  //return realId.toString ();
}
getFileID (fileid);
//+++++++++++++++++++++++++++++++
function ran ()
{
  _seed = (_seed * 211 + 30031) % 65536;
  return (_seed / 65536);
}
//+++++++++++++++++++++++++++++++
function getFileIDMixString ()
{
  mixed = "";
  var _source = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ/\\:._-1234567890";
  var len = _source.length;
  for (var i = 0; i < len; ++i) {
    var index = int (this.ran () * _source.length);
    mixed = mixed + _source.charAt (index);
    _source = _source.split (_source.charAt (index)).join ("");
  }
}
//+++++++++++++++++++++++++++++++++++以下拼接出完整地址++++++++++
var II = String (i).length < 2 ? "0" + i : i;
var temp1 = realId.slice (0, 8);
var temp2 = realId.slice (10);
var temp0 = temp1 + II + temp2;
var vlist = [];
vlist[0] = "http://f.youku.com/player/getFlvPath/sid/00_00/st/" + format + "/fileid/" + temp0 + "?K=" + _key;
trace (vlist[0]);   //完整地址。注意时效。

  一些说明。
  1、对比网上资料介绍,上面的做法省去了两个计算。
    ⑴、随机数
    参考来自“硕鼠”给出的地址,实例证实,这样也可以;
    ⑵、K值的计算
    在信息文件中,已有此值。实例证实,不必再用k1与k2计算得到K。
  2、加密的方法和数据,优酷很可能改动。现在的效果不敢说能保永久。如果有了变故,还是解析优酷播放器自身的制作为好,这是万能法宝。
  3、json.as文件,可从优酷的共享F8版播放器中反编得到,放在编辑文件同路径下即可。用记事本打开文件,删除类(class)的路径。
  4、从F8的反编文件VideoController.as中可查阅到解密内容。
  5、从网站页面的F9版播放器的反编文件PlayListProxy.as中可查阅到解密内容。

  制作到此可告一段落,需要完善的地方还很多。欢迎大家多多讨论、指教。