GetMP3Length
Author: valtzu
Added: 18. huhtikuuta 2011 kello 23.06
Edited: 18. huhtikuuta 2011 kello 23.06
Category: Ääni & musiikki
Description
Laskee MP3 -kappaleen pituuden sekunteina. Uudelleenkirjoitettu versio, jonka pitäisi tunnistaa lähes kaikenlaiset mp3:set.
Code
Select all1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 | Function GetMP3Length(fileName As String)
If Not FileExists(filename) Then Return False
s = FileSize(fileName)
f = OpenToRead(fileName)
songLength = 0
vbr = False
tagEndOffset = 0 // Missä kohtaa ID3v2-tagi loppuu
Repeat
// Luetaanpa big endian dword
fourr= ReadByte(f)Shl 24+ReadByte(f)Shl 16+ReadByte(f) Shl 8+ReadByte(f)
If (fourr Shr 8) = $334449 Then // "ID3"
SeekFile f, FileOffset(f)+2
tagSize = ReadInt(f)
tagSize = tagSize Shl 1 Shr 25+tagSize Shl 9 Shr 25 Shl 7+tagSize Shl 17 Shr 25 Shl 14+tagSize Shl 25 Shr 25 Shl 21
tagEndOffset=FileOffset(f)+tagSize
SeekFile f, tagEndOffset
ElseIf fourr Shr 21 = 2047 Then // 0b11111111111
mpegVer = fourr Shl 11 Shr 30 // 0 = mpeg-2.5, 1=-, 2=mpeg-2, 3=mpeg-1
layer = fourr Shl 13 Shr 30 // 0 = -, 1=III, 2=II, 3=I
crcProt = fourr Shl 15 Shr 31 // 0 = protected, 1=not protected
brIndex = fourr Shl 16 Shr 28 // should not be 1111
srIndex = fourr Shl 20 Shr 30 // 0=44100,1=48000,2=32000,3=-
padding = fourr Shl 22 Shr 31 // 0=not padded
channel = fourr Shl 24 Shr 30 // 0=stereo, 1=joint stereo, 2=dual mono, 3=mono
If crcProt = 0 Then crc = ReadShort(f)
If brIndex < 15 Then
If mpegVer = 2 Or mpegVer = 0 Then
Select layer
Case 2,1: bitRates$="000008016024032040048056064080096112128144160"
Case 0,3: bitRates$="000032048056064080096112128144160176192224256"
End Select
bitRate = Int(Mid(bitRates,brIndex*3+1,3))*1000
If mpegVer = 2 Then
sampleRate = Int(Mid("1600220524000000",srIndex*4+1,4))*10
Else
sampleRate = Int(Mid("11025120000800000000",srIndex*5+1,5))
EndIf
samplesPerFrame = Mid("038411520576",Int(Min(2,3-layer))*4+1,4)
Else
Select layer
Case 3 : bitRates$="000032064096128160192224256288320352384416448"
Case 2 : bitRates$="000032048056064080096112128160192224256320384"
Case 1,0: bitRates$="000032040048056064080096112128160192224256320"
End Select
bitRate = Int(Mid(bitRates$,brIndex*3+1,3))*1000
sampleRate = Int(Mid("441480320000",srIndex*3+1,3))*100
samplesPerFrame = Mid("038411521152",Int(Min(2,3-layer))*4+1,4)
EndIf
If layer = 3 Then
frameLen = RoundDown(12.0*bitRate/sampleRate+padding)*4
Else
frameLen = RoundDown((144.0*bitRate/sampleRate)+padding)
EndIf
nextOffset = FileOffset(f)+frameLen
// ainoastaan mpeg-1 ja mpeg-2 voi olla vbr:ää
If mpegVer = 3 Or mpegVer = 2 Then
If mpegVer = 3 Then
xingOff = 21 + 15*(channel<>3)
Else
xingOff = 13 + 8*(channel<>3)
EndIf
SeekFile f, FileOffset(f)+xingOff-4
If ReadInt(f) = $58696E67 Then // "Xing"
vbr = True
If ReadInt(f) Shr 24 Mod 2 Then
vbrFrameC = ReadInt(f)
vbrFrameC = vbrFrameC Shr 24+vbrFrameC Shl 24+vbrFrameC Shl 8 Shr 24 Shl 8+vbrFrameC Shl 16 Shr 24 Shl 16
songLength = vbrFrameC*samplesPerFrame/sampleRate
Exit
EndIf
Else
vbr = False
Exit
EndIf
EndIf
If nextOffset>=s Then Exit
SeekFile f, nextOffset // hypätään seuraavan framen alkuun
Else
// eipä löytynyt haluamaaamme, joten palataan takaisin päin
SeekFile f, FileOffset(f)-3
EndIf
Else
// mennäänpä taaksepäin, koska ei löytynyt, mitä etsittiin
SeekFile f, FileOffset(f)-3
EndIf
Until FileOffset(f)>s-5 Or songLength
CloseFile f
// Jos tiedosto ei ollut vbr-muodossa,niin lasketaan pituus suoraan bitratesta
If (Not vbr) And bitRate Then songLength = (s-tagEndOffset)*8/bitRate
Return songLength
End Function
mp3file$ = "Media\SK_Battle2.mp3"
songLength = GetMP3Length(mp3file)
If songLength Then // Onnistuiko?
Print "The song "+mp3file+" is "+songLength+" seconds long."
Else
Print "Error occured :("
EndIf
WaitKey
|
Comments
No comments. You can be first!
Leave a comment
You must be logged in to comment.