länge eine Mp3 Datei

  • Hi,

    weiß jemand wie ich die Gesamt-länge einer MP3 ermittle und die momentane Position in der Datei?

    schönen Dank :!:

    ---
    In "Independence Day" konnten die Windows-Erdcomputer problemlos mit denen der Außerirdischen kommunizieren. Was sagt uns das über unseren lieben Bill Gates? :D
    ---

    Einmal editiert, zuletzt von franzp (13. November 2008 um 21:44)

  • also möglich ist das schon, aber nicht so einfach als erstes musst du wissen wie eine mp3 aufgebaut ist. Habe vor einiger Zeit mich auch mal damit beschäftigt und diese .svg gefunden die alles sehr anschaulich verdeutlich. Aber dann kommt es drauf an, ob die Datei eine vbr ist oder konstant. (vb example)
    link zum Bild

    du kannst aber auch die Länge über die wmp-objekt bekommen

    • Offizieller Beitrag

    Hi,

    hier ein altes Skript, dass meiner Mutter hilft um aus mp3 CDs eine Playlist zu erstellen.

    Spoiler anzeigen
    [autoit]

    #Region ;**** Directives created by AutoIt3Wrapper_GUI ****
    #AutoIt3Wrapper_icon=..\..\..\Icons\Music-icon.ico
    #AutoIt3Wrapper_outfile=..\..\..\..\Dokumente und Einstellungen\xf01145\Desktop\printPlaylist.exe
    #AutoIt3Wrapper_Res_Comment=Erstellen einer Playlist.txt
    #AutoIt3Wrapper_Res_Description=Erstellen einer Playlist.txt
    #AutoIt3Wrapper_Res_LegalCopyright=Mega
    #AutoIt3Wrapper_Res_Language=1031
    #EndRegion ;**** Directives created by AutoIt3Wrapper_GUI ****
    #include<File.au3>

    [/autoit] [autoit][/autoit] [autoit]

    Global $SongLength = 55, $songCounted = 0
    Global $directory = FileSelectFolder("Ordner auswählen aus dem die MP3-Dateien zu einer Playlist umgewandelt werden sollen: ", "", 6)
    If @error Then Exit (0)
    If StringLen($directory) > 3 Then $directory &= "\"

    [/autoit] [autoit][/autoit] [autoit]

    Global $FileList = _FileListToArray($directory, '*.mp3')

    [/autoit] [autoit][/autoit] [autoit]

    If (Not IsArray($FileList)) And (@error = 1) Then
    MsgBox(0, "", "No Files\Folders Found.")
    Exit
    EndIf
    Global $file = FileOpen(@DesktopDir & '\Playlist_' & @MDAY & '_' & @MON & '_' & @YEAR & '.txt', 2 + 8)

    [/autoit] [autoit][/autoit] [autoit]

    If $file = -1 Then
    MsgBox(0, "Error", "Unable to open file.")
    Exit
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    ; Headline
    FileWriteLine($file, 'Nr.' & " | " & fullfill($SongLength + 1, "Song", " ") & "| " & 'Duration')
    FileWriteLine($file, '--------------------------------------------------------------------------')

    [/autoit] [autoit][/autoit] [autoit]

    For $i = 1 To UBound($FileList) - 1
    $info_A = _GetMP3Info ($directory & $FileList[$i])
    If StringLen($FileList[$i]) >= $SongLength Then
    FileWriteLine($file, StringFormat('%0.3d', $i) & " | " & StringLeft($FileList[$i], $SongLength) & " | " & _checkTime($info_A[5]))
    Else
    FileWriteLine($file, StringFormat('%0.3d', $i) & " | " & fullfill($SongLength, $FileList[$i], ' ') & " | " & _checkTime($info_A[5]))
    EndIf
    Next
    FileWriteLine($file, '--------------------------------------------------------------------------')
    MsgBox(64, 'Info', 'Die Playlist wurde in' & @CRLF & @CRLF & _
    @DesktopDir & '\Playlist_' & @MDAY & '_' & @MON & '_' & @YEAR & '.txt' & @CRLF & @CRLF & "gespeichert.")
    FileClose($file)

    [/autoit] [autoit][/autoit] [autoit]

    Func _GetExtProperty($sPath, $iProp)
    Local $iExist, $sFile, $sDir, $oShellApp, $oDir, $oFile, $aProperty, $sProperty
    $iExist = FileExists($sPath)
    If $iExist = 0 Then
    SetError(1)
    Return 0
    Else
    $sFile = StringTrimLeft($sPath, StringInStr($sPath, "\", 0, -1))
    $sDir = StringTrimRight($sPath, (StringLen($sPath) - StringInStr($sPath, "\", 0, -1)))
    $oShellApp = ObjCreate("shell.application")
    $oDir = $oShellApp.NameSpace ($sDir)
    $oFile = $oDir.Parsename ($sFile)
    If $iProp = -1 Then
    Local $aProperty[35]
    For $i = 0 To 34
    $aProperty[$i] = $oDir.GetDetailsOf ($oFile, $i)
    Next
    Return $aProperty
    Else
    $sProperty = $oDir.GetDetailsOf ($oFile, $iProp)
    If $sProperty = "" Then
    Return 0
    Else
    Return $sProperty
    EndIf
    EndIf
    EndIf
    EndFunc ;==>_GetExtProperty

    [/autoit] [autoit][/autoit] [autoit]

    Func _checkTime($time)
    Return StringRegExpReplace($time, '\b\d:\d\d', 0 & '\0')
    EndFunc ;==>_checkTime

    [/autoit] [autoit][/autoit] [autoit]

    Func fullfill($maxLength, $string, $fullFillChar)
    ; $maxLength = maximum string size
    ; $fullFillChar = char to fullfill the string
    While 1
    If StringLen($string) < $maxLength Then
    $string &= $fullFillChar
    ContinueLoop
    EndIf
    ExitLoop
    WEnd
    Return $string
    EndFunc ;==>fullfill

    [/autoit] [autoit][/autoit] [autoit]

    ;===============================================================================
    ;
    ; Description: Retrieve MP3 (MP2, MPA) basic information
    ; Parameter(s): File name
    ; Requirement(s): None
    ; Return Value(s): On Success - array with data:
    ; 0 - MPEG version
    ; 1 - Layer
    ; 2 - Bitrate
    ; 3 - Frequency
    ; 4 - Channel Mode
    ; 5 - Duration
    ; 6 - Frames
    ; 7 - CRC protected
    ; 8 - Copyrighted
    ; 9 - Original
    ; On Failure empty string and sets @ERROR:
    ; 1 - Info not found
    ; Author(s): YDY (Lazycat) <[email='mpc@nm.ru'][/email]>
    ; Version: 1.2.00
    ; Date: 30.12.2004
    ; Note(s): None
    ;
    ;===============================================================================
    Func _GetMP3Info($file)
    Local $data[10], $offset = 1, $isValid = 0, $isVBR = 0
    Local $aVersion = StringSplit("MPEG 2.5|Undefined|MPEG 2.5|MPEG 1", "|")
    Local $aLayer = StringSplit("Undefined|Layer III|Layer II|Layer I", "|")
    Local $sBitrate = ""
    Local $sFrequency = ""
    Local $aChanMode = StringSplit("Stereo|Joint stereo|Dual channel|Mono", "|")
    Local $aFlags = StringSplit("No|Yes", "|")
    Local $head, $nVer, $nLay

    [/autoit] [autoit][/autoit] [autoit]

    If _FileReadAtOffsetHEX ($file, 1, 3) = "494433" Then ; ID3v2 tag found
    $offset = _HEXToSSInt(_FileReadAtOffsetHEX ($file, 7, 4)) + 10 ; End of ID3v2 tag
    Endif

    [/autoit] [autoit][/autoit] [autoit]

    For $ic = $offset to 4096 + $offset
    $marker = _FileReadAtOffsetHEX ($file, $ic, 2)
    $marker = StringLeft($marker, 3)
    If StringInStr("FFF,FFE", $marker) Then ; Assume that is frame start
    $head = _HexToBin(_FileReadAtOffsetHEX ($file, $ic, 4))
    $nVer = _GetRBits($head, 19, 2)
    $nLay = _GetRBits($head, 17, 2)
    If ($nVer <> 1) and ($nLay <> 0) Then
    If _FileReadAtOffsetHEX ($file, $ic+36, 4) = "58696E67" Then $isVBR = 1 ; Is this a right way?..
    $isValid = 1
    Exitloop
    Endif
    Endif
    Next

    [/autoit] [autoit][/autoit] [autoit]

    If not $isValid Then
    SetError(1) ; Frame not found (not mp3 data?)
    Return ("")
    Endif

    [/autoit] [autoit][/autoit] [autoit]

    Select
    Case $nVer = 3
    $sFrequency = "44100|48000|32000|Undefined"
    Case $nVer = 2
    $sFrequency = "22050|24000|16000|Undefined"
    Case $nVer = 0
    $sFrequency = "11025|12000|8000|Undefined"
    EndSelect
    Local $aFrequency = StringSplit($sFrequency, "|")
    $data[3] = _GetData($aFrequency, _GetRBits($head, 10, 2))

    [/autoit] [autoit][/autoit] [autoit]

    Local $pad = 0, $bitrate, $framesize, $frames, $length, $fps
    If _GetRBits($head, 9, 1) Then $pad = 1

    [/autoit] [autoit][/autoit] [autoit]

    If $isVBR Then
    $data[2] = "Variable"
    Else
    Select
    Case $nVer = 3 and $nLay = 3
    $sBitrate = "Free|32|64|96|128|160|192|224|256|288|320|352|384|416|448|Undefined"
    Case $nVer = 3 and $nLay = 2
    $sBitrate = "Free|32|48|56|64|80|96|112|128|160|192|224|256|320|384|Undefined"
    Case $nVer = 3 and $nLay = 1
    $sBitrate = "Free|32|40|48|56|64|80|96|112|128|160|192|224|256|320|Undefined"
    Case $nVer = 2 and $nLay = 3
    $sBitrate = "Free|32|48|56|64|80|96|112|128|144|160|176|192|224|256|Undefined"
    Case ($nVer = 2 and $nLay = 2) or ($nVer = 2 and $nLay = 1)
    $sBitrate = "Free|8|16|24|32|40|48|56|64|80|96|112|128|144|160|Undefined"
    EndSelect
    Local $aBitrate = StringSplit($sBitrate, "|")
    $data[2] = _GetData($aBitrate, _GetRBits($head, 12, 4))
    $bitrate = 1000 * $data[2]
    If $nLay = 3 Then
    $framesize = (((12 * $bitrate) / $data[3]) + $pad) * 4
    $fps = $data[3]/384
    Else
    $framesize = ((144 * $bitrate) / $data[3]) + $pad
    $fps = $data[3]/1152
    Endif
    $frames = FileGetSize($file) / $framesize
    $length = $frames / $fps
    Endif

    [/autoit] [autoit][/autoit] [autoit]

    $data[0] = _GetData($aVersion, $nVer)
    $data[1] = _GetData($aLayer, $nLay)
    $data[4] = _GetData($aChanMode, _GetRBits($head, 6, 2))
    $data[5] = StringFormat("%d:%02d", Int($length / 60), $length - Int($length / 60) * 60)
    $data[6] = Int($frames)
    $data[7] = _GetData($aFlags, not _GetRBits($head, 16, 1)) ; CRC
    $data[8] = _GetData($aFlags, _GetRBits($head, 3, 1)) ; Private
    $data[9] = _GetData($aFlags, _GetRBits($head, 2, 1)) ; Original
    Return($data)
    EndFunc

    [/autoit] [autoit][/autoit] [autoit]

    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Support functions ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

    [/autoit] [autoit][/autoit] [autoit]

    Func _GetRBits($str, $pos, $size)
    Local $ic, $res = 0, $bStr = StringMid($str, 33 - $pos - $size, $size)
    For $ic = 0 to $size-1
    If StringMid($bStr, $size-$ic, 1) == "1" Then $res = $res + 2^$ic
    Next
    Return ($res)
    EndFunc

    [/autoit] [autoit][/autoit] [autoit]

    Func _GetData(ByRef $array, $val)
    If $val > UBound($array)-1 Then Return("Undefined")
    Return ($array[$val+1])
    EndFunc

    [/autoit] [autoit][/autoit] [autoit]

    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Common functions ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

    [/autoit] [autoit][/autoit] [autoit]

    Func _HEXToSSInt($sHexStr)
    Local $iCnt, $iLen, $sTempStr = "", $iReturn = 0
    For $iCnt = 1 to StringLen($sHexStr) Step 2
    $sTempStr = $sTempStr & StringTrimLeft(_HexToBin(StringMid($sHexStr, $iCnt, 2)), 1)
    Next
    $iLen = StringLen($sTempStr)
    For $iCnt = 0 To $iLen - 1
    $iReturn = $iReturn + Number(StringMid($sTempStr, $iLen - $iCnt, 1)) * 2^$iCnt
    Next
    Return($iReturn)
    EndFunc

    [/autoit] [autoit][/autoit] [autoit]

    Func _HexToBin($str)
    Local $res="", $i
    While StringLen($str) > 0
    $val = Dec(StringRight($str, 1))
    $str = StringTrimRight($str, 1)
    For $i = 1 to 4
    $res = String(Mod($val, 2)) & $res
    $val = Int($val/2)
    Next
    Wend
    Return ($res)
    EndFunc

    [/autoit] [autoit][/autoit] [autoit]

    Func _FileReadAtOffsetHEX ($file, $offset, $bytes)
    Local $tfile = FileOpen($file, 0)
    Local $tstr = "", $i
    FileRead($tfile, $offset-1)
    For $i = $offset To $offset + $bytes - 1
    $tstr = $tstr & Hex(Asc(FileRead($tfile, 1)), 2)
    Next
    FileClose($tfile)
    Return ($tstr)
    Endfunc

    [/autoit]

    Mega

  • vielen Dank

    _getmp3info wäre genau das was ich brauche.. Allerdings scheint die UDF nicht mit allen mp3´s zurecht zu kommen. Bei einigen wird einfach als Duration 0:00 angezeigt bei anderen hängt gibt die udf ganz auf und gibt @error.

    Was für Voraussetzungen brauchen die MP3´s denn?

    @leviathan.. Danke für die tipps. Evtl. liegt das natürlich genau an den Unterschied von vbr und konstant, dass die UDF durcheinander bringt. Aber es würde mir ja auch ein externes Kommandozeilen Programm reichen, dass z.B. einfach "mp3info.exe bla.mp3" als ergebnis die Informationen des Titels ausgibt.. Vielleicht gibt es sowas ja ... braucht ja kein Autoit code sein :D

    schöne Grüße

    Franz

    ---
    In "Independence Day" konnten die Windows-Erdcomputer problemlos mit denen der Außerirdischen kommunizieren. Was sagt uns das über unseren lieben Bill Gates? :D
    ---

  • [autoit]

    Filegetversion

    [/autoit]

    geht leider nicht.. :S aber wäre schön gewesen.

    EDIT:

    gelöst... mit _GetExtProperty zeigt er immer die richtige Dauer an.. SUPER vielen Dank! :D

    ---
    In "Independence Day" konnten die Windows-Erdcomputer problemlos mit denen der Außerirdischen kommunizieren. Was sagt uns das über unseren lieben Bill Gates? :D
    ---

    3 Mal editiert, zuletzt von franzp (13. November 2008 um 16:58)