Sources
Delphi Russian Knowledge Base
DRKB - это самая большая и удобная в использовании база знаний по Дельфи в рунете, составленная Виталием Невзоровым

Как определить продолжительность в секундах wav файла?

01.01.2007
uses 
 
MPlayer, MMsystem;
 
type
 
EMyMCIException = class(Exception);
 
TWavHeader = record
    Marker1
: array[0..3] of Char;
   
BytesFollowing: Longint;
    Marker2
: array[0..3] of Char;
    Marker3
: array[0..3] of Char;
    Fixed1
: Longint;
   
FormatTag: Word;
   
Channels: Word;
   
SampleRate: Longint;
   
BytesPerSecond: Longint;
   
BytesPerSample: Word;
   
BitsPerSample: Word;
    Marker4
: array[0..3] of Char;
   
DataBytes: Longint;
 
end;
 
procedure TForm1
.Button1Click(Sender: TObject);
var
 
Header: TWavHeader;
begin
 
with TFileStream.Create('C:\SomeFile.wav', fmOpenRead) do
   
try
     
ReadBuffer(Header, SizeOf(Header));
   
finally
     
Free;
   
end;
 
ShowMessage(FloatToStr((Int64(1000) * header.DataBytes div header.BytesPerSecond) / 1000));
end;  

Взято с сайта https://www.swissdelphicenter.ch/en/tipsindex.php


function GetWaveLength(WaveFile: string): Double;
var
    groupID
: array[0..3] of char;
    riffType
: array[0..3] of char;
   
BytesPerSec: Integer;
   
Stream: TFileStream;
    dataSize
: Integer;
 
// chunk seeking function,
 
// -1 means: chunk not found
 
 
function GotoChunk(ID: string): Integer;
 
var
      chunkID
: array[0..3] of char;
      chunkSize
: Integer;
 
begin
     
Result := -1;
 
   
with Stream do
       
begin
             
// index of first chunk
         
Position := 12;
        repeat
             
// read next chunk
         
Read(chunkID, 4);
         
Read(chunkSize, 4);
           
if chunkID <> ID then
             
// skip chunk
         
Position := Position + chunkSize;
         
until(chunkID = ID) or (Position >= Size);
         
if chunkID = ID then
               
// chunk found,
             
// return chunk size
           
Result := chunkSize;
       
end;
 
end;
 
begin
   
Result := -1;
   
Stream := TFileStream.Create(WaveFile, fmOpenRead or fmShareDenyNone);
   
with Stream do
       
try
         
Read(groupID, 4);
       
Position := Position + 4; // skip four bytes (file size)
       
Read(riffType, 4);
 
       
if(groupID = 'RIFF') and (riffType = 'WAVE') then
           
begin
             
// search for format chunk
           
if GotoChunk('fmt') <> -1 then
             
begin
               
// found it
             
Position := Position + 8;
             
Read(BytesPerSec, 4);
                 
//search for data chunk
                dataSize
:= GotoChunk('data');
 
               
if dataSize <> -1 then
                     
// found it
                 
Result := dataSize / BytesPerSec
               
end
           
end
       
finally
         
Free;
     
end;
end;

This returns the number of seconds as a floating point number, which is not necessarily the most helpful format. Far better to return it as a string representing the time in hours, minutes and seconds. The following function achieves this based on the number of seconds as an integer:

function SecondsToTimeStr(RemainingSeconds: Integer): string;
var
   
Hours, Minutes, Seconds: Integer;
   
HourString, MinuteString, SecondString: string;
begin
     
// Calculate Minutes
   
Seconds := RemainingSeconds mod 60;
   
Minutes := RemainingSeconds div 60;
   
Hours := Minutes div 60;
   
Minutes := Minutes - (Hours * 60);
 
   
if Hours < 10 then
       
HourString := '0' + IntToStr(Hours) + ':'
     
else
       
HourString := IntToStr(Hours) + ':';
 
   
if Minutes < 10 then
       
MinuteString := '0' + IntToStr(Minutes) + ':'
     
else
       
MinuteString := IntToStr(Minutes) + ':';
 
   
if Seconds < 10 then
       
SecondString := '0' + IntToStr(Seconds)
     
else
       
SecondString := IntToStr(Seconds);
   
Result := HourString + MinuteString + SecondString;
end;

Having created these functions you can call them from any relevant event - for example a button click:

procedure TForm1.Button1Click(Sender: TObject);
var
   
Seconds: Integer;
begin
   
Seconds := Trunc(GetWaveLength(Edit1.Text));
   
//gets only the Integer part of the length
    Label1
.Caption := SecondsToTimeStr(Seconds);
end;

You can even reduce this to a single line of code if you prefer:

procedure TForm1.Button1Click(Sender: TObject);
begin
    Label1
.Caption := SecondsToTimeStr(Trunc(GetWaveLength(Edit1.Text)));
end;

Взято с Delphi Knowledge Base: https://www.baltsoft.com/