在线视频下载apowersoft网页,在线视频下载插件
[原创]在线视频下载(使用Python/Bash/C/Reguar表达式)
Windows操作系统操作系统上下载在线视频不是很难,可以安装爱酷等对应在线视频(这里是优酷)的官方下载工具,更通用地,可以使用硕鼠下载,这个软件我没用过,但我需要使用硕鼠官方网站http://www.flvcd.com(支持70多个在线视频网站的解析,好强大的说)的视频解析作为代理将某个在线视频播放地址解析成对应的下载地址,我使用计算机编程语言和正则表达式进行抓取我想要的部分(下载地址以及视频标题)并且下载给定视频地址的视频,这个脚本如下:
#!/usr/bin/env python
导入系统
定义输出:
sys.stderr.write(s \n) #将进度输出到标准错误(注意,它不是用于输出实际的错误消息,
#我使用标准错误只是为了方便地捕获标准输出(和卷曲一样),以便以后可以合并这些flv)
argc=len(sys.argv)
如果argc==2:
格式=超级
elif argc==3:
format=sys.argv[2]
否则:
输出(用法:% s视频URL[视频质量=普通高超级.]"% sys。argv[0])
输出(例如);
输出( % s http://v.youku.com/v_show/id_XMzMzMjE0MjE2.html超级% sys.argv[0])
出口(1)
视频URL=sys。argv[1];
导入urllib2
导入人人贷
网址=http://www.flvcd.com/parse.php?kw= URL库。quote(视频网址) format=格式;
req=urllib2 .请求(网址);
#给假的火狐浏览器浏览器添加一些标题(如果我们不这样做,在尝试获取土豆视频时会出现问题)
req.add_header(host , www .flvcd。com’);
req.add_header(Referer ,URL[:-4]);
req.add_header(用户代理、‘Mozilla/5.0(Macintosh;英特尔MAC OS X 10.6;rv:2.0)壁虎/20100101火狐/4.0);
请求。add _ header( Accept-Language , en-us,en;q=0.5’);
请求。add _ header( Accept-Encoding , gzip,deflate );
req.add_header(Accept-Charset , ISO-8859-1,utf-8;q=0.7,*;q=0.7’);
req.add_header(Keep-Alive , 115 );
RES=URL lib 2。urlopen(req);
html=res.read()
进口是
模式=re。编译( input \ s type= hidden \ s name= INF \ s value=([^]));
第一次匹配=模式。搜索(html);
URLs=第一个匹配。组(1);
urls=unicode(urls, gbk );# urls原来是utf8编码
urlpattern=re.compile( [NU](.));
结果=URL模式。查找全部(网址);
数据=[范围(0,len(结果),2)中我的结果[我:我2]]
计数=长度(数据)
文件=[]
输出( \n -开始从URL“% s”下载(总共%d个块): % (videourl,count))
对于枚举中的k,v(数据):
输出(正在下载第%.2d个块,共%.2d个.%(k ^ 1,计数))
urllib.urlretrieve(v[1],v[0] .flv’)
files.append( (v[0] .flv’).替换(, \ )。替换( $ , \$ )。编码( utf-8 ))
输出(下载的块. 2d完全“% (k 1,)”
输出(-已完成- \n )
打印( )。加入(文件)"")我们保存这个脚本到首页(即~)目录下,为dl.py,即保存为~/dl.py,操作如下
# 打开终端
vi ~/dl.py #按回车键
#按我键
# 粘贴上面的计算机编程语言代码
#按经济社会委员会键
:wq #按回车键
sudo chmod u x ~/dl.py #使其可执行这个脚本首先解析命令行参数然后提取在线视频地址和欲下载视频的质量,然后通过flvcd.com代理解析成若干个下载地址(优酷网站会将大视频分割成若干块,但像土豆等视频网站不会),接着使用正则提取视频标题和下载地址并下载,输出进度到stderr,输出每块下载的视频文件文件名(这些文件名中特殊字符被转义接着被包围并以空格分开)到stdout,程序添加的一些超文本传送协议头是为了欺骗硕鼠官网网站我们是通过火狐浏览器浏览器访问的(但并没有完全欺骗,似乎部分土豆在线视频的下载地址无法下载,待解)
输出空格分割的文件名是为了方便壳对标准输出捕获然后使用下面的程序进行猫白血病病毒文件合并(主要针对优酷,前面说过,优酷的大视频是分段的,所以我写了下面的C程序合并这些分段的猫白血病病毒视频):
#包含标准视频
#包含标准库
#包含字符串。h
//#include malloc.h //如果您使用的是windows,请取消对此行的注释
数据类型说明无符号字符字节;
数据类型说明结构{
字节类型[3];
字节版本;
字节类型标志;
字节头长度[4];
} FlvHeader
数据类型说明结构{
字节标记类型;
字节数据大小[3];
字节时间戳[3];
字节时间戳_扩展名;
byte streamID[3];
//字节标记数据[数据大小]
} FlvTag
//确定当前系统是否为大端(网络、媒体等),例如,int 1在中存储为"00 00 00 01"
//大端机器,而01 00 00 00在小端机器中,如果我们假设sizeof(int)=4且左
//地址小于下一个(右边的)地址
(同Internationalorganizations)国际组织是_big_endian() {
int i=0x1
return *(char*) i!= \ x1
}
//在将消息打印到标准错误之前,用退出代码exitStatus退出程序
void quit(char* msg,int exitStatus) {
fprintf(stderr, %s ,msg);
退出(退出状态);
}
//将从猫白血病病毒文件中读取的原始整数转换为适合当前系统的字节序的
int整型(字节*位,整数大小){
int i,ret=0;
if (bits==NULL 大小1 大小4) {
退出(无效位(为空?)还是大小(满分[1,4]?)调用 intval\n 时,1);
}
if (is_big_endian()) {
返回*(int*)位;
}
for(I=0;我尺寸;我)
ret=(int)bits[I](ret 8);
返回浸水使柔软
}
//将存储为当前系统适合的字节序的的整数转换为猫白血病病毒文件中的生的
byte* byteval(int value,int size) {
静态字节位[4]={ 0 };
字节* p=(字节*)值;
int I;
如果(尺寸1 尺寸4) {
退出(无效大小(超出[1,4]?)调用byteval\n 时,1);
}
if (is_big_endian()) {
*(int*)位=值;
}否则{
for(I=0;I 4;我)
bits[I]=p[3-I];
}
返回位4 -大小;
}
//与转为整数相同,只是这里为两倍
double双val(字节*位){
静态字节reverse _ bits[8]={ 0 };
int I;
if (bits==NULL)
退出(无效位(为空?)\n ,1);
if (is_big_endian()) {
*(双*)reverse _ bits=*(双*)位;
}否则{
for(I=0;I 8;我)
reverse _ bits[I]=bits[7-I];
}
return *(double *)reverse _ bits;
}
//与byteval相同,只是这里为两倍
byte* bytevaldouble(双精度值){
静态字节位[8]={ 0 };
字节* p=(字节*)值;
int I;
if (is_big_endian()) {
*(双*)位=值;
}否则{
for(I=0;I 8;我)
bits[I]=p[7-I];
}
返回位;
}
//如果成功返回头,否则返回空
flv header * flv _ header _ read(FILE * FP,FlvHeader* header) {
return fread(header,sizeof(FlvHeader),1,fp)==1?表头:空;
}
//检查猫白血病病毒标头是否有效,以便我们可以确定是否需要进行合并
int flv _ is _ valid _ header(flv header * header){
返回标头标头-类型[0]==F 标头-类型[1]==L 标头-类型[2]==V
((header-type flag 5)==5);
}
//从文件fp点中读取猫白血病病毒标签,并将标签[元]保存到标签,将标签数据大小保存到数据大小,将以前的标签大小保存到
//previousSize,返回纯标记数据
//注意:这个函数会通过返回一个指针来保留最后分配的内存,所以会产生内存泄漏
//但是只有一个泄漏,可以简单的通过字节*数据=flv _ tag _ read(FP,);/*某些操作*/免费(数据);
//但是记住不要在自由的操作之后再次调用flv_tag_read除非你想得到"段错误"之类的错误。
byte* flv_tag_read(FILE* fp,FlvTag* tag,int* dataSize,int* previousSize) {
静态字节* _ tagData=NULL
静态int _ dataSize=0;//存储_标记数据的长度
int tagSize=0,countread=fread(tag,sizeof(FlvTag),1,FP);
如果(countread!=1)
返回空
tagSize=intval(tag- dataSize,3);
if(_ tag data==NULL _ dataSize tagSize){//如果_标记数据没有分配或者如果_标记数据不够,尝试重新分配for _tagData
if(_tagData) //但是应该在分配内存之前释放旧的_标记数据
free(_ tagData);
_ tagData=(byte *)malloc(tagSize * sizeof(byte));
}
if (fread(_tagData,sizeof(byte),tagSize,fp)!=tagSize
fread(previousSize,sizeof(int),1,fp)!=1 ) {
退出(‘FLV标签数据(损坏的标签数据或损坏的先前大小?)坏了. \n ,1);
}
* dataSize=_ dataSize=tagSize
* previous size=*(int *)byte val(* previous size,4);
return _ tagData
}
//使用最笨的搜索算法在二进制数据数据中搜索二进制数据搜索
//如果找到搜索,则返回数据中的索引,否则返回-1
int stud _ byte _ index of(byte * search,int searchLength,byte* data,int dataSize) {
int i,j,end=dataSize - searchLength,found
如果(搜索==空数据==空结束0 搜索长度1)
退出(搜索时参数无效,1);
for(I=0;我结束;i) {
发现=1;
for(j=0;j搜索长度;j)
if (data[j]!=search[j]) {
发现=0;
打破;
}
如果(找到)
返回我;
数据;
}
return-1;
}
//剥离脚本数据标记中的关键帧数据,并将has关键帧重写为错误的
byte * flv _ script data _ strip _ key frames(flv tag * tag,byte* scripttagData,int* dataSize) {
byte hasKeyframes[]={h , a , s , K , e , y , f , r , a , m , \ x1 };
byte keyframes[]={\x0 , \x9 , k , e , y , f , r , a , m , e , s , \ x3 };
字节* ds=空
int len=sizeof(有关键帧)/sizeof(字节);
(同Internationalorganizations)国际组织索引;
如果(!标签标签-标签类型!=0x12 !scripttagData !dataSize) {
退出(不能剥离非脚本数据的[空或视频/音频标签数据?]关键帧或空指针,1);
}
index=study _ byte _ index of(has key frames,len,scripttagData,* dataSize-1);
如果(索引!=-1)
脚本标记数据[index len]= \ x0 ;
指数=愚蠢_字节_indexof(关键帧,sizeof(关键帧)/sizeof(字节),scripttagData,* dataSize);
如果(索引!=-1) {
*数据大小=索引
ds=byteval(index,3);
tag-dataSize[0]=ds[0];
tag-dataSize[1]=ds[1];
tag-dataSize[2]=ds[2];
}
返回scripttagData
}
//用标签[元]标签、标签数据标签数据和以前的标签大小将猫白血病病毒标记写入文件fp点
//如果成功,返回写入的字节,否则返回0
int flv_tag_write(FILE* fp,FlvTag* tag,byte* tagData,int* dataSize,int* previousSize) {
如果(
fwrite(tag,sizeof(FlvTag),1,fp)!=1
fwrite(tagData,sizeof(byte),*dataSize,fp)!=*dataSize
fwrite(previousSize,sizeof(int),1,fp)!=1
) {
返回0;
}
返回sizeof(flv标签)* dataSize * sizeof(字节)sizeof(int);
}
//从猫白血病病毒脚本标签数据(纯数据)中获取持续时间,并将持续时间索引保存在我们找到的位置
//如果偏移量不为空,则猫白血病病毒文件中要偏移的持续时间
double flv _ tag _ get _ duration(byte * tag data,int dataSize,int* offset) {
//确保标记是脚本标记,即:tag.tagType==0x12
字节搜索[9]={ d , u , r , a , t , I , o , \ 0 };
int index=study _ byte _ index of(search,9,tagData,dataSize);
if (index==-1) {
退出(对不起,无法获取猫白血病病毒元持续时间。, 1);
}
index=sizeof(搜索)/sizeof(字节);
中频(偏移)
*偏移量=索引;
返回doubleval(标记数据索引);
}
//从猫白血病病毒标记中获取时间戳[元]
int flv _ tag _ get _ timestamp(flv tag * tag){
如果(!标签)
return-1;
return((int)(tag-timestamp _ extension)24)intval(tag-timestamp,3);
}
//将时间戳设置为猫白血病病毒标记[元]
int flv _ tag _ set _ timestamp(flv tag * tag,int timestamp) {
如果(!标签时间戳0)
return-1;
标签-时间戳_扩展名=时间戳24;
memcpy(tag- timestamp,byteval(时间戳0x00FFFFFF,3),3);
返回时间戳;
}
int main(int argc,char* argv[]) {
由文件头标头;
FlvTag标记;
字节*标记数据
FILE *fpdst=NULL,* fpsrc=NULL
int i=0,srccount=argc - 2,headerLength,duration_index=0,
prevSize,dataSize,offset,foundduration=0,zero=0,basetimestamp[2],lasttimestamp[2]={0} .
char * * src=argv 2;
双倍持续时间=0.0;
int BTS=0;
if (argc 2) {
fprintf(stderr,用法:% s flvtobesaved第一个flv[第二个flv[第三个flv[.]]]\n ,argv[0]);
出口(1);
}
if ((fpdst=fopen(argv[1], WB )==NULL){
fprintf(stderr,无法写入文件%s\n ,argv[1]);
出口(1);
}
而(我的帐户){
if ((fpsrc=fopen(src[i], Rb )==NULL){
fprintf(stderr,无法打开文件“% s”\ n”,src[I]);
出口(1);
}
如果(!flv_header_read(fpsrc,header) !flv_is_valid_header(表头)){
fprintf(stderr,文件" %s "的标头已损坏或者不是猫白血病病毒标头. \n ,src[I]);
出口(1);
}
if (i==0) {
fwrite( header,sizeof(FlvHeader),1,FP dst);
fwrite( zero,sizeof(int),1,FP dst);//第一个先前的标记大小为0
duration _ index=sizeof(flv header);
}
头长度=intval(头。表头长度,4);
如果(0!=fseek(fpsrc,headerLength 4,SEEK_SET)) { //跳到实际猫白血病病毒标签数据(跳过前面第一个标签大小,4)
fprintf(stderr,文件" %s "的第一个先前大小(应为0)已损坏. \n ,src[I]);
出口(1);
}
bts=(int)(持续时间* 1000);
基本时间戳[0]=最后一个时间戳[0];
基本时间戳[1]=最后一个时间戳[1];
if (bts basetimestamp[0])
BTS=基本时间戳[0];
if (bts basetimestamp[1])
BTS=基本时间戳[1];
发现持续时间=0;
while(tag data=flv _ tag _ read(fpsrc,tag,dataSize,prevSize)) {
if (tag.tagType==0x12!foundduration) { //如果找不到脚本数据和持续时间,请尝试获取持续时间
duration=flv _ tag _ get _ duration(tag data,dataSize,offset);
发现持续时间=1;
if (i==0) { //准备用于写入的脚本数据,我们选择第一个猫白血病病毒文件头作为样本
duration_index=4 sizeof(FlvTag)偏移量;
flv _ script data _ strip _ key frames(tag,tagData,dataSize);
flv_tag_write(fpdst,tag,tagData,dataSize,prev size);
}
} else if(标签。标记类型==0x 8 标记。标记类型==0x 9){
最后时间戳[标签。标签类型-0x 8]=BTS flv _ tag _ get _ timestamp(标签);
flv_tag_set_timestamp(标签,最后一个时间戳[标签。标记类型-0x 8]);
flv_tag_write(fpdst,tag,tagData,dataSize,prev size);
if (i==0!foundduration) {
duration _ index=4 sizeof(FlvTag)dataSize;
}
}
}
//fprintf(stdout, base: %d,last: %d\n ,basetimestamp[0],last timestamp[0]);
printf(将文件“%s”完全合并到%s\n ,src[i],argv[1]);
fclose(fpsrc);
我;
}
如果(0!=fseek(fpdst,duration_index,SEEK_SET))
退出(无法搜索到持续时间\n ,1);
fwrite(bytevaldouble(duration),1,8,FP dst);//将实际持续时间保存到文件
fclose(fpdst);
返回0;
}
我们保存为~/flvmerge.c(方法同上), 然后编译并链接成可执行程序:
# 打开终端,如已经打开可以忽略
vi ~/flvmerge.c #按进入键
#按我键
# 粘贴上面的C代码
#按经济社会委员会键
:wq #按回车键
gcc -o ~/flvmerge ~/flvmerge.c
我不期望读者能够看懂这个C程序,因为牵涉到猫白血病病毒文件结构和C语言指针的知识,而我在写这个程序时也是遇到很多困难:没有改变后续分段的时间戳,各分段的起始时间戳不一致导致声音视频不同步,关键帧不完整(这个在高级的播放器播放没有问题,但对于很傻的猫白血病病毒播放器比如优酷猫白血病病毒播放器的话,它就无法手动快进到关键帧之后的时间戳,所以我正考虑要不要修复关键帧,但我用猫白血病病毒元数据注入器修复scriptdatatag损坏的猫白血病病毒视频发现,它猥琐地删除了关键帧,所以我也.然后快进快退都好的了), 但这个合并程序局限在合并的各个猫白血病病毒视频的scriptdatatag必须对持续时间(即视频时长)有定义而且不可能能够应对相当多的情况(其实也不是不可能,但需要看闪光文档), 我正在抽时间解决这个问题,很幸运地,优酷的各个分段的scriptdatatag都挺完整的。另外这个程序在小端机器上编译通过测试没问题,程序里我提供了对大端机器的支持,但可惜没有环境测试。
接下来是连接这两个程序的桥梁:- bash脚本上场了
#!/bin/bash
if [ $# -ne 1 -a $# -ne 2 ]
然后
回声用法:$ 0视频URL[视频质量=普通高超级.]
回声例如
回声 0美元http://v.youku.com/v_show/id_XMzMzMjE0MjE2.html超级
一号出口
船方不负担装货费用
files=$(~/dl.py $1 $2 )
评估集$files
if [ $# -gt 1 ]
然后
合并文件=$(echo $ 1 sed s/[0-9]* .flv$/_merged.flv/)
“回声”开始将文件合并到文件" $mergedfile "中
eval ~/flv合并 $ merged file $ files
回显-将文件完全合并到文件$mergedfile
回声
船方不负担装货费用我们保存为~/g(方法同上):
# 打开终端,如已经打开可以忽略
vi ~/g #按回车键
#按我键
# 粘贴上面的尝试代码
#按经济社会委员会键
:wq #按回车键
Sudo chmod u x ~/g #使其可执行。这个程序试图捕获~/dl.py的输出,然后,如果有必要(当有多个片段时),使用~/FLVmerge将分割的视频合并成一个大的flv文件。
好了,一切准备就绪。可以在终端输入~/g,按回车键执行。您可以看到使用命令的帮助。此外,给出一个下载示例,默认下载到当前文件夹,即执行命令pwd的结果对应的目录。
每个命令的用法如下
~/dl.py在线视频地址视频质量#下载指定地址和质量的视频,可能会有很多段给优酷。
~/flv合并要合并的文件第一个flv视频和第二个flv视频.#合并后续flv视频,如“第一个flv视频”和“第二个flv视频”.到“要合并的文件”
~/g在线视频地址视频质量#在指定地址下载指定质量的视频。如果有多个片段,并且每个片段都是flv格式,则将这些片段合并到一个视频中,删除后续的片段编号,并添加_merged.flv文件名。比如‘音乐银行001 . flv’就会变成‘音乐银行_合并. flv’。不用怕用这个程序,它只会写入第一个参数,也就是‘要合并的文件’,不会改变后面的分段视频,所以如果你想看分段视频,可以直接看。程序没有修改或者删除它们,所以即使合并出现错误(比如mp4格式)也不用怕。可以看分段视频。
* *关于视频质量:由flvcd的格式参数决定。对于优酷:正常标清,高高清,超超高清,其他请实验。另外,如果选择优酷的高清模式下载,这些文件不会合并,因为优酷的高清视频是mp4格式,mp4的合并还有待研究。
你可以试试这个:
~/g http://v.youku.com/v_show/id_XMzMzMjE0MjE2.html超#这将在优酷超清模式下下载音乐银行11216 ,下载后保存为音乐银行E633111216-_merged.flv 。文件位置是您执行最后一个命令的位置,您可以在ls *旁边查看下载的文件。猫白血病病毒
读者可能不太了解命令下载的好处。当~/g与curl(Mac OS X)/wget(Ubuntu)正则化结合使用时,你会看到批量下载优酷相册或优酷空间视频的威力。如果网络带宽允许,可以试试:curl-s http://music.youku.com/ grep-op 3358v.youku.com/v _ show/id _ \ w . html xargs-L1 ~/g #这样会下载优酷音乐频道页面的所有音乐视频,并合并所有相同的地址。
这是我之前的博客地址:http://blog.csdn.net/Wind__Fantasy,曾经介绍过下载《郑云》完整视频的bash脚本(PS:可惜我忘记了注册邮箱和密码,这次要彻底去博客园了。csdn上广告太多,我受不了。)
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。