📄 umpegaformat.pas
字号:
unit uMPEGAFormat;
interface
uses Classes;
const BufSize = 128;
MPEG_VER_ERROR = 0;
MPEG_VER_1 = 1;
MPEG_VER_2 = 2;
MPEG_VER_2_5 = 3;
MPEG_LAYER_ERROR = 0;
MPEG_LAYER_I = 1;
MPEG_LAYER_II = 2;
MPEG_LAYER_III = 3;
MPEG_BITRATE_ERROR = -1;
MPEG_SAMPLINGRATE_ERROR = -1;
MPEG_CHANNEL_STEREO = 0;
MPEG_CHANNEL_JOINTSTEREO = 1;
MPEG_CHANNEL_DUAL = 2;
MPEG_CHANNEL_SINGLE = 3;
MaxGapBeforeMpeg = 10240;
//位率索引表
MpegKBitRate : array [1 .. 3, 1 .. 3, 0 .. 15] of Integer = ( (//MPEG 1
(0,32,64, 96,128,160,192,224,256,288,320,352,
384,416,448,MPEG_BITRATE_ERROR), //Layer I
(0, 32, 48, 56, 64, 80, 96,112,128,160,192,224,
256,320,384,MPEG_BITRATE_ERROR), //Layer II
(0, 32, 40, 48, 56, 64, 80, 96,112,128,160,192,
224,256,320,MPEG_BITRATE_ERROR) //Layer III
), (//MPEG 2
(0, 32, 48, 56, 64, 80, 96,112,128,144,160,176,
192,224,256,MPEG_BITRATE_ERROR), //Layer I)
(0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96,112,
128,144,160,MPEG_BITRATE_ERROR), //Layer II
(0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96,112,
128,144,160,MPEG_BITRATE_ERROR) //Layer III
),
(//MPEG 2.5
(0, 32, 48, 56, 64, 80, 96,112,128,144,160,176,
192,224,256,MPEG_BITRATE_ERROR), //Layer I)
(0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96,112,
128,144,160,MPEG_BITRATE_ERROR), //Layer II
(0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96,112,
128,144,160,MPEG_BITRATE_ERROR) //Layer III
));
// 采样频率索引表
MpegSamplingRate : array [1 .. 3, 0 .. 3] of integer = ( (44100, 48000, 32000, MPEG_SAMPLINGRATE_ERROR), (22050, 24000, 16000, MPEG_SAMPLINGRATE_ERROR), (32000, 16000, 8000, MPEG_SAMPLINGRATE_ERROR));
MpegEmphasisStr : array [0 .. 3] of string = (
'None', '50/15 ms', '', 'CCIT J.17');
type //MPEG Audio Frame Header的类
TMPEGAFormat = class
private
FHdrbuf: array[0..3] of Byte;
Buf: array[0..BufSize-1] of Byte;
function Locatehdr: Boolean;
function GetHdrInfo: Boolean;
function GetFrameLen: Integer;
public
Version: Integer; // 版本
KBitRate: Integer; // 位率 (kbps)
SamplingRate: Integer; // 采样频率 (HZ)
FrameLen: Integer; // 帧长度
Frames: Integer; // 帧数
Len: Integer; // 播放时间(单位毫秒)
Layer: Integer; // 压缩层次
PaddingLen: Integer; // 填料长度
Padding: Boolean; // 是否有填料
ChannelMode: Integer; // 声道模式
ChannelModeExt: Integer; // 声道扩展模式
ChannelModeExtStr: string; // 声道扩展模式对应字符串
Copyright: Boolean; // 版权
Original: Boolean;
EmphasisStr: string;
// 主函数,从流中获取MPEG info
function GetinfoFromStream(Stream: TStream): Boolean;
end;
implementation
function TMPEGAFormat.GetinfoFromStream(Stream: TStream): Boolean;
var
Pos, Count, Size: Integer;
begin
Pos := 0; Size := Stream.Size;
Result := False;
// 每次读取128字节,找MPEG的帧头
while (Pos < MaxGapBeforeMpeg) and (Pos < Size) do
begin
if Size - Pos > BufSize then
Count:=BufSize else Count := Size - Pos;
Stream.ReadBuffer(Buf, Count);
// 通过帧头,获取基本信息
if Locatehdr and GetHdrInfo then
begin
Frames := (Size - pos) div FrameLen;
// 计算帧数
Len:= Round((Size - Pos)*8/KBitRate);
// 计算播放时间
Result := True;
Exit;
end;
Inc(Pos, Count);
end;
end;
function TMPEGAFormat.Locatehdr: Boolean;
var
I: Integer;
begin
I := 0; Result := False;
while (I < BufSize - 4) do
begin
if (Buf[I] = 255) and (Buf[I+1] and $E0 = $E0) then
// 利用帧同步,找帧头32位
begin
Move(Buf[I], Fhdrbuf, 4);
Result := True;
Exit;
end;
Inc(I);
end;
end;
// 计算帧长度
function TMPEGAFormat.GetFrameLen: Integer;
{ 384 samples/frame for Layer I
1152 samples/frame for Layer II and Layer III
8 bits Mpeg 1, 16 bits Mpeg 2 & 2.5}
var
BitRate: Integer;
begin
BitRate := KBitRate * 1000;
if SamplingRate > 0 then
if Version = MPEG_VER_1 then
if Layer = MPEG_LAYER_I then
Result := Trunc ((48 * BitRate) / SamplingRate) + PaddingLen
else Result := Trunc ((144 * BitRate) / SamplingRate) + PaddingLen
else
if Layer = MPEG_LAYER_I then
Result := Trunc ((24 * BitRate) / SamplingRate) + PaddingLen
else Result := Trunc ((72 * BitRate) / SamplingRate) + PaddingLen
else
Result := 0;
end;
function TMPEGAFormat.GetHdrInfo: Boolean;
begin
//获取版本
case (FHdrBuf [1] shr 3) and 3 of
0: Version := MPEG_VER_2_5;
2: Version := MPEG_VER_2;
3: Version := MPEG_VER_1;
else Version := MPEG_VER_ERROR;
end;
// 压缩层次
Layer := (4 - (FHdrBuf[1] shr 1) and 3) and 3;
// 位率
if (Version <> MPEG_VER_ERROR) and (Layer <> MPEG_LAYER_ERROR) then
KBitRate := MpegKBitRate [Version, Layer, (FHdrBuf [2] shr 4) and $F]
else KBitRate := MPEG_BITRATE_ERROR;
// 采样频率 (HZ)
if Version <> MPEG_VER_ERROR then
SamplingRate := MpegSamplingRate [Version, (FHdrBuf [2] shr 2) and 3]
else SamplingRate := MPEG_SAMPLINGRATE_ERROR;
// 填料的长度
Padding := ((FHdrBuf [2] shr 1) and 1) = 1;
if Padding then
if Layer = MPEG_LAYER_I then Paddinglen := 4 else Paddinglen := 1;
// 帧长度
FrameLen := GetFrameLen;
// 声道模式
ChannelMode := (FHdrBuf [3] shr 6) and 3;
// 声道扩展模式
ChannelModeExt:=(FHdrBuf [3] shr 4) and 3;
// 版权
Copyright:=((fHdrBuf [3] shr 3) and 1) = 1;
//
Original := ((FHdrBuf [3] shr 2) and 1) = 1;
EmphasisStr := MpegEmphasisStr[fHdrBuf [3] and 3];
if (Version <> MPEG_VER_ERROR) and (Layer <> MPEG_LAYER_ERROR)
and (KBitRate <> MPEG_BITRATE_ERROR) and (SamplingRate <> MPEG_SAMPLINGRATE_ERROR) then
Result := True else Result := False;
end;
end.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -