Ignore:
Timestamp:
Oct 4, 2011, 1:18:33 PM (13 years ago)
Author:
george
Message:
  • Modified: MPlayer system now play audio files.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • CoolAudio/Systems/UAudioSystemMPlayer.pas

    r275 r276  
    66
    77uses
    8   Classes, SysUtils, UAudioSystem;
     8  Classes, SysUtils, UAudioSystem, Process, Math, Dialogs;
     9
     10const
     11{$ifdef Unix}
     12  MPlayerExecutableName = 'mplayer';
     13{$endif}
     14{$ifdef Windows}
     15  MPlayerExecutableName = 'mplayer.exe';
     16{$endif}
    917
    1018type
     
    1321  TAudioSystemMPlayer = class(TAudioSystem)
    1422  private
     23    FPath: string;
    1524    procedure SetOutputMode(AValue: TOutputDriver); override;
     25    function FindPath: string;
    1626  public
    1727    constructor Create; override;
    1828    destructor Destroy; override;
     29    property Path: string read FPath write FPath;
    1930  end;
    2031
     
    2334  TPlayerMPlayer = class(TPlayer)
    2435  private
     36    FProcess: TProcess;
     37    FProcessActive: Boolean;
     38    FPlaying: Boolean;
    2539    FVolume: Real;
     40    function GetProcessOutput: string;
     41    procedure SendCommand(Command: string);
    2642    function GetLength: TDateTime; override;
    2743    function GetPosition: TDateTime; override;
     
    3147    procedure SetVolume(AValue: Real); override;
    3248    procedure SetMuted(AValue: Boolean); override;
     49    procedure SetFileName(AValue: string); override;
    3350  public
    3451    procedure Play; override;
    3552    procedure Pause; override;
    3653    procedure Stop; override;
    37   end;
    38 
     54    constructor Create; override;
     55    destructor Destroy; override;
     56  end;
     57
     58resourcestring
     59  SMPlayerNotFound = 'MPlayer executable not found. Make sure it is properly installed in binary path';
     60  SSendCommandException = 'Exception occured during sending command to MPlayer';
     61  SErrorReadingOutput = 'Exception while reading MPlayer output';
     62  SCantStopProcess = 'Can''t stop Mplayer process';
    3963
    4064implementation
     
    4771end;
    4872
     73function TAudioSystemMPlayer.FindPath: string;
     74var
     75  tmps: string;
     76  tmppath: string;
     77  I: Integer;
     78begin
     79  Result := '';
     80  {$ifdef Darwin}
     81  {$else}
     82  // Searches for MPlayer in the PATH
     83  tmps := GetEnvironmentVariable('PATH');
     84  repeat
     85    I := pos(':', tmps);
     86    if I = 0 then I := Length(tmps);
     87    tmppath := IncludeTrailingPathDelimiter(Copy(tmps, 0, I - 1)) + MPlayerExecutableName;
     88    if FileExists(tmppath) then Result := tmppath
     89      else Delete(tmps, 1, I);
     90  until (Length(tmps) <= 1) or (Result <> '');
     91  {$endif}
     92  if Result = '' then raise Exception.Create(SMPlayerNotFound);
     93end;
     94
    4995constructor TAudioSystemMPlayer.Create;
    5096begin
    5197  inherited Create;
     98  FPath := '';
    5299end;
    53100
     
    59106{ TPlayerMPlayer }
    60107
     108procedure TPlayerMPlayer.SendCommand(Command: string);
     109begin
     110  Command := Command + LineEnding;// #10; // MPLayer always needs #10 as Lineending, no matter if win32 or linux
     111  try
     112    if FProcessActive then FProcess.Input.Write(Command[1], System.Length(Command));
     113  except
     114    raise Exception.Create(SSendCommandException);
     115  end;
     116end;
     117
    61118function TPlayerMPlayer.GetLength: TDateTime;
    62119begin
    63   Result:=inherited GetLength;
    64120end;
    65121
    66122function TPlayerMPlayer.GetPosition: TDateTime;
    67 begin
    68   Result:=inherited GetPosition;
     123var
     124  tmps: string;
     125  I: Integer;
     126  Time: Real;
     127begin
     128  if FProcess.Running then begin
     129    I := 0;
     130    repeat
     131      SendCommand('get_property time_pos');
     132      Sleep(8);
     133      tmps := GetProcessOutput;
     134      Inc(I);
     135    until (Pos('time_pos', tmps) > 0) or (I >= 3);
     136    I := LastDelimiter('=', tmps);
     137    if I > 0 then begin
     138      Time := StrToFloat(Copy(tmps, I + 1, System.Length(tmps)));
     139      Time := Time * 1000;
     140      Result := Round(Time);
     141    end else Result := -1;
     142  end else Result := -1;
    69143end;
    70144
    71145function TPlayerMPlayer.GetVolume: Real;
    72146begin
    73   Result:=inherited GetVolume;
    74147end;
    75148
    76149function TPlayerMPlayer.GetMuted: Boolean;
    77 begin
    78   Result:=inherited GetMuted;
     150var
     151  tmps, s: string;
     152  I: Integer;
     153begin
     154  if FPlaying and FProcess.Running then begin
     155    repeat
     156      SendCommand('get_property mute');
     157      Sleep(5);
     158      tmps := GetProcessOutput;
     159    until Pos('mute', tmps) > 0;
     160    i := LastDelimiter('=', tmps);
     161    if i > 0 then begin
     162      s := Copy(tmps, i + 1, System.Length(tmps) - i);
     163      Result := s = 'yes';
     164    end;
     165  end;
    79166end;
    80167
    81168procedure TPlayerMPlayer.SetPosition(AValue: TDateTime);
    82169begin
    83   inherited SetPosition(AValue);
    84170end;
    85171
    86172procedure TPlayerMPlayer.SetVolume(AValue: Real);
    87173begin
    88   inherited SetVolume(AValue);
     174  if FVolume = AValue then Exit;
     175  FVolume := AValue;
     176  if FPlaying and FProcess.Running then begin
     177    if AValue < 0 then AValue := 0;
     178    if AValue > 1 then AValue := 1;
     179    SendCommand('set_property volume ' + IntToStr(Round(AValue * 100)) + '/1');
     180  end;
    89181end;
    90182
    91183procedure TPlayerMPlayer.SetMuted(AValue: Boolean);
    92184begin
    93   inherited SetMuted(AValue);
     185  if FPlaying and FProcess.Running then
     186    SendCommand('mute');
     187end;
     188
     189procedure TPlayerMPlayer.SetFileName(AValue: string);
     190begin
     191  inherited SetFileName(AValue);
     192end;
     193
     194function IntTodB(I, Ref: Longint): Integer;
     195var
     196  dB: Real;
     197begin
     198  if I = 0 then db := 0.001 else dB := I;
     199  dB := 20 * log10(dB / ref);
     200  Result := Round(dB);
    94201end;
    95202
    96203procedure TPlayerMPlayer.Play;
    97 begin
    98   inherited Play;
     204var
     205  MPOptions: String;
     206  Vol: Real;
     207begin
     208  if FPlaying then Stop;
     209  //FProcess := TProcess.Create(nil);
     210  MPOptions := '-slave -quiet -softvol';
     211  if AudioSystem.OutputMode = omAlsa then MPOptions := MPOptions + ' -ao alsa';
     212  if AudioSystem.OutputMode = omOSS then MPOptions := MPOptions + ' -ao oss';
     213  if AudioSystem.OutputMode = omWin32 then MPOptions := MPOptions + ' -ao win32';
     214  if AudioSystem.OutputMode = omDirectX then MPOptions := MPOptions + ' -ao dsound';
     215
     216  //MPOptions := '-af volume=' + IntToStr(IntTodB(Round(FVolume * 100), 100)) + ' ' + MPOptions;// -volume xx only supported with patched mplayer;
     217
     218  FProcess.CommandLine := TAudioSystemMPlayer(AudioSystem).FPath + ' ' + MPOptions + ' "' + FFileName + '"';
     219  FProcess.Options := FProcess.Options + [poUsePipes, poDefaultErrorMode, poStderrToOutPut, poNoConsole];
     220  //InputBox('', '', FProcess.CommandLine);
     221  FProcess.Execute;
     222
     223  if FProcess.Running then begin
     224    FPlaying := True;
     225  end;
    99226end;
    100227
    101228procedure TPlayerMPlayer.Pause;
    102229begin
    103   inherited Pause;
     230  if FPlaying then begin
     231    SendCommand('pause');
     232    Sleep(10);
     233    //FPaused := not FPaused;
     234  end;
    104235end;
    105236
    106237procedure TPlayerMPlayer.Stop;
    107238begin
    108   inherited Stop;
     239  if FPlaying then begin
     240    SendCommand('quit');
     241    Sleep(15);
     242    if FProcess.Running then begin
     243      Sleep(50);
     244      if FProcess.Running then
     245        if not FProcess.Terminate(0) then
     246          raise Exception.Create(SCantStopProcess);
     247    end;
     248  end;
     249  FPlaying := False;
     250end;
     251
     252constructor TPlayerMPlayer.Create;
     253begin
     254  inherited Create;
     255  FProcess := TProcess.Create(nil);
     256end;
     257
     258destructor TPlayerMPlayer.Destroy;
     259begin
     260  Stop;
     261  FProcess.Free;
     262  inherited Destroy;
     263end;
     264
     265function TPlayerMPlayer.GetProcessOutput: string;
     266var
     267  AStringList: TStringList;
     268begin
     269  try
     270    AStringList:=TStringList.Create;
     271    try
     272      if FProcess.Running then AStringList.LoadFromStream(FProcess.Output);
     273      if AStringList.Count > 0 then
     274        Result := AStringList.Strings[0]
     275        else Result := '';
     276    except
     277      Result := '';
     278      raise Exception.Create(SErrorReadingOutput);
     279    end;
     280  finally
     281    AStringList.Free;
     282  end;
    109283end;
    110284
Note: See TracChangeset for help on using the changeset viewer.