Что нового

Качество mp3/wav

dallas.roma

Новичок
Сообщения
1
Репутация
0
Поделитесь кодом с помощью которого можно узнать качество (битрейт/время) - mp3/wav файла.
 

gregaz

AutoIT Гуру
Сообщения
1 166
Репутация
299
Долго ждал содержательного ответа,т.к. мне самому требовалось корректное нахождение битрейта МР3-файла.
Требовалось нахождение битрейта в процессе чтения ID3-тегов.

Какой смысл несколько раз открывать файл и читать его разными способами.
Пришлось самому вникнуть и попробовать решить проблему.

В результате родилось вот такое решение :

Код:
#include <Array.au3>
#Include<Constants.au3>

Global $aBitrate[17][7] = [ _         
[  "Free"  , "Free" , "Free" ,"", "Free" , "Free","Free"], _; 0000
[    "8"   ,   "8"  ,  "32"  ,"",  "32"  ,  "32" ,  "32"], _; 0001
[   "16"   ,  "16"  ,  "48"  ,"",  "40"  ,  "48" ,  "64"], _; 0010
[   "24"   ,  "24"  ,  "56"  ,"",  "48"  ,  "56" ,  "96"], _; 0011
[   "32"   ,  "32"  ,  "64"  ,"",  "56"  ,  "64" , "128"], _; 0100
[   "40"   ,  "40"  ,  "80"  ,"",  "64"  ,  "80" , "160"], _; 0101
[   "48"   ,  "48"  ,  "96"  ,"",  "80"  ,  "96" , "192"], _; 0110
[   "56"   ,  "56"  , "112"  ,"",  "96"  , "112" , "224"], _; 0111
[   "64"   ,  "64"  , "128"  ,"", "112"  , "128" , "256"], _; 1000
[   "80"   ,  "80"  , "144"  ,"", "128"  , "160" , "288"], _; 1001
[   "96"   ,  "96"  , "160"  ,"", "160"  , "192" , "320"], _; 1010
[  "112"   , "112"  , "176"  ,"", "192"  , "224" , "352"], _; 1011
[  "128"   , "128"  , "192"  ,"", "224"  , "256" , "384"], _; 1100
[  "144"   , "144"  , "224"  ,"", "256"  , "320" , "416"], _; 1101
[  "160"   , "160"  , "256"  ,"", "320"  , "384" , "448"], _; 1110 
["Undefined","Undefined" , "Undefined" , "Undefined" , "Undefined" , "Undefined", "Undefined"]]
;  1001      1010     1011        1101     1110    1111

$sFilePath = FileOpenDialog("Select MP3 File", "::{20D04FE0-3AEA-1069-A2D8-08002B30309D}", "MP3 (*.mp3)", 1 )
$iMp3FileBitrate=GetBitrate($sFilePath)

MsgBox(0,"$iMp3FileBitrate",$iMp3FileBitrate)


Func GetBitrate($sFile)
   $hFile=FileOpen($sFilePath,16)
   $bTagHeader=FileRead($hFile,10)
   $iTagSize=GetID3V2TagSize($bTagHeader)
   FileSetPos($hFile,$iTagSize,$FILE_CURRENT)
;- Проверка наличия ID3v2.4-тегов и нахождение  размера строки тегов 
   $bFragment=FileRead($hFile,4)
   If $bFragment="0x49443304" Then ; ID3v2.4
	  $iTagString =GetID3V2TagSize($bFragment); ===>
	  FileSetPos($hFile,$iTagString+6,$FILE_CURRENT)
   Else
	  FileSetPos($hFile,-4,$FILE_CURRENT)
   EndIf
;- Нахождение и чтение заголовка 1-го MP3-фрейма	
   While 1
	  $bFragment=FileRead($hFile,1)
	  If $bFragment="0xFF" Then 
		 $bFragment=$bFragment & StringTrimLeft(FileRead($hFile,3),2)
		 If StringRegExp($bFragment,"FFE|FFF",0) Then ExitLoop
	  EndIf
   WEnd
   $hexFirstFrameHeader=StringTrimLeft($bFragment,2)
   If $hexFirstFrameHeader = "" Then Return SetError(1,0,"Unknown");
;- Определение Битрейта
   FileSetPos($hFile,32,$FILE_CURRENT)
   $bNextFrameHeader=FileRead($hFile,4)
   If StringInStr( $bNextFrameHeader, "0x58696E67" ) Then ;Xing
	  $iBitrate="VBR"
   Else
	  $bin2FrameHeader = _HexToBin2($hexFirstFrameHeader); ===>
	  $bin2MPEG_Layer=StringMid($bin2FrameHeader,12,4)
	  $bin2Bitrate=StringMid($bin2FrameHeader,17,4)
	  $iMPEG_LayerCode=_Bin2ToDec($bin2MPEG_Layer); ===>
	  $iBitrateCode=_Bin2ToDec($bin2Bitrate); ===>
	  $iBitrate=$aBitrate[$iBitrateCode][$iMPEG_LayerCode-9]
   EndIf
   Return $iBitrate
EndFunc

Func GetID3V2TagSize($bHeader)
   ; Возвращается размер без размера заголовка
   If BinaryMid($bHeader,1,3)<> "0x494433" Then Return SetError(1,0,-1)
   $bin2TagSize = _HexToBin2(StringRegExpReplace($bHeader,"0x.{12}(.+)","\1"))
   $sPattern=".(.{7})"
   $bin2TagSize=StringRegExpReplace($bin2TagSize,$sPattern,'\1');Удаление significant- битов
   If @extended=0 Then Return SetError(2, 0, -1)
   $iTagSize = Dec(_Bin2ToHex($bin2TagSize))
   Return  $iTagSize
EndFunc

Func _Bin2ToDec($bin2Str)
   $ilen=StringLen($bin2Str)
   Local $iRez=0
   For $i=1 To $ilen 
	  $iI=StringMid($bin2Str,$i,1)
	  $iRez+=$iI*2^($ilen-$i)
   Next 
   Return $iRez
EndFunc	 ; ====> Bin2ToDec

Func _HexToBin2($hexStr)
   Local $sString='0123456789ABCDEF'
   Local $aBin2Codes[17]=[16,'0000','0001','0010','0011','0100','0101','0110','0111','1000','1001','1010','1011','1100','1101','1110','1111']
   $bin2Rez=''
   For $i =1 To StringLen($hexStr)
	  $hexFragment=StringMid($hexStr,$i,1)
	  $iIndex=StringInStr ( $sString,$hexFragment)
	  $bin2Rez &= $aBin2Codes[$iIndex]
   Next
   Return $bin2Rez
EndFunc ; ====> HexToBin2

Func _Bin2ToHex($bin2Str)
   Local $sString='0123456789ABCDEF'
   Local $aBin2Codes[17]=[16,'0000','0001','0010','0011','0100','0101','0110','0111','1000','1001','1010','1011','1100','1101','1110','1111']
   $hexRez=''
   For $i =1 To StringLen($bin2Str) step 4
	  $bin2Fragm=StringMid($bin2Str,$i,4)
	  $iIndex=_ArraySearch($aBin2Codes,$bin2Fragm,0,0,0,1)
	  $hexRez &= StringMid($sString,$iIndex,1)
   Next
   FileClose ($hFile)
   Return $hexRez
EndFunc ; ====> Bin2ToHex

Здесь Битрейт находится в процессе нахожления тегов ID3
Что весьма удобно.
Просьба потестировать
 
Верх