在 Inno Setup 中逐渐淡化 TDirectShow Player(Inno Media Player)音量
Fade TDirectShow Player (Inno Media Player) volume gradually in Inno Setup
我编写了以下代码以在安装程序完成安装我的程序时逐渐降低视频播放音量。
procedure CurPageChanged(CurPageID: Integer);
var
X: Integer;
begin
...
if CurPageID = wpFinished then
begin
VideoHandler.Release;
VideoHandler.Close;
DSSetVolume(-0);
X := 0;
repeat
DSSetVolume(X);
Log(IntToStr(X));
X = X - 1;
until X = -10000;
DSStopMediaPlay;
...
end;
...
end;
上面的代码输出了 X 值,因为我希望逐渐减小音量,我可以在日志中看到它像 -1 , -2 ... -10000
一样。但是当这个重复过程开始时,
WizardForm
正常显示,但其 wpFinished
页面中没有显示任何内容。只显示一个空表格。除了 WizardForm.Caption
之外,表格中没有绘制任何内容。它的行为就像冻结,直到重复过程(循环)完成。
成交量从不正常减少或逐渐减少。
循环结束,Log输出-10000
后,WizardForm
正常显示,页面也正常显示。音量突然停止是因为我设置为DSStopMediaPlay
.
如何才能正确地完成上述过程(逐渐降低视频播放声音)而不出现任何卡顿或异常情况?
更新
当在 Windows.[=22= 的声音控制面板中将用户的系统声音设置为 20%
时,以下代码可以提供最佳效果]
procedure VolumeFadeTimerProc(HandleW, msg, idEvent, TimeSys: LongWord);
begin
MPEGVideoVolume := MPEGVideoVolume - 15;
if MPEGVideoVolume < -4000 then
begin
DSStopMediaPlay;
KillTimer( 0, TimerID);
KillTimer( 0, VolumeFadeTimer);
Log('Volume Fade Timer has been reset.');
end
else
begin
Log('MPEG Video Volume has been set to: ' + IntToStr(MPEGVideoVolume));
DSSetVolume(MPEGVideoVolume);
end;
end;
减量为15
最大减量为-4000
当在 Windows.[=22= 的声音控制面板中将用户的系统声音设置为 100%
时,以下代码可以提供最佳效果]
procedure VolumeFadeTimerProc(HandleW, msg, idEvent, TimeSys: LongWord);
begin
MPEGVideoVolume := MPEGVideoVolume - 35;
if MPEGVideoVolume < -10000 then
begin
DSStopMediaPlay;
KillTimer( 0, TimerID);
KillTimer( 0, VolumeFadeTimer);
Log('Volume Fade Timer has been reset.');
end
else
begin
Log('MPEG Video Volume has been set to: ' + IntToStr(MPEGVideoVolume));
DSSetVolume(MPEGVideoVolume);
end;
end;
减量为35
最大减量为-10000
是否需要根据用户设置的系统声音量自动更改音量减小量和最大减小量?
提前致谢。
因为您停止了循环中的 window 消息泵。是什么冻结了 window 并且可能还阻止了音量淡出。
您必须使用计时器来淡出音量而不冻结消息泵。
[Code]
function SetTimer(
hWnd: longword; nIDEvent, uElapse: LongWord; lpTimerFunc: LongWord): LongWord;
external 'SetTimer@user32.dll stdcall';
var
Volume: Integer;
VolumeFadeTimer: LongWord;
procedure VolumeFadeTimerProc(
H: LongWord; Msg: LongWord; IdEvent: LongWord; Time: LongWord);
begin
{ Fade by -1000 every 100 ms }
Volume := Volume - 1000;
if Volume <= -10000 then
begin
DSStopMediaPlay;
KillTimer(0, VolumeFadeTimer);
end
else
begin
DSSetVolume(Volume);
end;
end;
procedure CurPageChanged(CurPageID: Integer);
begin
if CurPageID = wpFinished then
begin
VideoHandler.Release;
VideoHandler.Close;
Volume := 0;
{ call VolumeFadeCallback every 100 ms }
VolumeFadeTimer := SetTimer(0, 0, 100, CreateCallback(@VolumeFadeTimerProc));
DSSetVolume(Volume);
end;
end;
对于 CreateCallback
function, you need Inno Setup 6. If you are stuck with Inno Setup 5, you can use WrapCallback
function from InnoTools InnoCallback 库。
我编写了以下代码以在安装程序完成安装我的程序时逐渐降低视频播放音量。
procedure CurPageChanged(CurPageID: Integer);
var
X: Integer;
begin
...
if CurPageID = wpFinished then
begin
VideoHandler.Release;
VideoHandler.Close;
DSSetVolume(-0);
X := 0;
repeat
DSSetVolume(X);
Log(IntToStr(X));
X = X - 1;
until X = -10000;
DSStopMediaPlay;
...
end;
...
end;
上面的代码输出了 X 值,因为我希望逐渐减小音量,我可以在日志中看到它像 -1 , -2 ... -10000
一样。但是当这个重复过程开始时,
WizardForm
正常显示,但其wpFinished
页面中没有显示任何内容。只显示一个空表格。除了WizardForm.Caption
之外,表格中没有绘制任何内容。它的行为就像冻结,直到重复过程(循环)完成。成交量从不正常减少或逐渐减少。
循环结束,Log输出
-10000
后,WizardForm
正常显示,页面也正常显示。音量突然停止是因为我设置为DSStopMediaPlay
.
如何才能正确地完成上述过程(逐渐降低视频播放声音)而不出现任何卡顿或异常情况?
更新
当在 Windows.[=22= 的声音控制面板中将用户的系统声音设置为 20%
时,以下代码可以提供最佳效果]
procedure VolumeFadeTimerProc(HandleW, msg, idEvent, TimeSys: LongWord);
begin
MPEGVideoVolume := MPEGVideoVolume - 15;
if MPEGVideoVolume < -4000 then
begin
DSStopMediaPlay;
KillTimer( 0, TimerID);
KillTimer( 0, VolumeFadeTimer);
Log('Volume Fade Timer has been reset.');
end
else
begin
Log('MPEG Video Volume has been set to: ' + IntToStr(MPEGVideoVolume));
DSSetVolume(MPEGVideoVolume);
end;
end;
减量为15
最大减量为-4000
当在 Windows.[=22= 的声音控制面板中将用户的系统声音设置为 100%
时,以下代码可以提供最佳效果]
procedure VolumeFadeTimerProc(HandleW, msg, idEvent, TimeSys: LongWord);
begin
MPEGVideoVolume := MPEGVideoVolume - 35;
if MPEGVideoVolume < -10000 then
begin
DSStopMediaPlay;
KillTimer( 0, TimerID);
KillTimer( 0, VolumeFadeTimer);
Log('Volume Fade Timer has been reset.');
end
else
begin
Log('MPEG Video Volume has been set to: ' + IntToStr(MPEGVideoVolume));
DSSetVolume(MPEGVideoVolume);
end;
end;
减量为35
最大减量为-10000
是否需要根据用户设置的系统声音量自动更改音量减小量和最大减小量?
提前致谢。
因为您停止了循环中的 window 消息泵。是什么冻结了 window 并且可能还阻止了音量淡出。
您必须使用计时器来淡出音量而不冻结消息泵。
[Code]
function SetTimer(
hWnd: longword; nIDEvent, uElapse: LongWord; lpTimerFunc: LongWord): LongWord;
external 'SetTimer@user32.dll stdcall';
var
Volume: Integer;
VolumeFadeTimer: LongWord;
procedure VolumeFadeTimerProc(
H: LongWord; Msg: LongWord; IdEvent: LongWord; Time: LongWord);
begin
{ Fade by -1000 every 100 ms }
Volume := Volume - 1000;
if Volume <= -10000 then
begin
DSStopMediaPlay;
KillTimer(0, VolumeFadeTimer);
end
else
begin
DSSetVolume(Volume);
end;
end;
procedure CurPageChanged(CurPageID: Integer);
begin
if CurPageID = wpFinished then
begin
VideoHandler.Release;
VideoHandler.Close;
Volume := 0;
{ call VolumeFadeCallback every 100 ms }
VolumeFadeTimer := SetTimer(0, 0, 100, CreateCallback(@VolumeFadeTimerProc));
DSSetVolume(Volume);
end;
end;
对于 CreateCallback
function, you need Inno Setup 6. If you are stuck with Inno Setup 5, you can use WrapCallback
function from InnoTools InnoCallback 库。