import Foundation struct AudioPlayerCommand: CommandProcessor { static let commandType: CommandType = .audioPlayer let content: Content let results: PageGenerationResults init(content: Content, results: PageGenerationResults, language: ContentLanguage) { self.content = content self.results = results } func process(_ arguments: [String], markdown: Substring) -> String { guard arguments.count == 2 else { invalid("Invalid audio player arguments") return "" } let fileId = arguments[0] let titleText = arguments[1] guard content.isValidIdForFile(fileId) else { invalid("Invalid file id \(fileId) for audio player") return "" } guard let file = content.file(fileId) else { results.missing(file: fileId, source: "Audio player song list") return "" } guard let data = file.dataContent() else { results.inaccessibleContent(file: file) return "" } let songs: [Song] do { songs = try JSONDecoder().decode([Song].self, from: data) } catch { results.invalidFormat(file: file, error: "Not valid JSON containing [Song]: \(error)") return "" } var playlist: [AudioPlayer.PlaylistItem] = [] var amplitude: [AmplitudeSong] = [] for song in songs { guard let image = content.file(song.cover) else { results.missing(file: song.cover, containedIn: file) continue } guard image.type.isImage else { results.warning("Cover '\(song.cover)' in file \(fileId) is not an image file") continue } guard let audioFile = content.file(song.file) else { results.missing(file: song.cover, containedIn: file) continue } guard audioFile.type.isAudio else { results.warning("Song '\(song.file)' in file \(fileId) is not an audio file") continue } let coverSize = 2 * content.settings.audioPlayer.playlistCoverImageSize let coverImage = image.imageVersion(width: coverSize, height: coverSize, type: image.type) let coverUrl = coverImage.outputPath results.require(image: coverImage) results.require(file: audioFile) let playlistItem = AudioPlayer.PlaylistItem( index: playlist.count, image: coverUrl, name: song.name, album: song.album, track: song.track, artist: song.artist) let amplitudeSong = AmplitudeSong( name: song.name, artist: song.artist, album: song.album, track: "\(song.track)", url: audioFile.absoluteUrl, cover_art_url: coverUrl) playlist.append(playlistItem) amplitude.append(amplitudeSong) } let footerScript = AudioPlayerScript(items: amplitude).content results.require(footer: footerScript) results.require(headers: .audioPlayerCss, .audioPlayerJs) results.require(icons: .audioPlayerClose, .audioPlayerPlaylist, .audioPlayerNext, .audioPlayerPrevious, .audioPlayerPlay, .audioPlayerPause ) return AudioPlayer(playingText: titleText, items: playlist).content } }