Using Delphi 10.4 Community Edition, VCL, Windows 10 64bit, although the compiled .exe
application is 32bit.
The VCL's TMediaPlayer
seems to have a file path/name length limit of 128 characters. Is this really an internal limitation? Is there any way to access longer file paths/names?
I was coding a small soundPad player by using the TMediaPlayer
component.
The installer I am using installs the .exe
program in the user's home directory, and at the same time a few sample audio files in the program's root directory.
In this case, the path to the audio file may be quite long. For example:
C:\Users\user\AppData\Local\Programs\MySoundPlayer\ThisIsMySoundWithAVeryLongFileNameThereIsSomeCopyrightInfoAndSomeOther.wav
When trying to play such a file, TMediaPlayer
will give an error message:
Exception class name = 'EMCIDeviceError'
Exception message = 'Invalid filename. Make sure the filename has 8 characters, a period, and an extension.'
I tried different lengths in the file name, and it looks like 127 is the maximum length.
So, the VCL TMediaPlayer
component does not recognize file paths / names longer than 127 characters?
I tried the same code with a Delphi FMX app, and FMX's TMediaPlayer
worked ok. It seems that the maximum file path and name length of the FMX TMediaPlayer
is 259, which is quite sufficient.
The length 259 seem to be the limit of the File Explorer overall...
It is said that the VCL's TMediaPlayer
component is starting to become obsolete, and is only involved in backward compatibility reasons. But what can replace it in the future?
So, I guess I have to move on to FMX and learn its secrets. Is VCL a receding component system?
procedure TForm1.PlayButtonClick(Sender: TObject);
var
pathstring, playerfilename, playstring : string;
begin
try
pathstring := ExtractFilePath(Application.ExeName);
playerfilename := 'ThisIsMySoundWithAVeryLongFileNameThereIsSomeCopyrightInfoAndSomeOther.wav';
playstring := pathstring + playerfilename;
MediaPlayer1.FileName := playstring;
MediaPlayer1.Open;
MediaPlayer1.Play;
except
on E : Exception do
begin
ShowMessage('Exception class name = ' + E.ClassName);
ShowMessage('Exception message = ' + E.Message);
end;
end;
end;
Per this answer to
mciSendString()
won't play an audio file if path is too long:The
Invalid filename
error message you are seeing is the system text for theMCIERR_FILENAME_REQUIRED
error code.The VCL's
TMediaPlayer
is based on MCI and internally usesmciSendCommand()
, which is just the binary version ofmciSendString()
. They both suffer from the same problem.The preferred fix is to either use shorter paths, or use a more modern audio API.
However, since
mmioInstallIOProc()
can be used to letTMediaPlayer
play media files from memory instead of files, I think a similar solution could be used to play files with long file paths, since you could take over the responsibility of opening/reading/seeking a file, bypassing the path limitation of the troublesomemmioOpen()
. Just replace theTResourceStream
in that code with aTFileStream
, and update theMMIOM_READ
andMMIOM_SEEK
handlers accordingly to read/seek thatTFileStream
.For example (untested, might need some tweaking):