Files
lazarus-ccr/components/playsoundpackage/uplaysound.pas

251 lines
7.1 KiB
ObjectPascal
Raw Normal View History

unit uplaysound;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, LResources, Forms, Controls, Graphics, Dialogs
, FileUtil{$IFDEF WINDOWS}, mmsystem{$ELSE}, asyncprocess, process{$ENDIF}, aboutplaysound;
type
TPlayStyle = (psAsync, psSync);
Tplaysound = class(TAboutPlaySound)
private
{ Private declarations }
{$IFNDEF WINDOWS}
SoundPlayerAsyncProcess: Tasyncprocess;
SoundPlayerSyncProcess: Tprocess;
{$ENDIF}
fPlayCommand:String;
fDefaultPlayCommand: String;
fPathToSoundFile: string;
fPlayStyle: TPlayStyle;
protected
{ Protected declarations }
function GetPlayCommand: String;
procedure PlaySound(const szSoundFilename: string); virtual;
public
{ Public declarations }
constructor Create(AOwner: TComponent); override;
destructor Destroy; reintroduce;
// This is the default method
procedure Execute;
procedure StopSound;
published
{ Published declarations }
// This is normally set at runtime
property SoundFile: string read fPathToSoundFile write fPathToSoundFile;
// Default is Async
property PlayStyle: TPlayStyle read fPlayStyle write fPlayStyle default psASync;
// This is automatically determined when the component loads
property PlayCommand:String read fPlayCommand write fPlayCommand;
end;
procedure Register;
implementation
uses
LazFileUtils;
resourcestring
C_UnableToPlay = 'Unable to play ';
function GetNonWindowsPlayCommand:String;
begin
Result := '';
// Try play
if (FindDefaultExecutablePath('play') <> '') then
Result := 'play';
// Try aplay
if (result = '') then
if (FindDefaultExecutablePath('aplay') <> '') then
Result := 'aplay -q';
// Try paplay
if (Result = '') then
if (FindDefaultExecutablePath('paplay') <> '') then
Result := 'paplay';
// Try mplayer
if (Result = '') then
if (FindDefaultExecutablePath('mplayer') <> '') then
Result := 'mplayer -really-quiet';
// Try CMus
if (Result = '') then
if (FindDefaultExecutablePath('CMus') <> '') then
Result := 'CMus';
// Try pacat
if (Result = '') then
if (FindDefaultExecutablePath('pacat') <> '') then
Result := 'pacat -p';
// Try ffplay
if (Result = '') then
if (FindDefaultExecutablePath('ffplay') <> '') then
result := 'ffplay -autoexit -nodisp';
// Try cvlc
if (Result = '') then
if (FindDefaultExecutablePath('cvlc') <> '') then
result := 'cvlc -q --play-and-exit';
// Try canberra-gtk-play
if (Result = '') then
if (FindDefaultExecutablePath('canberra-gtk-play') <> '') then
Result := 'canberra-gtk-play -c never -f';
// Try Macintosh command?
if (Result = '') then
if (FindDefaultExecutablePath('afplay') <> '') then
Result := 'afplay';
end;
constructor Tplaysound.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
fPlayStyle := psASync;
// fPathToSoundFile := ProgramDirectory;
{$IFDEF WINDOWS}
fDefaultPlayCommand := 'sndPlaySound';
{$ELSE}
fDefaultPlayCommand := GetNonWindowsPlayCommand; // Linux, Mac etc.
{$ENDIF}
// About Dialog properties
AboutBoxComponentName := 'PlaySound';
AboutBoxWidth := 400;
AboutBoxHeight := 400;
AboutBoxBackgroundColor := clCream;
//AboutBoxFontName (string)
//AboutBoxFontSize (integer)
AboutBoxVersion := '0.0.3';
AboutBoxAuthorname := 'Gordon Bamber';
AboutBoxOrganisation := 'Public Domain';
AboutBoxAuthorEmail := 'minesadorada@charcodelvalle.com';
AboutBoxLicenseType := 'LGPL';
AboutBoxDescription := 'Plays WAVE sounds in Windows or Linux';
end;
destructor Tplaysound.Destroy;
begin
{$IFNDEF WINDOWS}
FreeAndNil(SoundPlayerSyncProcess);
FreeAndNil(SoundPlayerAsyncProcess);
{$ENDIF}
inherited;
end;
procedure Tplaysound.Execute;
begin
if not FileExistsUTF8(fPathToSoundFile) then
Exit;
Try
PlaySound(fPathToSoundFile);
Except
On E: Exception do
E.CreateFmt(C_UnableToPlay +
'%s Message:%s', [fPathToSoundFile, E.Message]);
end;
end;
function TPlaySound.GetPlayCommand: String;
begin
if FPlayCommand = '' then
Result := FDefaultPlayCommand
else
Result := FPlayCommand;
end;
procedure Tplaysound.PlaySound(const szSoundFilename: string);
var
{$IFDEF WINDOWS}
flags: word;
{$ELSE}
L: TStrings;
i: Integer;
playCmd: String;
{$ENDIF}
begin
{$IFDEF WINDOWS}
if fPlayStyle = psASync then
flags := SND_ASYNC or SND_NODEFAULT
else
flags := SND_SYNC or SND_NODEFAULT;
try
sndPlaySound(PChar(szSoundFilename), flags);
except
ShowMessage(C_UnableToPlay + szSoundFilename);
end;
{$ELSE}
// How to play in Linux? Use generic Linux commands
// Use asyncprocess to play sound as SND_ASYNC
// proceed if we managed to find a valid command
playCmd := GetPlayCommand;
if (playCmd <> '') then
begin
L := TStringList.Create;
try
L.Delimiter := ' ';
L.DelimitedText := playCmd;
if fPlayStyle = psASync then
begin
if SoundPlayerAsyncProcess = nil then
SoundPlayerAsyncProcess := TaSyncProcess.Create(nil);
SoundPlayerAsyncProcess.CurrentDirectory := ExtractFileDir(szSoundFilename);
SoundPlayerAsyncProcess.Executable := FindDefaultExecutablePath(L[0]);
SoundPlayerAsyncProcess.Parameters.Clear;
for i := 1 to L.Count-1 do
SoundPlayerAsyncProcess.Parameters.Add(L[i]);
SoundPlayerAsyncProcess.Parameters.Add(szSoundFilename);
try
SoundPlayerAsyncProcess.Execute;
except
On E: Exception do
E.CreateFmt('Playstyle=paASync: ' + C_UnableToPlay +
'%s Message:%s', [szSoundFilename, E.Message]);
end;
end
else
begin
if SoundPlayerSyncProcess = nil then
SoundPlayerSyncProcess := TProcess.Create(nil);
SoundPlayerSyncProcess.CurrentDirectory := ExtractFileDir(szSoundFilename);
SoundPlayerSyncProcess.Executable := FindDefaultExecutablePath(L[0]);
SoundPlayersyncProcess.Parameters.Clear;
for i:=1 to L.Count-1 do
SoundPlayerSyncProcess.Parameters.Add(L[i]);
SoundPlayerSyncProcess.Parameters.Add(szSoundFilename);
try
SoundPlayerSyncProcess.Execute;
SoundPlayersyncProcess.WaitOnExit;
except
On E: Exception do
E.CreateFmt('Playstyle=paSync: ' + C_UnableToPlay +
'%s Message:%s', [szSoundFilename, E.Message]);
end;
end;
finally
L.Free;
end;
end
else
raise Exception.CreateFmt('The play command %s does not work on your system',
[fPlayCommand]);
{$ENDIF}
end;
procedure Tplaysound.StopSound;
begin
{$IFDEF WINDOWS}
sndPlaySound(nil, 0);
{$ELSE}
if SoundPlayerSyncProcess <> nil then SoundPlayerSyncProcess.Terminate(1);
if SoundPlayerAsyncProcess <> nil then SoundPlayerAsyncProcess.Terminate(1);
{$ENDIF}
end;
procedure Register;
begin
RegisterComponents('LazControls', [Tplaysound]);
{$I playsound_icon.lrs}
end;
end.