弄了三天都没有弄成功过。。就是用线程启动一个外部程序FFMPEG.EXE,传入命令让它关闭,这个外部程序只要按一个q键和CTRL+C就会自动关闭.如果没有执行完直接关进程的话转一半的来的视频就不能播放。
代码如下:
procedure TForm2.Button1Click(Sender: TObject);\\启动程序是在后台运行的
begin
ssdcwt.Create(false);\\调用下面的线程end;procedure TForm2.Button1Click(Sender: TObject);\\发送命令给正在转换的外部程序
begin
//sendmessage()用这个不行;
//postmessage()也不行;
不知道那个位高手能帮我解决一下,困扰了我三天了,只要按一下按钮就是正常停止而不是强行关闭。。
end;
这是一个线程
unit Unit1;interfaceuses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;type
ssdcwt = class(TThread)
private
{ Private declarations }
protected
procedure Execute; override;
end;implementationuses Unit2, TlHelp32, pThread;{ Important: Methods and properties of objects in visual components can only be
used in a method called using Synchronize, for example, Synchronize(UpdateCaption); and UpdateCaption could look like, procedure ssdcwt.UpdateCaption;
begin
Form1.Caption := 'Updated in a thread';
end; }{ ssdcwt }
procedure MyRun_pipe(cmd: String; var m: TMemo);
varhReadPipe,hWritePipe:THandle;
si:STARTUPINFO;
lsa:SECURITY_ATTRIBUTES;
pi:PROCESS_INFORMATION;
cchReadBuffer:DWORD;
ph:PChar;
fname:PChar;
begintry
Screen.Cursor :=crDefault;
fname:=allocmem(255);
ph:=AllocMem(5000);
lsa.nLength :=sizeof(SECURITY_ATTRIBUTES);
lsa.lpSecurityDescriptor :=nil;
lsa.bInheritHandle :=True;if CreatePipe(hReadPipe,hWritePipe,@lsa,0)=false then
begin
ShowMessage('Can not create pipe!');
exit;
end;fillchar(si,sizeof(STARTUPINFO),0);
si.cb :=sizeof(STARTUPINFO);
si.dwFlags :=(STARTF_USESTDHANDLES or STARTF_USESHOWWINDOW);
si.wShowWindow :=SW_HIDE; //SW_show;
si.hStdOutput :=hWritePipe;
si.hStdInput :=hWritePipe;
si.hStdError :=hWritePipe;
StrPCopy(fname,cmd);
if CreateProcess( nil, fname, nil, nil, true, 0, nil, nil, si, pi) = False then
begin
ShowMessage('can not create process');
FreeMem(ph);
FreeMem(fname);
Exit;
end;
while(true) do
begin
if not PeekNamedPipe(hReadPipe,ph,1,@cchReadBuffer,nil,nil) then break;
if cchReadBuffer<>0 then
begin
if ReadFile(hReadPipe,ph^,4096,cchReadBuffer,nil)=false then break;
ph[cchReadbuffer]:=chr(0);
m.Lines.Add(ph); //关键就是在新进程结束前输出
end
else if(WaitForSingleObject(pi.hProcess ,0)=WAIT_OBJECT_0)//等待cmd结束
then break;
end;
ph[cchReadBuffer]:=chr(0);
m.Lines.Add(ph);
CloseHandle(hReadPipe);
CloseHandle(pi.hThread);
CloseHandle(pi.hProcess);
CloseHandle(hWritePipe);
FreeMem(ph);
FreeMem(fname);
finally
Screen.Cursor := crDefault;
end;
end;
procedure ssdcwt.Execute;var
ssdcwt1:string;
begin
ssdcwt1:='ffmpeg.exe -y -i D:\1.avi -bitexact -vcodec mpeg4 -fixaspect -s 320x240 -r 14.985 -b 190 -acodec aac -ac 1 -ar 16000 -ab 48 -f 3gp -muxvb 64 -muxab 32 ssdcwt.3gp';
myrun_pipe(ssdcwt1,form2.Memo1);
end;
end.
代码如下:
procedure TForm2.Button1Click(Sender: TObject);\\启动程序是在后台运行的
begin
ssdcwt.Create(false);\\调用下面的线程end;procedure TForm2.Button1Click(Sender: TObject);\\发送命令给正在转换的外部程序
begin
//sendmessage()用这个不行;
//postmessage()也不行;
不知道那个位高手能帮我解决一下,困扰了我三天了,只要按一下按钮就是正常停止而不是强行关闭。。
end;
这是一个线程
unit Unit1;interfaceuses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;type
ssdcwt = class(TThread)
private
{ Private declarations }
protected
procedure Execute; override;
end;implementationuses Unit2, TlHelp32, pThread;{ Important: Methods and properties of objects in visual components can only be
used in a method called using Synchronize, for example, Synchronize(UpdateCaption); and UpdateCaption could look like, procedure ssdcwt.UpdateCaption;
begin
Form1.Caption := 'Updated in a thread';
end; }{ ssdcwt }
procedure MyRun_pipe(cmd: String; var m: TMemo);
varhReadPipe,hWritePipe:THandle;
si:STARTUPINFO;
lsa:SECURITY_ATTRIBUTES;
pi:PROCESS_INFORMATION;
cchReadBuffer:DWORD;
ph:PChar;
fname:PChar;
begintry
Screen.Cursor :=crDefault;
fname:=allocmem(255);
ph:=AllocMem(5000);
lsa.nLength :=sizeof(SECURITY_ATTRIBUTES);
lsa.lpSecurityDescriptor :=nil;
lsa.bInheritHandle :=True;if CreatePipe(hReadPipe,hWritePipe,@lsa,0)=false then
begin
ShowMessage('Can not create pipe!');
exit;
end;fillchar(si,sizeof(STARTUPINFO),0);
si.cb :=sizeof(STARTUPINFO);
si.dwFlags :=(STARTF_USESTDHANDLES or STARTF_USESHOWWINDOW);
si.wShowWindow :=SW_HIDE; //SW_show;
si.hStdOutput :=hWritePipe;
si.hStdInput :=hWritePipe;
si.hStdError :=hWritePipe;
StrPCopy(fname,cmd);
if CreateProcess( nil, fname, nil, nil, true, 0, nil, nil, si, pi) = False then
begin
ShowMessage('can not create process');
FreeMem(ph);
FreeMem(fname);
Exit;
end;
while(true) do
begin
if not PeekNamedPipe(hReadPipe,ph,1,@cchReadBuffer,nil,nil) then break;
if cchReadBuffer<>0 then
begin
if ReadFile(hReadPipe,ph^,4096,cchReadBuffer,nil)=false then break;
ph[cchReadbuffer]:=chr(0);
m.Lines.Add(ph); //关键就是在新进程结束前输出
end
else if(WaitForSingleObject(pi.hProcess ,0)=WAIT_OBJECT_0)//等待cmd结束
then break;
end;
ph[cchReadBuffer]:=chr(0);
m.Lines.Add(ph);
CloseHandle(hReadPipe);
CloseHandle(pi.hThread);
CloseHandle(pi.hProcess);
CloseHandle(hWritePipe);
FreeMem(ph);
FreeMem(fname);
finally
Screen.Cursor := crDefault;
end;
end;
procedure ssdcwt.Execute;var
ssdcwt1:string;
begin
ssdcwt1:='ffmpeg.exe -y -i D:\1.avi -bitexact -vcodec mpeg4 -fixaspect -s 320x240 -r 14.985 -b 190 -acodec aac -ac 1 -ar 16000 -ab 48 -f 3gp -muxvb 64 -muxab 32 ssdcwt.3gp';
myrun_pipe(ssdcwt1,form2.Memo1);
end;
end.
解决方案 »
- 在Canvas 上 显示文字的问题
- 请问要用什么控件连接Oracle比较好
- 现在Delphi程序员一般工资多少??
- 请问Delphi7上怎么没有TClientSocket和TServerSocket控件呀?
- 就是隐藏不了qq的登陆窗口,有哪位高手请赐教,在下感激不进
- 一個修改的問題?
- 即时通讯系统( 仿OICQ ) 提供下载
- 為什麼我用formatdatetime('yyyy-mm-dd hh:tt:ss',now);保存到數據表中的結果是這個樣子﹕’2002-07-02﹕下午 0‘我設置的字段長度是60﹐
- 请大家讨论ADO的特性和优点。
- 那 里 有DAO3.6
- 物价飞涨,拜托各位程序员找工作时把工资开高点,别把行情搞坏了,对大家没好处
- 远程数据库项目,应该怎么选择数据库?
改成si.dwFlags :=STARTF_USESHOWWINDOW;下面发送一个q就可以关闭程序但是这个程序的输出信息就不能在Memo1里面显示而是在自己的窗口显示
procedure TForm2.Button1Click(Sender: TObject);\\发送命令给正在转换的外部程序
begin
//sendmessage(H,WM_CHAR,113,0);这样就能正常关闭。
END;
有什么办法可以解决这个问题。。
现在的问题是我把这个外部程序的输入信息读到Memo1里面去了。这个外部程序就是一个窗口里面什么东西都没有都读到MEMO1里面来了这个如果我给这个外部程序发消息Q没有反应。。如果我没有把外部程序的信息读到MEMO1里面去。直接在窗口上显示这样我发送消息Q他就能自动关闭。而且转换到一半就停止的视频可以播器。如果把外部信息都读到MEMO1里面去了。发消息给外部程序没有一点反应所以问题就在这里。我把外部程序返回的信息读到MOME1里面去有什么办法可以让他在转换当中正常停。也就是发送消息。能让他停止也不是直接关进程。。
我说的够清楚了吧。你可以试一下我的代码