赞
踩
一、杂谈
最近有很多热心网友反馈抖音去水印又不行了,之前是时不时被blocked,现在直接连内容都没有了,返回直接就是空了,我们今天简要给大家分析一下请求过程,附上delphi 源码,及生成签名验证,成功请求到json数据的解决方法。
二、请求过程分析
我们还是先获取一个抖音链接
https://v.douyin.com/A2VSVxc/
通过访问重定向
https://www.douyin.com/video/7065264218437717285
然后提取到其中的视频ID
7065264218437717285
如果是之前,我们会直接GET请求
https://www.douyin.com/aweme/v1/web/aweme/detail/?aweme_id=7065264218437717285
然后就能得到响应内容了。
但是这种方法已经失效了,今天我们会讲解如何在增加一些请求头参数以及X-Bogus后,可以仍然获取到JSON格式的数据。如:
{"aweme_detail":{"anchors":null,"authentication_token":"......
.........}
可以看到,获取到的aweme_detail json数据和以前一样。
三、URL参数X-Bogus
X-Bogus你可以理解为是一个根据视频ID及user-agent通过JS生成的用户信息参数,它可以用于校验。
详细的一篇分析可以参考Freebuf上的《【JS 逆向百例】某音 X-Bogus 逆向分析,JSVMP 纯算法还原》。
下面是完整的delphi 源码解析类,主要流程如下:
1.传入抖音分享链接:
https://v.douyin.com/A2VSVxc/
重定向得到:
https://www.douyin.com/video/7065264218437717285
2.提取到其中的视频ID:
7065264218437717285
3.无水印视频接口不变:
https://www.douyin.com/aweme/v1/web/aweme/detail/?aweme_id=7065264218437717285
4.(增加步骤4)根据X-Bogus 算法,传入url链接及USER_AGENT数据,生成一个形如:
https://www.douyin.com/aweme/v1/web/aweme/detail/?aweme_id=7065264218437717285&X-Bogus=DFSzswSL2MtANHxFtG3DB09WcBjv
一个携带X-Bogus签名验证字段的请求链接。使用这个链接发送GET请求,就能得到aweme_detail 的json 数据了。不信大家可以试试。不过,这个链接是不能
在浏览器直接访问的,还必须加上cookie,refer等请求头数据,详情看下面的Tdouyin解析类。
5.关于高清无水印视频链接的获取方法
从"aweme_detail" json数据解析出视频的Uri项,带入高清视频接口:
https://aweme.snssdk.com/aweme/v1/play/?video_id=v0200fg10000c86doo3c77uai4m711qg&ratio=1080p&line=0
执行重定向getRedirectedUrl()得到高清无水印链接:
https://v95-p-cold.douyinvod.com/9f8215c6204afafffee302e612317776/64201324/video/tos/cn/tos-cn-ve-15c001-alinc2/35721d123b6243cca42398b0c5243c32/?a=1128&ch=0&cr=0&dr=0&cd=0%7C0%7C0%7C0&cv=1&br=2209&bt=2209&cs=0&ds=4&ft=bvjWJkQQqUsmfd4ZFo0OW_EklpPiXnlFZMVJEEy8kdbPD-I&mime_type=video_mp4&qs=0&rc=NDU3Omc3aDY8ZGc7OTkzOUBpajQ6N2Q6ZnJnOzMzNGkzM0BiXjE0NTQvXmExNTVeNTU2YSNuLmpmcjQwbDNgLS1kLS9zcw%3D%3D&l=20230326163724C8959375177E24BE6CEE&btag=a8000
详细步骤看以下TDouyin解析类,关键代码处都有注解:
1.解析类:
- unit uDouyin;
-
- interface
- uses
- windows,classes,System.Net.URLClient, System.Net.HttpClient, System.Net.HttpClientComponent,
- System.SysUtils,strutils,uLog,System.RegularExpressions,uFuncs,system.JSON,uConfig,
- uVideoInfo,uDownVideo;
- const
- wm_user=$0400;
- wm_downfile=wm_user+100+1; //消息参数;
-
- //USER_AGENT标识客户端的类型,这儿是电脑浏览器端。
- USER_AGENT:string='Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Safari/537.36';
-
- //USER_AGENT标识客户端的类型,这儿是手机APP端。
- USER_AGENT_PHONE:string='Mozilla/5.0 (iPhone; CPU iPhone OS 15_6 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.6 Mobile/15E148 Safari/604.1';
- USER_AGENT_PHONE_2:string='TikTok 26.2.0 rv:262018 (iPhone; iOS 14.4.2; en_US) Cronet';
-
- //无水印视频接口,跟以前一样。
- DOUYIN_API_URL:string='https://www.douyin.com/aweme/v1/web/aweme/detail/?aweme_id=' ;
- DOUYIN_API_URL_2:string='https://www.douyin.com/aweme/v1/web/aweme/detail/?aweme_id=%s&aid=1128&version_name=23.5.0&device_platform=android&os_version=2333' ;
-
- //高清无水印视频接口:
- DOUYIN_API_URL_1080 = 'https://aweme.snssdk.com/aweme/v1/play/?video_id=%s&ratio=1080p&line=0';
- type
- TDouyin=class(TThread) //支持多线程下载;
- private
- FId:cardinal; //线程标识;
- Furl:string; //分享的链接;;
- FRedirectedUrl:string; //重定向后的链接;
- Fvideourl:string; //解析后得到的无水印视频链接;
- FvideoId:string; //视频id 如:7065264218437717285
- FvideoTitle:string; //视频标题
- Fnickname:string; //作者昵称
- FcoverUrl:string; //视频封面链接
- Fmsg:string; //线程消息
- Fsavedir:string; //保存视频文件及封面图片的目录
- Furl_1080:string; //高清视频链接
- Furi_1080:string; //高清视频uri参数 不懂的+v:metabycf
- Fphotos:string;
- class var Fcookie: string; //cookie参数 ,可从浏览器获取 静态类成员
- class var Fform: HWND; //接收消息的窗体句柄 类成员
- procedure SetId(id:cardinal); //设置线程id
- procedure SetSaveDir(dir:string); //设置保存目录
- class procedure SetForm(const hForm: HWND); static; //设置窗体句柄 静态方法
- class procedure SetCookie(const cookie: string); static; //设置cookie 静态方法
-
- protected
- procedure Execute; override;
- public
- constructor Create(id:cardinal;url:string);
- destructor Destroy;
- property id:cardinal read FId write SetId; //id属性
- property url:string read Furl; //分享链接 属性
- property msg:string read Fmsg; //线程消息 属性
- property videourl:string read Fvideourl; //无水印视频链接 属性
- property videoTitle:string read FvideoTitle; //视频标题 属性
- property nickname:string read Fnickname; //用户昵称
- property RedirectedUrl:string read FRedirectedUrl; //重定向链接 属性
- property videoId:string read FvideoId; //视频id 属性 如:7065264218437717285
- property coverUrl:string read FcoverUrl; //封面链接 属性
- property url_1080:string read Furl_1080; //高清视频链接 属性
- property photos:string read Fphotos;
- property savedir:string read Fsavedir write setSaveDir; //保存目录 属性
- function getRedirectedUrl(url:string):string;overload; //获取重定向链接
- function getRedirectedUrl(url,refer,user_agent:string):string;overload; //获取重定向链接
- function getVideoId(txt:string):string; //解析出视频id 如:7065264218437717285
- function getVideoUrl():string; //解析无水印视频地址,封面链接,视频标题 工作流程方法在这儿:
- function parseJson(jo:string):string; //解析aweme_detail json数据
- class property form: HWND read Fform write SetForm; //窗体句柄 类属性
- class property cookie: string read Fcookie write SetCookie; //cookie 类属性
- function getPostResult(data:string):string; //post 请求
- function getRequestResult2(apiurl:string;Cookie:string):string; //GET 请求
- function getBogusUrl(url:string):string; X-Bogus 算法 不明白的+v:metabycf
- end;
- implementation
-
- //解析无水印视频地址,封面链接,视频标题 工作流程方法在这儿:
- function TDouyin.getVideoUrl():string;
- var
- apiurl,apiurl2,jo:string;
- i:integer;
- video:TvideoInfo;
- down:TdownVideo;
- begin
- result:='';
- FcoverUrl:='';
- FvideoUrl:='';
- Fphotos:='';
- try
- //第一步:执行重定向,从而获取到视频id
- //如:https://www.douyin.com/video/7065264218437717285
- FRedirectedUrl:=getRedirectedUrl(Furl,Furl,USER_AGENT);
- log('FRedirectedUrl='+FRedirectedUrl); //日志记录
- if(FRedirectedUrl)='' then exit;
-
- //第二步:分析出视频id,如:7065264218437717285
- FvideoId:=getVideoId(FRedirectedUrl);
- log('FvideoId='+FvideoId); //日志记录
- if(FvideoId)='' then exit;
-
- //apiurl:=DOUYIN_API_URL+FvideoId; //视频接口
- apiurl:=format(DOUYIN_API_URL_2,[FvideoId]); //视频接口
-
- //第三步:计算X-Bogus验证,加到视频接口上。得到新的请求链接 多了这一步骤。
- //如:https://www.douyin.com/aweme/v1/web/aweme/detail/?aweme_id=7065264218437717285&X-Bogus=DFSzswSL2MtANHxFtG3DB09WcBjv
- //不明白的+v:metabycf
- apiurl2:=getBogusUrl(apiurl); //具有X-Bogus验证的视频接口 多了这一步骤。
- log(apiurl2); //日志记录
- if(apiurl2='')then begin log('apiurl2=k');exit;end;
-
- //第四步:发送GET请求,带上cookie,refer参数;到这一步,已经能拿到"aweme_detail" json数据了。
- jo:=getRequestResult2(apiurl2,Fcookie);
- Fmsg:=jo;
- log(jo); //日志记录
- if(pos('aweme_detail',jo)<=0)then begin
- log('aweme_detail=k');
- exit;
- end;
- if(pos('"aweme_detail":null',jo)>0)then exit;
-
- //第五步: 解析 "aweme_detail" json数据
- parseJson(jo);
-
- //第六步: 1解析 图文
- if(Fphotos<>'')then
- begin
- video:=TvideoInfo.Create(Fvideotitle,coverUrl,'',Fphotos);
- down:=TdownVideo.Create(Fid,video,Fsavedir,false);
- //down.form:=Fform;
- //down.cookie:=Fcookie;
- //if(DEBUG=true)then downvideo.process else
- down.Start;
- exit;
- end;
-
- //第六步: 2解析 高清视频地址
- if(Furi_1080<>'')then //Furi_1080为视频 uri
- begin
- Furl_1080:=format(DOUYIN_API_URL_1080,[Furi_1080]);
- log(Furl_1080); //日志记录
- Furl_1080:=getRedirectedUrl(Furl_1080,FRedirectedUrl, USER_AGENT_PHONE); //重定向
- log('Furl_1080='+Furl_1080); //日志记录
- end;
-
- //第七步: 启动下载线程,下载视频文件和封面图片。
- if(Fvideotitle<>'')and(Furl_1080<>'')and(FcoverUrl<>'')then
- begin
- video:=TvideoInfo.Create(Fvideotitle,coverUrl,Furl_1080,'');
- down:=TdownVideo.Create(Fid,video,Fsavedir,false);
- //down.form:=Fform;
- //down.cookie:=Fcookie;
- down.Start;
- end;
- finally
- //第八步: 发送解析完成消息。
- Fmsg:='complete';
- SendMessage(Fform,wm_downfile,2,integer(self));
- end;
-
- end;
-
- //第四步:发送GET请求,带上cookie,refer参数;到这一步,已经能拿到"aweme_detail" json数据了。
- function TDouyin.getRequestResult2(apiurl:string;Cookie:string):string;
- var
- client: TNetHTTPClient;
- ss: TStringStream;
- s,id:string;
- AResponse:IHTTPResponse;
- i:integer;
- begin
- try
- client := TNetHTTPClient.Create(nil);
- SS := TStringStream.Create('', TEncoding.UTF8);
- ss.Clear;
- with client do
- begin
- ConnectionTimeout := 10000; // 10秒
- ResponseTimeout := 10000; // 10秒
- AcceptCharSet := 'utf-8';
- UserAgent := USER_AGENT; //1 USER_AGENT USER_AGENT_PHONE_2
- client.AllowCookies:=true;
- client.HandleRedirects:=true;
- Accept:='application/json'; //'*/*'
- client.ContentType:='application/json'; //2
- client.AcceptLanguage:='zh-CN';
-
- client.CustomHeaders['Cookie'] := cookie;
- client.CustomHeaders['Referer'] := Furl;
- try
- AResponse:=Get(apiurl, ss);
- result:=ss.DataString;
- except
- on E: Exception do
- Log(e.Message);
-
- end;
- end;
- finally
- ss.Free;
- client.Free;
- end;
-
- end;
-
- //第五步: 解析 "aweme_detail" json数据 :分为视频和图文两类
- function TDouyin.parseJson(jo:string):string;
- var
- json,jroot,jvideo,j1,j2: TJSONObject;
- arr,arr1:TJSONARRAY;
- uri,aweme_type,photo:string;
- i:integer;
- begin
- result:='';
- try
- json := TJSONObject.ParseJSONValue(jo) as TJSONObject;
- if json = nil then exit;
- jroot:=json.GetValue('aweme_detail') as TJSONObject;
- FvideoTitle:=trim(jroot.GetValue('desc').Value);
-
- aweme_type:=jroot.GetValue('aweme_type').Value;
-
- if(aweme_type='68')then //图文
- begin
- arr:=jroot.GetValue('images') as TJSONARRAY;
- for I := 0 to arr.Size-1 do
- begin
- j1:=arr.Get(i) as TJSONObject;
- arr1:=j1.GetValue('url_list') as TJSONARRAY;
-
- photo:=arr1.Items[0].Value;
- Fphotos:=Fphotos+photo+#13#10;
- end;
- result:='#100#'+Fphotos+'#'+FcoverUrl+'#'+FvideoTitle;
- exit;
- end;
-
- jvideo:=jroot.GetValue('video') as TJSONObject;
- j1:=jvideo.GetValue('cover') as TJSONObject; //cover origin_cover
- arr:=j1.GetValue('url_list') as TJSONARRAY;
- FcoverUrl:=arr[0].Value;
-
- j1:=jvideo.GetValue('play_addr') as TJSONObject;
- arr:=j1.GetValue('url_list') as TJSONARRAY;
- FvideoUrl:=arr[0].Value;
- FvideoUrl:=stringreplace(FvideoUrl,'playwm','play',[rfReplaceAll]);
-
- Furi_1080:=j1.GetValue('uri').Value;
-
- result:='#100#'+FvideoUrl+'#'+FcoverUrl+'#'+FvideoTitle;
-
- finally
- if json <> nil then json.Free;
- end;
- end;
-
- //第二步:分析出视频id,如:7065264218437717285
- function TDouyin.getVideoId(txt:string):string;
- var
- m:TMatch;
- i:integer;
- begin
- result:='';
- m := TRegEx.Match(txt,'/video/([^/?]+)/');
- if(m.Groups[1].Success=false) or (length(m.Groups[1].Value)<>19)then exit;
- result:=m.Groups[1].Value;
-
- end;
- //X-Bogus 算法 不明白的+v:metabycf
- function TDouyin.getBogusUrl(url:string):string;
- var
- json:TJSONObject;
- data:string;
- begin
- result:='';
- try
- json:=TJSONObject.Create;
- json.AddPair('url',url);
- json.AddPair('user_agent',USER_AGENT);
- data:=json.ToString;
- log(data);
- data:=getPostResult(data);
- log(data);
- if(data='')then exit;
- json:=TJSONObject.ParseJSONValue(data) as TJSONObject;
- result:=json.GetValue('param').Value;
- finally
- json.Free;
- end;
- end;
-
- //第一步:执行重定向,从而获取到视频id
- function TDouyin.getRedirectedUrl(url,refer,user_agent:string):string;
- var
- client: TNetHTTPClient;
- ss: TStringStream;
- s,id:string;
- AResponse:IHTTPResponse;
- i:integer;
- begin
- try
- client := TNetHTTPClient.Create(nil);
- SS := TStringStream.Create('', TEncoding.UTF8);
- ss.Clear;
- with client do
- begin
- ConnectionTimeout := 2000; // 2秒
- ResponseTimeout := 2000; // 10秒
- AcceptCharSet := 'utf-8';
- UserAgent := user_agent;
- client.AllowCookies:=true;
- client.HandleRedirects:=false;
- Accept:='*/*';
- client.CustomHeaders['Referer'] := refer;
- try
- AResponse:=Get(url, ss);
- Log('getRedirectedUrl AResponse='+ss.DataString);
- s:=AResponse.HeaderValue['Location'];
- if(s='')then exit;
- result:=s;
- except
- on E: Exception do
- Log(e.Message);
-
- end;
- end;
- finally
- ss.Free;
- client.Free;
- end;
- end;
-
- constructor TDouyin.Create(id:cardinal;url:string);
- begin
- //inherited;
- //FreeOnTerminate := True;
- inherited Create(True);
- FId:=id;
- Furl:=url; //分享链接
- Furi_1080:=''; //视频uri
- Fphotos:='';
- end;
- destructor TDouyin.Destroy;
- begin
- inherited Destroy;
- end;
-
- //工作线程
- procedure TDouyin.Execute;
- begin
- try
- getVideoUrl();
- finally
-
- end;
- end;
-
-
- //------------------------------------------属性方法-------------------------------------
- procedure TDouyin.SetId(Id:cardinal);
- begin
- FId:=Id;
- end;
- class procedure TDouyin.SetForm(const hForm: HWND);
- begin
- Fform:=hForm;
- end;
-
- procedure TDouyin.SetSaveDir(dir:string);
- begin
- Fsavedir:=dir;
- end;
- class procedure TDouyin.SetCookie(const cookie: string);
- begin
- Fcookie:=cookie;
- end;
-
-
- end.

2、视频信息
- unit uVideoInfo;
-
- interface
- type
- TVideoInfo=class
- private
- Ftitle:string; //标题
- FcoverUrl:string; //封面地址
- FvideoUrl:string; //视频地址
- Fphotos:string; //图片地址
- procedure SetTitle(title:string);
- public
- property title:string read Ftitle write Settitle;
- property coverUrl:string read FcoverUrl;
- property videoUrl:string read FvideoUrl;
- property photos:string read Fphotos;
- constructor Create(title,coverUrl,videoUrl,photos:string);
- end;
- implementation
- constructor TVideoInfo.Create(title,coverUrl,videoUrl,photos:string);
- begin
- Ftitle:=title;
- FcoverUrl:=coverUrl;
- FvideoUrl:=videoUrl;
- Fphotos:=photos;
- end;
- procedure TVideoInfo.Settitle(title:string);
- begin
- Ftitle:=title;
- end;
- end.

3、下载
-
- unit uDownVideo;
-
- interface
- uses
- windows,classes,System.Net.URLClient, System.Net.HttpClient, System.Net.HttpClientComponent,
- System.SysUtils,strutils,uLog,System.RegularExpressions,uFuncs,system.JSON,uConfig,
- uVideoInfo,WinInet,urlmon,shlobj,ioutils;
- const
- wm_user=$0400;
- wm_downfile=wm_user+100+1;
- USER_AGENT:string='Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Safari/537.36';
- type
- TDownVideo=class(TThread)
- private
- FId:cardinal;
- Fvideo:TvideoInfo;
- Fsavedir:string;
- FvideoFilename:string;
- FcoverFilename:string;
- FphotoFilename:string; //图片文件名
- Fmsg:string;
- FSerial:boolean; //是否在文件名前面加入序号;
- Fsuccess:boolean;
- Frefer:string;
- class var Fcookie: string;
-
- procedure SetId(id:cardinal);
- procedure SetSavedir(dir:string);
- procedure SetRefer(refer:string);
- class var Fform: HWND;
- class procedure SetForm(const hForm: HWND); static;
- class procedure SetCookie(const cookie: string); static;
- function DownloadFile(SourceFile, DestFile: string): Boolean;
-
- protected
- procedure Execute; override;
- public
- constructor Create(id:cardinal;video:TvideoInfo;savedir:string;bSerial:boolean);
- destructor Destroy;
- property id:cardinal read FId write SetId;
- property savedir:string read Fsavedir write SetSavedir;
- property video:TvideoInfo read Fvideo;
- property msg:string read Fmsg;
- property videoFilename:string read FvideoFilename;
- property coverFilename:string read FcoverFilename;
- property photoFilename:string read FphotoFilename;
- property serial:boolean read Fserial;
- property success:boolean read Fsuccess;
- property refer:string read Frefer write SetRefer;
- class property cookie: string read Fcookie write SetCookie;
- class property form: HWND read Fform write SetForm;
- function formatFilename(caption:string):string;
- function formatDir(dir:string):string;
- function GetValidName(s:string):string;
-
- procedure downloadFileLog(SourceFile, DestFile: string);
- procedure process();
- end;
- implementation
- //bSerial为是否给文件名加上序号
- constructor TDownVideo.Create(id:cardinal;video:TvideoInfo;savedir:string;bSerial:boolean);
- begin
- //inherited;
- //FreeOnTerminate := True;
- inherited Create(True);
- FId:=id;
- Fvideo:=video;
- Fsavedir:=formatdir(savedir);
- Fmsg:='';
- FvideoFilename:='';
- FcoverFilename:='';
- FphotoFilename:='';
- Fsuccess:=false;
- Fserial:=bSerial;
- if(not directoryexists(Fsavedir))then
- forcedirectories(Fsavedir);
- end;
- destructor TDownVideo.Destroy;
- begin
- inherited Destroy;
- end;
- //下载流程
- procedure TDownVideo.process();
- var
- dir,title,photoUrl,photoname:string;
- b:boolean;
- photolist:tstrings;
- i:integer;
- begin
- photolist:=nil;
- try
- title:=formatfilename(trim(video.title));
- if(Fvideo.photos='')then //下载视频
- begin
- if(Fserial=true)then
- begin
- FcoverFilename:=Fsavedir+'\'+inttostr(Fid)+'.'+title+'.webp';
- FvideoFilename:=Fsavedir+'\'+inttostr(Fid)+'.'+title+'.mp4';
- end else begin
- FcoverFilename:=Fsavedir+'\'+title+'.webp';
- FvideoFilename:=Fsavedir+'\'+title+'.mp4';
- end;
- if(video.coverUrl<>'')then downloadFileLog(Fvideo.coverUrl,FcoverFilename);
- if(video.videoUrl<>'')then downloadFileLog(Fvideo.videoUrl,FvideoFilename);
- end else begin //下载图片
- photolist:=tstringlist.Create;
- photolist.Text:=video.photos;
-
- if(Fserial=true)then
- dir:=Fsavedir+'\'+inttostr(Fid)+'.'+title
- else
- dir:=Fsavedir+'\'+title;
- forcedirectories(dir);
- if(Fvideo.coverUrl<>'')then
- begin
- FcoverFilename:=dir+'\0.封面 '+title+'.webp';
- downloadFileLog(Fvideo.coverUrl,FcoverFilename);
- end;
- for I := 0 to photolist.Count-1 do
- begin
- photoUrl:=photolist[i];
- if(trim(photoUrl)='')then continue;
- photoname:=dir+'\'+inttostr(i+1)+'.'+title+'.webp';
- downloadFileLog(photoUrl,photoname);
- FphotoFilename:=FphotoFilename+photoname+#13#10;
- end;
- end;
-
- finally
- Fmsg:='complete';
- if(photolist<>nil)then photolist.Free;
- SendMessage(Fform,wm_downfile,1,integer(self));
- end;
- end;
- //线程中执行下载
- procedure TDownVideo.Execute;
- begin
- process();
- end;
- function TDownVideo.GetValidName(s:string):string;
- var
- c:char;
- txt:string;
- begin
- txt:=s;
- for c in TPath.GetInvalidFileNameChars() do
- begin
- txt:=stringreplace(txt,c,'',[rfReplaceAll]);
- end;
- result:=txt;
- end;
- //去除文件名中的非法字符
- function TDownVideo.formatFilename(caption:string):string;
- var
- s:string;
- begin
- s:=caption;
- if(length(s)>72)then s:=leftstr(s,72);
- result:=GetValidName(s);
- end;
- //去除路径中的非法字符
- function TDownVideo.formatDir(dir:string):string;
- var
- caption:string;
- begin
- caption:=trim(extractfilename(dir));
- if(length(caption)>72)then caption:=leftstr(caption,72);
- caption:=GetValidName(caption);
- result:=extractfilepath(dir)+caption;
- end;
- //下载文件
- procedure TDownVideo.downloadFileLog(SourceFile, DestFile: string);
- begin
- if(fileexists(DestFile))then deletefile(DestFile);
- if(Downloadfile(SourceFile,DestFile))then
- begin
- log('成功:'+DestFile);
- Fsuccess:=true;
- end else begin
- log('失败:'+DestFile+' '+SourceFile);
- Fsuccess:=false;
- end;
- end;
- //下载文件
- function TDownVideo.DownloadFile(SourceFile, DestFile: string): Boolean;
- begin
- try
- DeleteUrlCacheEntry(pchar(SourceFile));
- Result := UrlDownloadToFile(nil, PChar(SourceFile), PChar(DestFile), 0, nil) = 0;
- except
- Result := False;
- end;
- end;
-
-
- //------------------------------------------属性方法-------------------------------------
- procedure TDownVideo.SetSavedir(dir:string);
- begin
- Fsavedir:=dir;
- end;
- procedure TDownVideo.SetRefer(refer:string);
- begin
- Frefer:=refer;
- end;
- class procedure TDownVideo.SetCookie(const cookie: string);
- begin
- Fcookie:=cookie;
- end;
- procedure TDownVideo.SetId(Id:cardinal);
- begin
- FId:=Id;
- end;
- class procedure TDownVideo.SetForm(const hForm: HWND);
- begin
- Fform:=hForm;
- end;
-
- end.

需要技术支持及成品的+v:metabycf
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。