在线视频的5种下载办法
最简单的办法,就是利⽤各种⽹盘搜索,到⽹盘的分享地址,转存到⾃⼰的⽹盘,然后下载。这样就避免了从在线视频⽹站直接下载,⽽且常常清晰度⽐较⾼。
如果⽹盘不到,第⼆种办法是利⽤⼀些在线视频的解析⽹站。只要把视频的⽹址输进去,就能解析出下载地址,也很简单。⼤的视频⽹站如B站,优酷等都有解析⽹站。不过,现在的视频⽹站经常调整,所以解析也常常失效。
第三种办法是利⽤某些⼯具。我⽐较常⽤的是you-get和youtube-dl,都是⽤python编写的,开放源代码,可以根据⾃⼰的需求修改。youtube-dl的功能更为强⼤,⽀持的⽹站也更多。但某些功能做的太繁琐,⽤起来不太⽅便,⽐如下载字幕,挑选清晰度等。you-get在这些⽅⾯⽐较⽅便些,同时程序较⼩,改起来也⽅便些。
第四种办法是直接查看⽹页的源代码,到下载地址。某些视频⽹站如西⽠视频可以这样做。
第五种办法是设法获取到m3u8下载列表,然后再下载。如果得到了m3u8的⽹址,可以⽤某些m3u8专⽤下载⼯具下载,试过⼀两种,感觉都不理想,不是速度太慢,就是操作繁琐。
可以⽤youtube-dl直接下载:youtube-dl <m3u8的url>。⽅便是⽅便,但因为实质是利⽤ffmpeg来下载
(那些m3u8专⽤下载⼯具估计有的也是这样的),⼤概是单线程的,⼀是速度⽐较慢,⼆是如果出错,⼜得重来。所以我⼀般都是⼿⼯下载m3u8⽂件后再⽤下载⼯具如Internet Download Manager之类下载视频⽂件,然后再⽤ffmpeg拼成单个⽂件。
⼿⼯下载了m3u8⽂件,如果想偷懒,可以直接在命令⾏输⼊ffmpeg -protocol_whitelist file,http,https,tcp,tls,crypto -i index.m3u8 -c copy
my_movie.ts下载,优缺点和上⾯⽤youtube-dl下载m3u8是⼀样的。
⼿⼯操作的话,第⼀步是下载m3u8⽂件。有个还不错的⼯具,chrome浏览器的插件hls downloader,可以⾃动捕捉到m3u8的⽹址,⽤起来⽐较⽅便。有些⽹址⽤这个⼯具捕捉不到,需要点击chrome浏览器的Network页,然后出含有m3u8的⽹址,再⼿⼯下载。个别的⽹站还需要研究它的js源码,到m3u8的内容。⽐如某⽹站在Network页⾥不到m3u8,分析其js,到了⼀个函数foo(e.data),e.data⾥就是
m3u8的内容。于是在该函数上加上断点,刷新页⾯,到断点停下来时,在Console⾥输⼊console.log(e.data); 就打印出了m3u8。
下载到的m3u8⽂件,主要有两种。⼀种有完整的播放列表,⼀种只有⼀个m3u8的地址:
#EXTM3U
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=1000000,RESOLUTION=1280x720
/foo/bar/index.m3u8
得到播放列表后,⾸先⽤程序转成便于下载⼯具导⼊的列表⽂件:
private void m3u8toList()
{
StringBuilder sb = new StringBuilder();
var lines = File.ReadAllLines(@"C:\index.m3u8");
foreach (string line in lines)
{
if (line.IndexOf("#") < 0)
{
sb.AppendLine(line);
}
}
File.WriteAllText(@"C:\", sb.ToString());
}
播放列表⾥的视频⽂件名⼤致有两种,⼀种是有规律的,如foo_001.ts, foo_002.ts等,这种相对⽅便⼀些,⼀种没有规律,⽐如
N3Atb.ts,2BjMl.ts等,这种会给下⼀步的合并⽂件带来困难(如果直接⽤ffmpeg下载没有这个问题,但⼿⼯操作就有问题)。⼀个办法是利⽤DownthemAll这个插件,写段程序⽣成它专⽤的下载列表:
var lines = File.ReadAllLines(@“C:\");//下载列表⽂件,⼀⾏⼀个url
StringBuilder sb = new StringBuilder();
int count = 1;
sb.AppendLine("<?xml version=\"1.0\"?>");
sb.AppendLine("<metalink xmlns=\"urn:ietf:params:xml:ns:metalink\" version=\"4.0\" a0:version=\"3.0.8\" xmlns:a0=\"www.downthemall/properties#\">");
sb.AppendLine("<generator>DownThemAll!/3.0</generator>");
var date = (Int64)(DateTime.UtcNow .Subtract(new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc)) .TotalMilliseconds);
var utcString = DateTime.UtcNow.ToString("r");
sb.AppendLine("<published>" + utcString + "</published>");
foreach (var line in lines)
{
string serial = String.Format("{0:0000}", count);
string url = line.Replace("&", "&").Replace(">", ">").Replace("<", "<").Replace("\"", """);
sb.AppendLine("<file name=\"" + serial + ".ts" + "\" a0:num=\"442\" a0:startDate=\"" + date.ToString() + "\" >");
sb.AppendLine("<url priority=\"100\" a0:usable=\"" + url + "\">" + url + "</url>");
sb.AppendLine("</file>");
date = date + 4;
count++;
}
sb.AppendLine("</metalink>");
File.WriteAllText(@"C:\a4", sb.ToString());
不过因为downthemall的下载速度不快,所以这个⽅法我也不常⽤,⼀般是先⽤其他下载⼯具下载完视频⽂件后,再⽤下⾯的程序给⽂件重命名:
private void renameDownloads()
{
var lines = File.ReadAllLines(@"C:\");
int count = 1;
SortedList<string, string> mapping = new SortedList<string, string>();
int idx = 0;
foreach (var line in lines)百度视频怎么下载
{
idx = line.LastIndexOf("/") + 1;
mapping.Add(line.Substring(idx), string.Format("{0:0000}", count) + ".ts");
count++;
}
var files = Directory.GetFiles(folder, "*.ts");
foreach (var file in files)
{
string fileName = Path.GetFileName(file);
File.Move(file, Path.Combine(folder, mapping[fileName]));
}
}
某些m3u8⾥的视频⽂件是加密的,下载的ts⽂件⽤播放器⽆法直接打开。⼀般是⽂件中有段:
#EXT-X-KEY:METHOD=AES-128,URI="foo/key.key"
这种需要先从这个⽹址⼿⼯下载key.key⽂件,然后⽤下⾯的程序解密:
private void decrypt()
{
var folder = @"C:\foo";
byte[] encryptionKey = File.ReadAllBytes(@"C:\foo\key.key");
StringBuilder sberror = new StringBuilder();
var files = Directory.GetFiles(folder, "*.ts");
for (int i = 0; i < files.Length; i++)
{
string fileName = Path.GetFileName(files[i]);
string outputFile = Path.Combine(folder, Path.GetFileNameWithoutExtension(fileName) + ".mp4");
using (FileStream outputFileStream = new FileStream(outputFile, FileMode.Create))
{
byte[] encryptionIV = new byte[16];
using (FileStream inputFileStream = new FileStream(files[i], FileMode.Open))
{
try
{
using (var aes = new AesManaged { Key = encryptionKey, IV = encryptionIV, Mode = CipherMode.CBC })
using (var encryptor = aes.CreateDecryptor())
using (var cryptoStream = new CryptoStream(inputFileStream, encryptor, CryptoStreamMode.Read))
{
cryptoStream.CopyTo(outputFileStream);
}
}
catch (Exception ex)
{
sberror.AppendLine(fileName);
}
}
}
}
if (sberror.Length > 0)
{
File.WriteAllText(@"C:\", sberror.ToString());
MessageBox.Show("error");
}
}
值得注意的是某些加密视频中夹有⼀段不加密的⼴告。我⼀般是⼿⼯删除这些⼴告后再解密。
最后⼀步是合并下载到的视频⽂件。我⼀般是⽤个dos批处理⽂件来处理:
for %%i in (*.ts) do echo file '%%i'>> t1.txt
pause
ffmpeg -f concat -safe 0 - -c copy final.mp4
pause的作⽤是⽣成⽂件列表后,有个⼿⼯调整的机会。某些情况下,⽐如有1.ts,10.ts⽂件,正确的次序是从1到10,但是这个批处理有可能将10.ts排在1.ts的后⾯,所以需要⼿⼯调整。
需要注意的是某些m3u8⽂件中有EXT-X-DISCONTINUITY标记,这时⽤ffmpeg合并时有时会出错。我也没有什么好办法,只能将视频拆成两三段,相当于上下或者上中下集,分段数不太多的话,尚可接受。
⼤致的下载⽅法就这些。