Code:
function Initialize() filePath = SKIN:GetVariable("MP3FilePath") SKIN:Bang("!Log", "Try open mp3 file: " .. filePath)endfunction Update() local result = "" local file, err = io.open(filePath, "rb") if not file then result = "Fehler: " .. tostring(err) -- Bei Fehlern: Variablen setzen SKIN:Bang("!SetVariable", "Interpret", "NA") SKIN:Bang("!SetVariable", "Titel", "NA") SKIN:Bang("!SetVariable", "Albumcover", "NA") SKIN:Bang("!SetVariable", "Filename", "NA") else local fileName = filePath:match("([^/\\]+)$") file:seek("end", -128) local tagIndicator = file:read(3) if tagIndicator == "TAG" then local title = file:read(30) local artist = file:read(30) local album = file:read(30) local year = file:read(4) file:close() title = trim(title) artist = trim(artist) album = trim(album) year = trim(year) result = string.format("Datei: %s\nTitel: %s\nInterpret: %s\nAlbum: %s\nJahr: %s", fileName, title, artist, album, year) SKIN:Bang("!SetVariable", "Interpret", artist) SKIN:Bang("!SetVariable", "Titel", title) SKIN:Bang("!SetVariable", "Filename", fileName) -- Extrahiere das Albumcover: local imagePath, imgErr = ExtractAlbumCover(filePath) if imagePath then SKIN:Bang("!SetVariable", "Albumcover", imagePath) result = result .. "\nAlbumcover extrahiert: " .. imagePath else SKIN:Bang("!SetVariable", "Albumcover", "N/A") result = result .. "\nNo Albumcover (" .. (imgErr or "") .. ")" end else file:close() result = "Keine ID3v1-Metadaten gefunden." SKIN:Bang("!SetVariable", "Interpret", "N/A") SKIN:Bang("!SetVariable", "Titel", "N/A") SKIN:Bang("!SetVariable", "Albumcover", "N/A") SKIN:Bang("!SetVariable", "Filename", fileName or "N/A") end end SKIN:Bang("!Redraw") return 0endfunction trim(s) return s:match("^%s*(.-)%s*$")endfunction ExtractAlbumCover(mp3FilePath) local file, err = io.open(mp3FilePath, "rb") if not file then return nil, err end -- Lese den ID3v2-Header (erste 10 Bytes): local header = file:read(10) if not header or header:sub(1,3) ~= "ID3" then file:close() return nil, "No ID3v2-Tag Information." end local sizeBytes = {header:byte(7,10)} local tagSize = 0 for i = 1, 4 do tagSize = tagSize + (sizeBytes[i] % 128) * 2^(7 * (4 - i)) end local tagData = file:read(tagSize) file:close() if not tagData then return nil, "No Tag Information." end local offset = 1 local apicData = nil while offset <= (#tagData - 10) do local frameHeader = tagData:sub(offset, offset + 9) local frameId = frameHeader:sub(1,4) if frameId == "\0\0\0\0" then break end -- Ende der Frames local frameSize = 0 for i = 1, 4 do frameSize = frameSize + frameHeader:byte(4 + i) * 2^(8 * (4 - i)) end if frameId == "APIC" then apicData = tagData:sub(offset + 10, offset + 9 + frameSize) break end offset = offset + 10 + frameSize end if not apicData then return nil, "APIC-Frame not founded." end -- APIC-Frame parsen: local textEncoding = apicData:byte(1) -- Lese den MIME-Typ (nullterminiert): local mimeEnd = apicData:find("\0", 2, true) if not mimeEnd then return nil, "MIME-Typ nicht gefunden." end local mime = apicData:sub(2, mimeEnd - 1) local pictureType = apicData:byte(mimeEnd + 1) -- Read the description (also zero-terminated): local descStart = mimeEnd + 2 local descEnd = apicData:find("\0", descStart, true) if not descEnd then descEnd = descStart end local description = apicData:sub(descStart, descEnd - 1) -- Der Rest sind die Bilddaten: local imageData = apicData:sub(descEnd + 1) if #imageData == 0 then return nil, "No image data found." end -- Always save the cover as Cover.png in the same directory as the MP3 file: local dir = mp3FilePath:match("^(.*[/\\])") or "./" local imageFilename = dir .. "Cover.png" local imgFile, err = io.open(imageFilename, "wb") if not imgFile then return nil, "Error to create the AlbumCover: " .. err end imgFile:write(imageData) imgFile:close() return imageFilenameend