优酷视频解析
2015-07-19 09:09
417 查看
每次在网页上点开优酷的视频播放,我们可以再地址栏得到一个地址如下:
http://v.youku.com/v_show/id_XMTI4NDE5NjQwNA==.html
提取上面的地址中的 XMTI4NDE5NjQwNA,我们称为vid
可以通过如下代码得到:
我们可以得到:
http://v.youku.com/player/getPlayList/VideoIDS/XMTI4NDE5NjQwNA/Pf/4/ctype/12/ev/1
访问这个链接我们可以得到json数据,在json数据中我们需要的是
然后通过如下代码得到
(此代码的算法还不清晰,需要进一步研究)
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文件如下:
另外上面的编码用到了自己写的Base64编码,贴出来
参考自
http://www.cnblogs.com/zhaojunjie/p/4009192.html
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
相关文章推荐
- DVI 视频接口图文解析
- C#调用mmpeg进行各种视频转换的类实例
- C#获取视频某一帧的缩略图的方法
- 显示youtube视频缩略图和Vimeo视频缩略图代码分享
- PHP实现使用优酷土豆视频地址获取swf播放器分享地址
- PHP使用ffmpeg给视频增加字幕显示的方法
- PHP实现将视频转成MP4并获取视频预览图的方法
- C++实现优酷土豆去视频广告的方法
- PHP简单获取视频预览图的方法
- asp.net 页面中添加普通视频的几种方式介绍
- Android自定义控件之仿优酷菜单
- Android获取SD卡上图片和视频缩略图的小例子
- php使用memcoder将视频转成mp4格式的方法
- 基于js与flash实现的网站flv视频播放插件代码
- 用java实现的获取优酷等视频缩略图的实现代码
- java调用ffmpeg实现视频转换的方法
- js+HTML5基于过滤器从摄像头中捕获视频的方法
- 用Python的Django框架完成视频处理任务的教程
- Nginx搭建流媒体FLV视频服务器配置示例
- [总结]视频质量评价技术零基础学习方法