事实上流程大致是:调用飞驴下载API+js解析+文件下载+调用flvBind合并这样一个流程而已_(:з」∠)_

貌似是不用太多的说明。。嗯。。

起先的需求是从优酷上下载一些视频

只是网络上的各种软件 甚至是优酷自己的APP 都没有提供高清视频下载的功能

并且1080P视频本身对于优酷就是一种付费功能

仅仅好自己DIY攻克了=w=

一些模型类

class Youku {
public string Url;
public string Title;
public string Quality;
public int Count;
public List<YoukuFlvFile> FlvUrls = new List<YoukuFlvFile>();
} class YoukuFlvFile {
public string FileName;
public string FileUrl;
public string LocalFileName;
}

调用API

这里本来想找飞驴的开发人员中心要权限来的_(:з」∠)_ 可惜被拒了..

仅仅好截获站点自带的ajaxAPI...

这里要首先把页面地址转化为base64url 转化方法能够參考飞驴的开发文档

函数返回的是一串js代码 做进一步解析

顺带 这个api频繁调用会失效 大概server自己也要解析一会才有返回值...

CookieContainer cookie = new CookieContainer();
string getJS(string videoUrl) {
string vUrl64 = Base64Url(videoUrl);
string urlTop = "http://www.flvxz.com/?url="+vUrl64; //訪问API
HttpWebRequest req = (HttpWebRequest)WebRequest.Create("https://www.flvxz.com/getFlv.php?url="+vUrl64);
req.Referer = urlTop;
req.Method = "get";
req.Accept = "application/javascript, */*;q=0.8";
req.Headers.Add(HttpRequestHeader.AcceptLanguage, "zh-Hans-CN,zh-Hans;q=0.7,ja;q=0.3");
req.UserAgent = "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; WOW64; Trident/6.0)";
req.Host = "www.flvxz.com";
//req.CookieContainer = cookie;
HttpWebResponse resp = (HttpWebResponse)req.GetResponse();
StreamReader sr = new StreamReader(resp.GetResponseStream(),Encoding.UTF8);
string result = sr.ReadToEnd();
resp.Close(); return result;
} string Base64Url(string url) {
url = url.Replace("://",":##");
string vUrlBase64 = Convert.ToBase64String(Encoding.UTF8.GetBytes(url));
vUrlBase64 = vUrlBase64.Replace('+','-').Replace('=','_');
return vUrlBase64;
}

JS解析获取flv下载地址

这个非常蛋疼...返回的js是一大段eval语句 由多个flvout(html, id)函数调用组成

原本的飞驴页面则是直接运行这段js  而我们不得不用正則表達式解析...

其实我的思路是使用Regex解析,结合SgmlReader对html格式化,最后用LINQ2XML进行抓取

算是非常节省代码的一系列过程了。。

这里想细致研究的话就自行分析DOM结构吧=w=

函数返回一个Youku实例 包括子flv文件的文件名称和下载地址

Youku GetYoukuFiles(string youkuUrl) {
Youku youku = new Youku();
youku.Url = youkuUrl;
string js = getJS(youkuUrl);
Regex regex = new Regex(@"flvout\('(.+?)','(.+?)'\)");
int idx = 0;
foreach(Match m in regex.Matches(js)) {
string html = string.Format("<html>{0}</html>", m.Result("$1"));
MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(html));
Sgml.SgmlReader r = new Sgml.SgmlReader();
r.DocType = "html";
r.StripDocType = true;
r.InputStream = new StreamReader(ms);
var xml = XElement.Load(r); var h4 = xml.XPathSelectElements("./div/div/h4").FirstOrDefault();
if (h4 != null) {
youku.Title = h4.Value;
}
string qua = xml.Elements("span").Skip(1).First().Value;
if (qua.Contains("1080P")) {
string count = xml.Elements("span").Skip(2).First().Value;
youku.Quality = qua;
youku.Count = Convert.ToInt32(count); var items = xml.Elements("a").Where(elem=> {
var attrRel = elem.Attribute("rel");
return attrRel != null && attrRel.Value=="noreferrer";
}).Select(elem=>new {title = elem.Value, href = elem.Attribute("href").Value}); foreach(var item in items) {
var f = new YoukuFlvFile();
f.FileName = item.title;
f.FileUrl = item.href;
youku.FlvUrls.Add(f);
}
}
idx++;
} return youku;
}

下载文件

直接WebClient的干活 它的优点是假设出现exception会自己主动删除下载一半的文件...

假设想支持断点续传请自己编写很多其它文字_(:з」∠)_

void Download0(Youku m) {
var client = new WebClient();
if(m.FlvUrls.Count>0) {
string dir = Path.Combine(downloadDir, m.Title);
if (!Directory.Exists(dir)) {
Directory.CreateDirectory(dir);
} //下载
foreach(var file in m.FlvUrls) {
file.LocalFileName = Path.Combine(dir, file.FileName);
if (!File.Exists(file.LocalFileName)) {
client.DownloadFile(file.FileUrl, file.LocalFileName);
Console.WriteLine(file.FileName+" 完成下载");
} else {
Console.WriteLine(file.FileName+" 文件已存在");
}
}
}
}

合并flv

直接用flvBind命令行工具 省时省力

原来想用ffmpeg直接转成mp4来的 我已经疯了=w=

由于windows上使用管道的恶心程度和參数的问题仅仅好放弃...

假设知道怎么调教ffmpeg解决“多个x264流合并并且不二次编码”的旷世难题一定教教我_(:з」∠)_ 简直虐心

void Combine0(Youku m) {
ProcessStartInfo ps = new ProcessStartInfo(@"E:\Program files\ffmpeg-win64\bin\FlvBind.exe");
ps.Arguments = string.Join(" ",
new[]{ m.Title+".flv"}
.Concat(m.FlvUrls.Select(f=>f.LocalFileName))
.Select(str=>"\""+str+"\"")
);
ps.WorkingDirectory = downloadDir;
var p = Process.Start(ps);
p.WaitForExit();
Console.WriteLine(m.Title+" 合并完毕");
}

最后把上面的代码连上就可以=w=

void Main()
{
string url = "http://v.youku.com/v_show/id_XNzU4OTM0Njg0.html";
for(int t=0;t<5;t++) {
var m = GetYoukuFiles(url);
if (m.FlvUrls.Count>0) {
Download0(m);
if (!File.Exists(Path.Combine(downloadDir, m.Title+".flv"))) {
Combine0(m);
}
} else {
Console.WriteLine("获取失败...3秒后重试");
Thread.Sleep(3000);
}
}
} string downloadDir = @"D:\2014Cj";

以上代码能够在win8x64 .net4.5  LINQPAD 4.48中正常运行

SgmlReader能够在csdn下载频道中找到

flvBind能够自行搜索 是一个非常迷你的视频处理工具

.net下载优酷1080P视频的更多相关文章

  1. 视频下载四大神器—如何下载优酷/爱奇艺/腾讯/B站超清无水印视频

      视频下载四大神器—如何下载优酷/爱奇艺/腾讯/B站超清无水印视频  2018-07-11 |  标签»下载, 下载工具, 视频 又是视频下载,老生常谈的话题.阿刚同学已在乐软博客多次与大家分享推荐 ...

  2. python3自动下载优酷视频小程序

    我们一般都在优酷里看一些好玩的视频,有时候看到精彩的就想下载到本地保存起来留作纪念,在win下可以用维棠等软件下载,但苦了用linux的孩子们.尽管chrome和firefox的一些插件可以下载,但有 ...

  3. 优酷m3u8视频源地址获取失败

    昨天和今天上午,优酷站点视频全然没有办法播放,可是我是获取的优酷视频的视频原地址,所以app还是能够正常播放而且有下载功能.今天下午開始,优酷视频网页能够訪问了,可是视频原地址却不在了.我全部的app ...

  4. 破解优酷VIP视频

    目录 一 破解优酷VIP视频 一 破解优酷VIP视频 import requests import re import json HEADERS = { 'user-agent': 'Mozilla/ ...

  5. dede后台添加优酷等视频iframe链接时被替换成了图片

     添加文章时 添加优酷视频 :<iframe height=498 width=510 src='http://player.youku.com/embed/XNDAzNTAzODE4OA==' ...

  6. 优酷1080p的kux格式文件怎么转换为MP4格式?

    直接使用优酷自己的FFMPEG解码! 格式为:"优酷ffmpeg.exe的安装地址" -y -i ".kux文件储存地址" -c:v copy -c:a cop ...

  7. 优酷1080p的kux格式文件转码

    @echo off for /r . %%i in (*.kux) do ( "C:\Program Files (x86)\YouKu\YoukuClient\nplayer\ffmpeg ...

  8. 爬虫(三)解析js,抓取优酷免费视频的真实播放地址

    工具:google浏览器 + fiddler抓包工具 说明:这里不贴代码,[只讲思路!!!] 原始url = https://v.youku.com/v_show/id_XMzIwNjgyMDgwOA ...

  9. 在html里网页中嵌入优酷的视频

    <html> <embed src="http://player.youku.com/player.php/sid/XMjAzOTk4NjI4/v.swf" qu ...

随机推荐

  1. 2.1 Producer API官网剖析(博主推荐)

    不多说,直接上干货! 一切来源于官网 http://kafka.apache.org/documentation/ 2.1 Producer API 2.1.生产者API 我们鼓励所有新开发的程序使用 ...

  2. JS 数字格式千分位相互转换

    /** * 将数值四舍五入后格式化. * * @param num 数值(Number或者String) * @param cent 要保留的小数位(Number) * @param isThousa ...

  3. ACCESS数据库改名asp或asa

    到把mdb改为asp或asa ACCESS数据库:把数据库后缀名改成ASP是防止ACCESS数据库被下载

  4. Linux 从core信息中找到TLS信息

    背景 我们在查core问题时,有时候须要查看某个TLS变量的值.可是GDB没有提供直接的命令,或者我不知道.这篇文字的目的.就是想办法从core文件里找出某个线程存放TLS变量的内容. 依据 Linu ...

  5. 自己定义progressdialog载入动画,这里还有旋转的载入条,美团,多个图片动画

    自己定义progressdialog载入动画,这里还有旋转的载入条,美团,多个图片动画 下载Demo:http://download.csdn.net/detail/menglele1314/8775 ...

  6. amazeui学习笔记--js插件(UI增强)--警告框Alert

    amazeui学习笔记--js插件(UI增强)--警告框Alert 一.总结 1.警告框基本样式:用am-alert声明div容器, <div class="am-alert" ...

  7. JS学习笔记 - fgm练习 2-5 - 函数传参 设置div样式

    练习地址:http://www.fgm.cc/learn/lesson2/05.html <script> window.onload = function(){ var oDiv = d ...

  8. C# 泛型特化

    C# 泛型不是 C++ 的模板类,并不支持特化和偏特化,但是使用一些技巧可以在一定程度上达到相同的目的. 原文是 po 在 stackoverflow 上的一个回答:A: Generic indexe ...

  9. 【高德地图API】从零開始学高德JS API(五)路线规划——驾车|公交|步行

    先来看两个问题:路线规划与导航有什么差别?步行导航与驾车导航有什么差别? 回答: 1.路线规划,指的是为用户提供3条路线推荐.[高德]在提供路线规划的时候,会提供用户自己定义路线规划功能,这是别家没有 ...

  10. Shiro基础知识08----拦截器介绍(转)

    1 拦截器介绍 Shiro使用了与Servlet一样的Filter接口进行扩展:所以如果对Filter不熟悉可以参考<Servlet3.1规范>http://www.iteye.com/b ...