Как определить продолжительность в секундах wav файла?
Как определить продолжительность в секундах wav файла?
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;
Взято с сайта
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;