您的位置:首页 > 其它

优酷视频解析

2015-07-19 09:09 417 查看
每次在网页上点开优酷的视频播放,我们可以再地址栏得到一个地址如下:

http://v.youku.com/v_show/id_XMTI4NDE5NjQwNA==.html

提取上面的地址中的 XMTI4NDE5NjQwNA,我们称为vid

可以通过如下代码得到:

public static String getSuffix(String url){
        String suffix="";
        // ~~~正则表达式 ,匹配以id_开始的后面的所有字类字符,非字符就不匹配,实际上字符串是(?<=id_)(\w+)
        String strRegex = "(?<=id_)(\\w+)";
        Pattern pat = Pattern.compile(strRegex);
        Matcher mat = pat.matcher(url);
        //System.out.println(mat.matches());
        mat.find();
        for(int i=1;i<=mat.groupCount();i++){
            suffix+=mat.group(i).toString();
            //System.out.println(mat.group(i));
        }
        return suffix;
    }


我们可以得到:

http://v.youku.com/player/getPlayList/VideoIDS/XMTI4NDE5NjQwNA/Pf/4/ctype/12/ev/1

访问这个链接我们可以得到json数据,在json数据中我们需要的是

ip":974409714,"ep":"NgXTSQ8YIbPS0fjA8eJxVYn3sBdr1wvJXBg=",这个两个东西

然后通过如下代码得到

(此代码的算法还不清晰,需要进一步研究)

private static String myEncoder(String a,byte[]c,boolean isToBase64){
String result = "";
ArrayList<Byte> bytesR = new ArrayList<Byte>();
//List<byte> bytesR = new List<byte>();
int f = 0, h = 0, q = 0;
int[] b = new int[256];
for (int i = 0; i < 256; i++)
b[i] = i;
while (h < 256)
{
f = (f + b[h] + a.charAt(h % a.length())) % 256;
int temp = b[h];
b[h] = b[f];
b[f] = temp;
h++;
}
f = 0; h = 0; q = 0;
while (q < c.length)
{
h = (h + 1) % 256;
f = (f + b[h]) % 256;
int temp = b[h];
b[h] = b[f];
b[f] = temp;
byte[] bytes = new byte[] { (byte)(c[q] ^ b[(b[h] + b[f]) % 256]) };
bytesR.add(new Byte(bytes[0]));
result += Base64Code.DeCode(bytes);
//result += System.Text.ASCIIEncoding.ASCII.GetString(bytes);
q++;
}
if (isToBase64)
{
Byte [] byteR = new Byte[bytesR.size()];
for(int i=0;i<bytesR.size();i++){
byteR[i]=bytesR.get(i).byteValue();
}

byte[] bytes = new byte[byteR.length];
for(int i=0;i<byteR.length;i++){
bytes[i]=byteR[i].byteValue();
}
result = Base64Code.EnCode(bytes);
//result = Convert.ToBase64String(byteR);
}
return result;
}

public static String pNew ,token,sid;
public static void getEp(String vid, String ep)
{
String template1 = "becaf9be";
String template2 = "bf7e5f01";
//System.out.println(ep.length());
byte[] bytes = Base64Code.FromBase64String(ep);
ep = Base64Code.DeCode(bytes);
String temp = myEncoder(template1, bytes, false);
String[] part = temp.split("_");
sid = part[0];
token = part[1];
String whole = sid+"_"+vid+"_"+token;
byte[] newbytes = Base64Code.getBytes(whole);
pNew = myEncoder(template2, newbytes, true);
}


Algorithm.pNew,       token=Algorithm.token,       sid= Algorithm.sid;

然后令ep1 = URLEncoder.encode(Algorithm.pNew, "UTF-8");

拼接如下M3u8链接:

String http="http://pl.youku.com/playlist/m3u8?ctype=12&ep="+ep1+

                "&ev=1&keyframe=1&oip="+ip+"&sid="+sid+"&token="+token+"&type=mp4&vid="+vid;

然后得到一个M3u8文件,里面得到视频的链接,分成一段一段,取每一部分前面的链接,得到很多大概6分钟组成的真是的播放地址

由于真是的播放地址有时间的限制,所以就不贴出来了,部分M3u8文件如下:

#EXTM3U
#EXT-X-TARGETDURATION:12
#EXT-X-VERSION:3
#EXTINF:5.12, http://221.203.1.206/6775BB728E04C83D4251234999/0300080100535E50A013E405C062B8C137EC48-84DA-E0C1-CB15-821FE4249365.mp4.ts?ts_start=0&ts_end=5.02&ts_seg_no=0&ts_keyframe=1 #EXTINF:4.28, http://221.203.1.206/6775BB728E04C83D4251234999/0300080100535E50A013E405C062B8C137EC48-84DA-E0C1-CB15-821FE4249365.mp4.ts?ts_start=5.02&ts_end=9.3&ts_seg_no=1&ts_keyframe=1 #EXTINF:5.08, http://221.203.1.206/6775BB728E04C83D4251234999/0300080100535E50A013E405C062B8C137EC48-84DA-E0C1-CB15-821FE4249365.mp4.ts?ts_start=9.3&ts_end=14.38&ts_seg_no=2&ts_keyframe=1 #EXTINF:11.72, http://221.203.1.206/6775BB728E04C83D4251234999/0300080100535E50A013E405C062B8C137EC48-84DA-E0C1-CB15-821FE4249365.mp4.ts?ts_start=14.38&ts_end=26.1&ts_seg_no=3&ts_keyframe=1 #EXTINF:11.8, http://221.203.1.206/6775BB728E04C83D4251234999/0300080100535E50A013E405C062B8C137EC48-84DA-E0C1-CB15-821FE4249365.mp4.ts?ts_start=26.1&ts_end=37.9&ts_seg_no=4&ts_keyframe=1 #EXTINF:11.64, http://221.203.1.206/6775BB728E04C83D4251234999/0300080100535E50A013E405C062B8C137EC48-84DA-E0C1-CB15-821FE4249365.mp4.ts?ts_start=37.9&ts_end=49.54&ts_seg_no=5&ts_keyframe=1 #EXTINF:11.96,


另外上面的编码用到了自己写的Base64编码,贴出来

package com.nmbb.oplayer.vke;

public class Base64Code {
    
    private final static String table=
            "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
    
    // ~~~比特转二进制
    public static String ByteToBinary(byte ch){
        String res="";
        for(int i=7;i>=0;i--){
            res+=((ch>>i)&1);
        }
        return res;
    }
    
    
    // ~~~01串转64编码
    public static String BinaryToBase64(String src){
        int index=0;
        String res="";
        for(int i=0;i<src.length();i++){
            index=index*2+(src.charAt(i)-'0');
            if((i+1)%6==0){
                res+=table.charAt(index);
                index = 0;
            }
        }
        return res;
    }
    // ~~~加密
    public static String EnCode(byte bytes []){
        String res = "",temp = "";
        for(int i=0;i<bytes.length;i+=3){
            if(i+2<bytes.length){
                temp = ByteToBinary(bytes[i]);
                temp+=ByteToBinary(bytes[i+1]);
                temp+=ByteToBinary(bytes[i+2]);
                res+=BinaryToBase64(temp);
            }
            else if(i+1<bytes.length){
                temp = ByteToBinary(bytes[i]);
                temp+=ByteToBinary(bytes[i+1]);
                res+=BinaryToBase64(temp+"00")+"=";
            }
            else{
                temp = ByteToBinary(bytes[i]);
                res+=BinaryToBase64(temp+"0000")+"==";
            }
            
            
        }
        return res;
    }
    // ~~~获得比特串
    public static byte[] getBytes(String src){
        return src.getBytes();
    }
    
    // ~~~Base64字符串转ASCII字符串
    public static byte [] FromBase64String(String src){
        String bin="";
        for(int i=0;i<src.length();i++){
            int in=-1;
            for(int j=0;j<64;j++){
                if(src.charAt(i)==table.charAt(j)){
                    in=j;
                }
            }
            if(in==-1)continue;
            for(int j=5;j>=0;j--){
                bin+=((in>>j)&1);
            }
        }
        byte num=0;
        byte bytes[] = new byte[bin.length()/8];
        for(int i=0;i<bin.length();i++){
            num = (byte) (num * 2+(bin.charAt(i)-'0'));
            if((i+1)%8==0){
                bytes[i/8]=num;
                num=0;
            }
        }
        return bytes;
    }
    // ~~~解码
    public static String DeCode(byte [] bytes){
        String res="";
        for(int i=0;i<bytes.length;i++){
            res+=(char)bytes[i];
        }
        return res;
    }

}

参考自
http://www.cnblogs.com/zhaojunjie/p/4009192.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  优酷 视频