Changeset 276 for CoolAudio/Systems/UAudioSystemMPlayer.pas
- Timestamp:
- Oct 4, 2011, 1:18:33 PM (13 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
CoolAudio/Systems/UAudioSystemMPlayer.pas
r275 r276 6 6 7 7 uses 8 Classes, SysUtils, UAudioSystem; 8 Classes, SysUtils, UAudioSystem, Process, Math, Dialogs; 9 10 const 11 {$ifdef Unix} 12 MPlayerExecutableName = 'mplayer'; 13 {$endif} 14 {$ifdef Windows} 15 MPlayerExecutableName = 'mplayer.exe'; 16 {$endif} 9 17 10 18 type … … 13 21 TAudioSystemMPlayer = class(TAudioSystem) 14 22 private 23 FPath: string; 15 24 procedure SetOutputMode(AValue: TOutputDriver); override; 25 function FindPath: string; 16 26 public 17 27 constructor Create; override; 18 28 destructor Destroy; override; 29 property Path: string read FPath write FPath; 19 30 end; 20 31 … … 23 34 TPlayerMPlayer = class(TPlayer) 24 35 private 36 FProcess: TProcess; 37 FProcessActive: Boolean; 38 FPlaying: Boolean; 25 39 FVolume: Real; 40 function GetProcessOutput: string; 41 procedure SendCommand(Command: string); 26 42 function GetLength: TDateTime; override; 27 43 function GetPosition: TDateTime; override; … … 31 47 procedure SetVolume(AValue: Real); override; 32 48 procedure SetMuted(AValue: Boolean); override; 49 procedure SetFileName(AValue: string); override; 33 50 public 34 51 procedure Play; override; 35 52 procedure Pause; override; 36 53 procedure Stop; override; 37 end; 38 54 constructor Create; override; 55 destructor Destroy; override; 56 end; 57 58 resourcestring 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'; 39 63 40 64 implementation … … 47 71 end; 48 72 73 function TAudioSystemMPlayer.FindPath: string; 74 var 75 tmps: string; 76 tmppath: string; 77 I: Integer; 78 begin 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); 93 end; 94 49 95 constructor TAudioSystemMPlayer.Create; 50 96 begin 51 97 inherited Create; 98 FPath := ''; 52 99 end; 53 100 … … 59 106 { TPlayerMPlayer } 60 107 108 procedure TPlayerMPlayer.SendCommand(Command: string); 109 begin 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; 116 end; 117 61 118 function TPlayerMPlayer.GetLength: TDateTime; 62 119 begin 63 Result:=inherited GetLength;64 120 end; 65 121 66 122 function TPlayerMPlayer.GetPosition: TDateTime; 67 begin 68 Result:=inherited GetPosition; 123 var 124 tmps: string; 125 I: Integer; 126 Time: Real; 127 begin 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; 69 143 end; 70 144 71 145 function TPlayerMPlayer.GetVolume: Real; 72 146 begin 73 Result:=inherited GetVolume;74 147 end; 75 148 76 149 function TPlayerMPlayer.GetMuted: Boolean; 77 begin 78 Result:=inherited GetMuted; 150 var 151 tmps, s: string; 152 I: Integer; 153 begin 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; 79 166 end; 80 167 81 168 procedure TPlayerMPlayer.SetPosition(AValue: TDateTime); 82 169 begin 83 inherited SetPosition(AValue);84 170 end; 85 171 86 172 procedure TPlayerMPlayer.SetVolume(AValue: Real); 87 173 begin 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; 89 181 end; 90 182 91 183 procedure TPlayerMPlayer.SetMuted(AValue: Boolean); 92 184 begin 93 inherited SetMuted(AValue); 185 if FPlaying and FProcess.Running then 186 SendCommand('mute'); 187 end; 188 189 procedure TPlayerMPlayer.SetFileName(AValue: string); 190 begin 191 inherited SetFileName(AValue); 192 end; 193 194 function IntTodB(I, Ref: Longint): Integer; 195 var 196 dB: Real; 197 begin 198 if I = 0 then db := 0.001 else dB := I; 199 dB := 20 * log10(dB / ref); 200 Result := Round(dB); 94 201 end; 95 202 96 203 procedure TPlayerMPlayer.Play; 97 begin 98 inherited Play; 204 var 205 MPOptions: String; 206 Vol: Real; 207 begin 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; 99 226 end; 100 227 101 228 procedure TPlayerMPlayer.Pause; 102 229 begin 103 inherited Pause; 230 if FPlaying then begin 231 SendCommand('pause'); 232 Sleep(10); 233 //FPaused := not FPaused; 234 end; 104 235 end; 105 236 106 237 procedure TPlayerMPlayer.Stop; 107 238 begin 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; 250 end; 251 252 constructor TPlayerMPlayer.Create; 253 begin 254 inherited Create; 255 FProcess := TProcess.Create(nil); 256 end; 257 258 destructor TPlayerMPlayer.Destroy; 259 begin 260 Stop; 261 FProcess.Free; 262 inherited Destroy; 263 end; 264 265 function TPlayerMPlayer.GetProcessOutput: string; 266 var 267 AStringList: TStringList; 268 begin 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; 109 283 end; 110 284
Note:
See TracChangeset
for help on using the changeset viewer.