Musikplayer - Paar Problemchen

  • Hallo.

    Ich habe gestern angefangen einen kleinen Musikplayer zu schreiben.
    Dabei wird ein Treeview mit allen Ordnern im gleichen Verzeichnis erstellt (auch Unterordner). Eine Listview zeigt die Dateien im ausgewählten Ordner.
    Um mp3-Dateien abzuspielen verwende ich die Sound.au3.
    Allerdings lassen sich nicht alle mp3-Lieder von mir öffnen, bei vielen kommt der MCI Openerror. Liegt das am Codec, an der Bitrate?
    Ein zweites Problem ist, dass generell eine falsche Gesamtzeit der Lieder angezeigt wird.
    Beispiel: Madcon - Freaky like me -> geht in Wirklichkeit 3 Min und 9 Sek, _SoundGetLength spuckt aber 3 Min und 12 Sekunden aus. Bei anderen Liedern liegt AutoIt um über eine Minute daneben...

    Hier ist das Script:

    Spoiler anzeigen
    [autoit]

    Dim $vMExt = "*.mp3", $vOldSelectedFolder, $vPath
    Dim $vSound

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

    #include <GUIListView.au3>
    #Include <GuiTreeView.au3>
    #Include <Sound.au3>

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

    $hGUI = GUICreate("Musikplayer", 600, 400)
    $hFolderList = GUICtrlCreateTreeView(0, 0, 200, 400)
    $hFolderListHandle = GUICtrlGetHandle($hFolderList)
    $hFileList = GUICtrlCreateListView("Name|Titel|Interpret|Album", 200, 0, 400, 370)
    $hFileListHandle = GUICtrlGetHandle($hFileList)
    _GUICtrlListView_SetColumnWidth($hFileListHandle, 0, 200)
    $hGUIButtonPlayPause = GUICtrlCreateButton("Play", 205, 372, 50)
    $hGUIButtonStop = GUICtrlCreateButton("Stop", 260, 372, 50)
    $hGUILabelPos = GUICtrlCreateLabel("", 350, 375, 100, 15)
    GUISetState()

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

    CreateFolderTreeView($hFolderList)

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

    While 1
    Switch GUIGetMsg($hGUI)
    Case -3
    _SoundClose($vSound)
    Exit
    Case $hGUIButtonPlayPause
    If GUICtrlRead($hGUIButtonPlayPause) = "Pause" Then
    _SoundPause($vSound)
    GUICtrlSetData($hGUIButtonPlayPause, "Play")
    Else
    If _SoundResume($vSound) = 0 Then
    $vSound = _SoundOpen($vPath & "\" & _GUICtrlListView_GetItemText($hFileListHandle, _GUICtrlListView_GetSelectedIndices($hFileListHandle), 0))
    If $vSound = 0 Then
    MsgBox(16, "Datei kann nicht wiedergegeben werden", "Die ausgewählte Datei kann nicht widergegeben werden.")
    Else
    _SoundResume($vSound)
    GUICtrlSetData($hGUIButtonPlayPause, "Pause")
    EndIf
    $vSoundLength = _SoundLength($vSound)
    Else
    GUICtrlSetData($hGUIButtonPlayPause, "Pause")
    EndIf
    EndIf

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

    Case $hGUIButtonStop
    _SoundClose($vSound)
    If GUICtrlRead($hGUIButtonPlayPause) <> "Play" Then GUICtrlSetData($hGUIButtonPlayPause, "Play")
    EndSwitch

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

    If GUICtrlRead($hGUIButtonPlayPause) = "Pause" Then
    $vPos = _SoundPos($vSound) & " - " & $vSoundLength
    If GUICtrlRead($hGUILabelPos) <> $vPos Then GUICtrlSetData($hGUILabelPos, $vPos)
    EndIf

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

    _RefreshPlayList()
    WEnd

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

    Func _RefreshPlayList()
    $vSelectedFolder = GUICtrlRead($hFolderList)
    If $vSelectedFolder <> $vOldSelectedFolder Then
    $vOldSelectedFolder = $vSelectedFolder
    $vPath = GUICtrlRead($vSelectedFolder, 1)
    $vCurrentFolder = $vSelectedFolder

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

    While 1
    $vParentID = _GUICtrlTreeView_GetParentParam($hFolderList, $vCurrentFolder)
    If $vParentID = False Then ExitLoop
    $vPath = GUICtrlRead($vParentID, 1) & "\" & $vPath
    $vCurrentFolder = $vParentID
    WEnd

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

    ;List Files
    _GUICtrlListView_DeleteAllItems($hFileListHandle)
    $hSearch = FileFindFirstFile($vPath & "\" & $vMExt)
    While 1
    $vFileFound = FileFindNextFile($hSearch)
    If @error = 1 Then ExitLoop
    GUICtrlCreateListViewItem($vFileFound, $hFileList)
    WEnd
    FileClose($hSearch)
    EndIf
    EndFunc

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

    ;$h_TreeView = id of treeview
    ;$v_Folder = the folder to scan, leave it empty if you wanna scan the scriptdir
    Func CreateFolderTreeView($h_TreeView, $v_Folder = "")
    If $v_Folder <> "" And StringRight($v_Folder, 1) <> "\" Then $v_Folder &= "\"
    $hSearch = FileFindFirstFile($v_Folder & "*")

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

    While 1
    $vFolderFound = FileFindNextFile($hSearch)
    If @error = 1 Then ExitLoop
    If FileGetAttrib($v_Folder & $vFolderFound) = "D" Then
    $vDirInfo = DirGetSize($v_Folder & $vFolderFound, 1)
    $vSubItem = GUICtrlCreateTreeViewItem($vFolderFound, $h_TreeView)
    If IsArray($vDirInfo) And $vDirInfo[2] >= 1 Then CreateFolderTreeView($vSubItem, $v_Folder & $vFolderFound)
    EndIf
    WEnd
    FileClose($hSearch)
    EndFunc

    [/autoit]

    Ich danke für jede Hilfe.

  • Hallo,
    ich kann leider keinen deiner Fehler reproduzieren, Autoit liegt bei mir höchstens um eine Sekunde mit der Soundlänge daneben.
    Bei mir ließen sich problemlos alle Songs abspielen, habe da leider überhaupt kein Problem
    Könntest du die Fehlermeldung etwas genauer beschreiben und evtl. auch die Sounddatei? Vielleicht lässt sich anhand davon ein Fehler rauskristialiseren.

    • Offizieller Beitrag

    Die _Sound-Funktionen haben Probleme, wenn es sich nicht um "echte" MP3s handelt. Das heißt, es muss beim erstellen wirklich MPEG1 Layer III (wird als MP3 bezeichnet) verwendet worden sein.
    Wird beispielsweise MPEG1 Layer I verwendet (diese werden oft auch mit der Endung MP3 angelegt), so werden die Zeiten nicht korrekt berechnet.

    Wenn Du das umgehen willst, benutze die BASS-UDF.

  • Zu der Länge der Lieder: Habe gerade von Only Girl von Rihanna getestet, welches in Wirklichkeit 3:57 lang ist. In AutoIt wird 6:12 angezeigt...

    Zum Fehler: Bei allen Liedern die nicht gehen, ist @error nach _SoundOpen = 1 => @error: 1 = MCI open error
    Bitrate von dem Lied ist: 202 kBit/s

    @Oskar:
    Okay, muss ich diese wohl nutzen...

  • Bei mir funktioniert das Script. Er spielt auch Lieder die bis zu 1 Stunde gehen problemlos ab. :huh:
    Keine Ahnung was du für ein Problem mit deinem Script hast. ?(

    Mit freundlichen Grüßen

    volle

  • Hi, ich bin es wieder. Habe heute die Bass-Funktionen integriert. Allerdings finde ich ich keine Funktionen, die mir die gesamte Länge und derzeitige Position des Liedes zurückgeben (in gesamt ms oder s, oder in hh:mm:ss). Wie komme ich an diese Werte?

  • Das hier dürfte hoffentlich helfen:

    Spoiler anzeigen
    [autoit]

    $Track = [...]

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

    $Aktuell = StringTrimLeft(Sekunden_Umrechnung(_BASS_ChannelBytes2Seconds($Track, _BASS_ChannelGetPosition($Track, $BASS_POS_BYTE))), 3) ; MM:SS , ohne "StringTrimLeft([...], 3)" wieder HH:MM:SS
    $Gesamt = StringTrimLeft(Sekunden_Umrechnung(_BASS_ChannelBytes2Seconds($Track, _BASS_ChannelGetLength($Track, $BASS_POS_BYTE))), 3) ; MM:SS , ohne "StringTrimLeft([...], 3)" wieder HH:MM:SS
    MsgBox(0, "", $Aktuell & " / " & $Gesamt)

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

    Func Sekunden_Umrechnung($Sekunden_Ungerundet)
    Return StringFormat("%02d:%02d:%02d", Floor($Sekunden_Ungerundet / 3600), Mod(Floor($Sekunden_Ungerundet / 60), 60), Mod($Sekunden_Ungerundet, 60)) ; HH:MM:SS
    EndFunc

    [/autoit]


    Grüße, Andy :rolleyes: