local timer = libs.timer; local server = libs.server; local ITPlayerStateStopped = 0; local ITPlayerStatePlaying = 1; local ITPlayerStateFastForward = 2; local ITPlayerStateRewind = 3; local tid_update = -1; local obj = nil; local offset = 0; local page = 100; local last_playlist; local playlists = {}; local tracks = {}; events.detect = function () return libs.fs.exists("C:\\Program Files (x86)\\iTunes") or libs.fs.exists("C:\\Program Files\\iTunes"); end --@help Launch iTunes application actions.launch = function() os.start("itunes"); end events.focus = function () obj = luacom.CreateObject("iTunes.Application"); update_state(); update_lists(); tid_update = timer.timeout(update, 1000); end events.blur = function () timer.cancel(tid_update); obj = nil; collectgarbage(); end function valid() return (obj ~= nil); end function update () if (obj.CurrentPlaylist ~= nil) then if (last_playlist == nil or obj.CurrentPlaylist.playlistID ~= last_playlist.playlistID) then print("playlist changed"); last_playlist = obj.CurrentPlaylist; offset = 0; offset_prev = false; offset_next = false; update_lists(); end end update_state(); tid_update = timer.timeout(update, 1000); end function update_lists () print("updating lists ..."); playlists = {}; tracks = {}; if (valid()) then -- Get playlists local count = obj.LibrarySource.Playlists.Count; for i = 1, count do local playlist = obj.LibrarySource.Playlists(i); table.insert(playlists, { type = "item", text = playlist.Name .. "\nTracks: " .. playlist.Tracks.Count }); end -- Get tracks if (obj.CurrentPlaylist ~= nil) then local total = obj.CurrentPlaylist.Tracks.Count; count = math.min(page, total); local from = math.min(1 + offset, total); local to = math.min(from + page, total); if (from > 1) then table.insert(tracks, { type = "item", text = "Load previous tracks" }); offset_prev = true; end for i = from, to do local track = obj.CurrentPlaylist.Tracks:ItemByPlayOrder(i); table.insert(tracks, { type = "item", text = track.Name .. "\n" .. track.Artist, track = i }); end if (to < total) then table.insert(tracks, { type = "item", text = "Load next tracks" }); offset_next = true; end end end server.update( { id = "playlists", children = playlists }, { id = "tracks", children = tracks } ); print("updating lists: done"); end function update_state () local title = ""; local duration = 0; local position = 0; local volume = 0; local icon = "play"; if (valid()) then -- Get title if (obj.CurrentTrack ~= nil) then title = obj.CurrentTrack.Name .. " - " .. obj.CurrentTrack.Artist; duration = obj.CurrentTrack.Duration; position = obj.PlayerPosition; else title = "[Not Playing]"; end -- Get volume volume = obj.SoundVolume; -- Get state if (obj.PlayerState == ITPlayerStatePlaying) then icon = "pause"; end else title = "[Not Running]"; end server.update( { id = "title", text = title }, { id = "pos", progress = position, progressmax = duration }, { id = "vol", progress = volume }, { id = "play", icon = icon } ); end actions.playlist = function (i) print("playlist: " .. i); if (valid()) then obj:Stop(); obj.LibrarySource.Playlists(i+1).Tracks(1):Play(); update_state(); end end actions.track = function (i) print("track: " .. i); if (valid()) then if (obj.CurrentPlaylist ~= nil) then if (tracks[i+1].text == "Load previous tracks") then offset = offset - page; update_lists(); elseif (tracks[i+1].text == "Load next tracks") then offset = offset + page; update_lists(); else local track = obj.CurrentPlaylist.Tracks:ItemByPlayOrder(tracks[i+1].track); track:Play(); update_state(); end end end end --@help Play Pause track actions.play_pause = function () if (valid()) then obj:PlayPause(); update_state(); end end --@help Play track actions.play = function () if (valid()) then obj:Play(); update_state(); end end --@help Pause track actions.pause = function () if (valid()) then obj:Pause(); update_state(); end end --@help Resume track actions.resume = function () if (valid()) then obj:Resume(); update_state(); end end --@help Stop track actions.stop = function () if (valid()) then obj:Stop(); update_state(); end end --@help Next track actions.next = function () if (valid()) then obj:NextTrack(); update_state(); end end --@help Previous track actions.previous = function () if (valid()) then obj:PreviousTrack(); update_state(); end end --@help Forward track actions.forward = function () if (valid()) then obj:FastForward(); update_state(); end end --@help Rewind track actions.rewind = function () if (valid()) then obj:Rewind(); update_state(); end end --@help Mute Volume actions.volume_mute = function () libs.keyboard.stroke("volumemute"); end --@help Set Volume --@param vol:number Set volume actions.volume = function (vol) if (valid()) then obj.SoundVolume = vol; update_state(); end end --@help Volume up actions.volume_up = function () if (valid()) then obj.SoundVolume = obj.SoundVolume + 10; update_state(); end end --@help Volume Down actions.volume_down = function () if (valid()) then obj.SoundVolume = obj.SoundVolume - 10; update_state(); end end --@help Set Position --@param pos:number Set Position actions.position = function (pos) if (valid()) then obj.PlayerPosition = pos; update_state(); end end