local C={}local p=game:GetService("\072\116\116\112\083\101\114\118\105\099\101")local d=game:GetService("\084\119\101\101\110\083\101\114\118\105\099\101")local x=false function C.SpitPlaylist(C)for d=1,#C.Playlist,1 do if C.PlaylistPosition~=d then print(d..(" \058   "..p:JSONEncode(C.Playlist[d])))else print(d..(" \058 -\062"..p:JSONEncode(C.Playlist[d])))end end end function C.new()local p={Name="\065\117\100\105\111\080\108\097\121\101\114";Playlist={};PlaylistPosition=0;CurrentAudio={Name="",ID="\114\098\120\097\115\115\101\116\105\100\058\047\047\048"};AutoPlay=false,Looped=false;Sound=Instance.new("\083\111\117\110\100",Workspace);_Destroyed=false;_Events={AudioAdded=Instance.new("\066\105\110\100\097\098\108\101\069\118\101\110\116"),AudioRemoved=Instance.new("\066\105\110\100\097\098\108\101\069\118\101\110\116")}}p.AudioAdded=p._Events.AudioAdded.Event p.AudioRemoved=p._Events.AudioRemoved.Event setmetatable(p,{__index=C})p.Sound.Ended:connect(function()if p.AutoPlay then p:Next()end end)return p end function C.Destroy(C)assert(C._Destroyed==false,"\091\065\117\100\105\111 \080\108\097\121\101\114 \'"..(C.Name.."\'\093 \068\101\115\116\114\111\121\040\041 \058 \067\097\110\110\111\116 \100\101\115\116\114\111\121 \097\110 \097\108\114\101\097\100\121 \100\101\115\116\114\111\121\101\100 \097\117\100\105\111\112\108\097\121\101\114\046"))C._Destroyed=true C.Sound:Destroy()for C,p in pairs(C._Events)do p:Destroy()end end function C.AddAudioAtIndex(X,C,d,I)assert(X._Destroyed==false,"\091\065\117\100\105\111 \080\108\097\121\101\114 \'"..(X.Name.."\'\093 \065\100\100\065\117\100\105\111\065\116\073\110\100\101\120\040\041 \058 \067\097\110\110\111\116 \097\100\100 \097\117\100\105\111 \116\111 \100\101\115\116\114\111\121\101\100 \097\117\100\105\111\112\108\097\121\101\114\046"))assert(C~=nil,"\091\065\117\100\105\111 \080\108\097\121\101\114 \'"..(X.Name.."\'\093 \065\100\100\065\117\100\105\111\065\116\073\110\100\101\120\040\041 \058 \073\110\100\101\120\078\117\109\098\101\114 \101\120\112\101\099\116\101\100\044 \103\111\116 \110\105\108\046"))assert(typeof(C)=="\110\117\109\098\101\114","\091\065\117\100\105\111 \080\108\097\121\101\114 \'"..(X.Name..("\'\093 \065\100\100\065\117\100\105\111\065\116\073\110\100\101\120\040\041 \058 \110\117\109\098\101\114 \101\120\112\101\099\116\101\100 \102\111\114 \073\110\100\101\120\078\117\109\098\101\114\044 \103\111\116 "..(typeof(C).." \105\110\115\116\101\097\100\046"))))if C~=1 then assert(X.Playlist[C-1]~=nil,"\091\065\117\100\105\111 \080\108\097\121\101\114 \'"..(X.Name.."\'\093 \065\100\100\065\117\100\105\111\065\116\073\110\100\101\120\040\041 \058 \073\110\100\101\120 \111\117\116 \111\102 \098\111\117\110\100\115\046"))end assert(d~=nil,"\091\065\117\100\105\111 \080\108\097\121\101\114 \'"..(X.Name.."\'\093 \065\100\100\065\117\100\105\111\065\116\073\110\100\101\120\040\041 \058 \065\117\100\105\111\078\097\109\101 \101\120\112\101\099\116\101\100\044 \103\111\116 \110\105\108\046"))assert(typeof(d)=="\115\116\114\105\110\103","\091\065\117\100\105\111 \080\108\097\121\101\114 \'"..(X.Name..("\'\093 \065\100\100\065\117\100\105\111\065\116\073\110\100\101\120\040\041 \058 \115\116\114\105\110\103 \101\120\112\101\099\116\101\100 \102\111\114 \065\117\100\105\111\078\097\109\101\044 \103\111\116 "..(typeof(d).." \105\110\115\116\101\097\100\046"))))assert(I~=nil,"\091\065\117\100\105\111 \080\108\097\121\101\114 \'"..(X.Name.."\'\093 \065\100\100\065\117\100\105\111\065\116\073\110\100\101\120\040\041 \058 \065\117\100\105\111 \073\068 \101\120\112\101\099\116\101\100\044 \103\111\116 \110\105\108\046"))assert(typeof(I)=="\115\116\114\105\110\103","\091\065\117\100\105\111 \080\108\097\121\101\114 \'"..(X.Name..("\'\093 \065\100\100\065\117\100\105\111\065\116\073\110\100\101\120\040\041\058 \083\116\114\105\110\103 \101\120\112\101\099\116\101\100 \102\111\114 \073\068\044 \103\111\116 "..(typeof(I).." \105\110\115\116\101\097\100\046"))))assert(X:FindAudioByName(d)==false,"\091\065\117\100\105\111 \080\108\097\121\101\114 \'"..(X.Name..("\'\093 \065\100\100\065\117\100\105\111\065\116\073\110\100\101\120\040\041 \058 \065\110 \097\117\100\105\111 \119\105\116\104 \116\104\101 \110\097\109\101 \'"..(d.."\' \097\108\114\101\097\100\121 \101\120\105\115\116\115\033"))))if string.find(I,"\114\098\120\097\115\115\101\116\105\100\058\047\047")==nil then I="\114\098\120\097\115\115\101\116\105\100\058\047\047"..I end table.insert(X.Playlist,C,{Name=d or"\078\101\119\065\117\100\105\111";ID=I})if C<=X.PlaylistPosition then X.PlaylistPosition=X.PlaylistPosition+1 end if X.PlaylistPosition==0 then X:JumpToIndex(1)end if x then print("")print("\091\065\117\100\105\111 \080\108\097\121\101\114 \'"..(X.Name.."\'\093 \065\117\100\105\111 \097\100\100\101\100\046"))print("\065\100\100\101\100 \097\117\100\105\111 \058 "..p:JSONEncode(X.Playlist[C]))print("\078\101\119 \097\117\100\105\111 \108\105\115\116 \058")X:SpitPlaylist()print("")end X._Events.AudioAdded:Fire(d,C)end function C.AddAudio(d,C,p)assert(d._Destroyed==false,"\091\065\117\100\105\111 \080\108\097\121\101\114 \'"..(d.Name.."\'\093 \065\100\100\065\117\100\105\111\040\041 \058 \067\097\110\110\111\116 \097\100\100 \097\117\100\105\111 \116\111 \100\101\115\116\114\111\121\101\100 \097\117\100\105\111\112\108\097\121\101\114\046"))assert(C~=nil,"\091\065\117\100\105\111 \080\108\097\121\101\114 \'"..(d.Name.."\'\093 \065\100\100\065\117\100\105\111\040\041 \058 \065\117\100\105\111\078\097\109\101 \101\120\112\101\099\116\101\100\044 \103\111\116 \110\105\108\046"))assert(typeof(C)=="\115\116\114\105\110\103","\091\065\117\100\105\111 \080\108\097\121\101\114 \'"..(d.Name..("\'\093 \065\100\100\065\117\100\105\111\040\041 \058 \115\116\114\105\110\103 \101\120\112\101\099\116\101\100 \102\111\114 \065\117\100\105\111\078\097\109\101\044 \103\111\116 "..(typeof(C).." \105\110\115\116\101\097\100\046"))))assert(p~=nil,"\091\065\117\100\105\111 \080\108\097\121\101\114 \'"..(d.Name.."\'\093 \065\100\100\065\117\100\105\111\040\041 \058 \065\117\100\105\111 \073\068 \101\120\112\101\099\116\101\100\044 \103\111\116 \110\105\108\046"))assert(typeof(p)=="\115\116\114\105\110\103","\091\065\117\100\105\111 \080\108\097\121\101\114 \'"..(d.Name..("\'\093 \065\100\100\065\117\100\105\111\040\041\058 \083\116\114\105\110\103 \101\120\112\101\099\116\101\100 \102\111\114 \073\068\044 \103\111\116 "..(typeof(p).." \105\110\115\116\101\097\100\046"))))assert(d:FindAudioByName(C)==false,"\091\065\117\100\105\111 \080\108\097\121\101\114 \'"..(d.Name..("\'\093 \065\100\100\065\117\100\105\111\065\116\073\110\100\101\120\040\041 \058 \065\110 \097\117\100\105\111 \119\105\116\104 \116\104\101 \110\097\109\101 \'"..(C.."\' \097\108\114\101\097\100\121 \101\120\105\115\116\115\033"))))d:AddAudioAtIndex(#d.Playlist+1,C,p)end function C.RemoveAudioAtIndex(d,C)assert(d._Destroyed==false,"\091\065\117\100\105\111 \080\108\097\121\101\114 \'"..(d.Name.."\'\093 \082\101\109\111\118\101\065\117\100\105\111\065\116\073\110\100\101\120\040\041 \058 \067\097\110\110\111\116 \114\101\109\111\118\101 \097\117\100\105\111 \102\114\111\109 \100\101\115\116\114\111\121\101\100 \097\117\100\105\111\112\108\097\121\101\114\046"))assert(C~=nil,"\091\065\117\100\105\111 \080\108\097\121\101\114 \'"..(d.Name.."\'\093 \082\101\109\111\118\101\065\117\100\105\111\065\116\073\110\100\101\120\040\041 \058 \073\110\100\101\120\078\117\109\098\101\114 \101\120\112\101\099\116\101\100\044 \103\111\116 \110\105\108\046"))assert(typeof(C)=="\110\117\109\098\101\114","\091\065\117\100\105\111 \080\108\097\121\101\114 \'"..(d.Name..("\'\093 \110\117\109\098\101\114 \101\120\112\101\099\116\101\100 \102\111\114 \073\110\100\101\120\078\117\109\098\101\114\044 \103\111\116 "..(typeof(C).." \105\110\115\116\101\097\100\046"))))assert(d.Playlist[C]~=nil,"\091\065\117\100\105\111 \080\108\097\121\101\114 \'"..(d.Name.."\'\093 \082\101\109\111\118\101\065\117\100\105\111\065\116\073\110\100\101\120\040\041 \058 \073\110\100\101\120 \111\117\116 \111\102 \098\111\117\110\100\115\046"))local I=d.Playlist[C].Name if x then print("")print("\091\065\117\100\105\111 \080\108\097\121\101\114 \'"..(d.Name.."\'\093 \065\117\100\105\111 \114\101\109\111\118\101\100\046"))print("\082\101\109\111\118\101\100 \097\117\100\105\111 \058 "..p:JSONEncode(d.Playlist[C]))end table.remove(d.Playlist,C)if C<d.PlaylistPosition then d.PlaylistPosition=d.PlaylistPosition-1 elseif C==d.PlaylistPosition then if#d.Playlist==0 then d.CurrentSong={Name="";ID="\114\098\120\097\115\115\101\116\105\100\058\047\047\048"}d.PlaylistPosition=0 elseif d.PlaylistPosition>#d.Playlist then d:JumpToIndex(#d.Playlist)else d:JumpToIndex(d.PlaylistPosition)end end if x then print("\078\101\119 \097\117\100\105\111 \108\105\115\116 \058")d:SpitPlaylist()print("")end d._Events.AudioRemoved:Fire(I,C)end function C.RemoveAudio(p,C)assert(p._Destroyed==false,"\091\065\117\100\105\111 \080\108\097\121\101\114 \'"..(p.Name.."\'\093 \082\101\109\111\118\101\065\117\100\105\111\040\041 \058 \067\097\110\110\111\116 \114\101\109\111\118\101 \097\117\100\105\111 \102\114\111\109 \100\101\115\116\114\111\121\101\100 \097\117\100\105\111\112\108\097\121\101\114\046"))assert(C~=nil,"\091\065\117\100\105\111 \080\108\097\121\101\114 \'"..(p.Name.."\'\093 \082\101\109\111\118\101\065\117\100\105\111\040\041 \058 \078\097\109\101 \101\120\112\101\099\116\101\100\044 \103\111\116 \110\105\108\046"))assert(typeof(C)=="\115\116\114\105\110\103","\091\065\117\100\105\111 \080\108\097\121\101\114 \'"..(p.Name..("\'\093 \082\101\109\111\118\101\065\117\100\105\111\040\041 \058 \115\116\114\105\110\103 \101\120\112\101\099\116\101\100 \102\111\114 \078\097\109\101\044 \103\111\116 "..(typeof(C).." \105\110\115\116\101\097\100\046"))))local d,x=p:FindAudioByName(C)assert(d==true,"\091\065\117\100\105\111 \080\108\097\121\101\114 \'"..(p.Name..("\'\093 \082\101\109\111\118\101\065\117\100\105\111\040\041 \058 \067\111\117\108\100 \110\111\116 \114\101\109\111\118\101 \097\117\100\105\111 \'"..(C.."\'\044 \097\117\100\105\111 \119\097\115 \110\111\116 \102\111\117\110\100\046"))))p:RemoveAudioAtIndex(x)end function C.RemoveAllAudio(C)assert(C._Destroyed==false,"\091\065\117\100\105\111 \080\108\097\121\101\114 \'"..(C.Name.."\'\093 \082\101\109\111\118\101\065\117\100\105\111\040\041 \058 \067\097\110\110\111\116 \114\101\109\111\118\101 \097\117\100\105\111 \102\114\111\109 \100\101\115\116\114\111\121\101\100 \097\117\100\105\111\112\108\097\121\101\114\046"))for p=1,#C.Playlist,1 do C:RemoveAudioAtIndex(1)end end function C.Play(p,C)assert(p._Destroyed==false,"\091\065\117\100\105\111 \080\108\097\121\101\114 \'"..(p.Name.."\'\093 \080\108\097\121\040\041 \058 \067\097\110\110\111\116 \112\108\097\121 \097\110 \097\117\100\105\111 \111\102 \097 \100\101\115\116\114\111\121\101\100 \097\117\100\105\111 \112\108\097\121\101\114\046"))if C~=nil then assert(typeof(C)=="\116\097\098\108\101","\091\065\117\100\105\111 \080\108\097\121\101\114 \'"..(p.Name..("\'\093 \080\108\097\121\040\041 \058 \116\097\098\108\101 \101\120\112\101\099\116\101\100 \102\111\114 \065\117\100\105\111\083\101\116\116\105\110\103\115\044 \103\111\116 "..(typeof(C).." \105\110\115\116\101\097\100\046"))))end p:Stop()if C~=nil then for C,d in pairs(C)do if C~="\084\119\101\101\110"then p.Sound[C]=d end end if C.Tween~=nil then local x=d:Create(p.Sound,unpack(C.Tween))x:Play()end end p.Sound.SoundId=p.CurrentAudio.ID p.Sound:Play()end function C.PlayAudioAtIndex(d,C,p)assert(d._Destroyed==false,"\091\065\117\100\105\111 \080\108\097\121\101\114 \'"..(d.Name.."\'\093 \080\108\097\121\065\117\100\105\111\065\116\073\110\100\101\120\040\041 \058 \067\097\110\110\111\116 \112\108\097\121 \097\110 \097\117\100\105\111 \111\102 \097 \100\101\115\116\114\111\121\101\100 \097\117\100\105\111 \112\108\097\121\101\114\046"))assert(C~=nil,"\091\065\117\100\105\111 \080\108\097\121\101\114 \'"..(d.Name.."\'\093 \080\108\097\121\065\117\100\105\111\065\116\073\110\100\101\120\040\041 \058 \073\110\100\101\120\078\117\109\098\101\114 \101\120\112\101\099\116\101\100\044 \103\111\116 \110\105\108\046"))assert(typeof(C)=="\110\117\109\098\101\114","\091\065\117\100\105\111 \080\108\097\121\101\114 \'"..(d.Name..("\'\093 \080\108\097\121\065\117\100\105\111\065\116\073\110\100\101\120\040\041 \058 \110\117\109\098\101\114 \101\120\112\099\116\101\100 \102\111\114 \073\110\100\101\120\078\117\109\098\101\114\044 \103\111\116 "..(typeof(C).." \105\110\115\116\101\097\100\046"))))assert(d.Playlist[C]~=nil,"\091\065\117\100\105\111 \080\108\097\121\101\114 \'"..(d.Name.."\'\093 \080\108\097\121\065\117\100\105\111\065\116\073\110\100\101\120\040\041 \058 \073\110\100\101\120 \111\117\116 \111\102 \098\111\117\110\100\115\046"))if p~=nil then assert(typeof(p)=="\116\097\098\108\101","\091\065\117\100\105\111 \080\108\097\121\101\114 \'"..(d.Name..("\'\093 \080\108\097\121\065\117\100\105\111\065\116\073\110\100\101\120\040\041 \058 \116\097\098\108\101 \101\120\112\101\099\116\101\100 \102\111\114 \065\117\100\105\111\083\101\116\116\105\110\103\115\044 \103\111\116 "..(typeof(p).." \105\110\115\116\101\097\100\046"))))end d:JumpToIndex(C)d:Play(p)end function C.PlayAudio(d,C,p)assert(d._Destroyed==false,"\091\065\117\100\105\111 \080\108\097\121\101\114 \'"..(d.Name.."\'\093 \080\108\097\121\065\117\100\105\111\040\041 \058 \067\097\110\110\111\116 \112\108\097\121 \097\110 \097\117\100\105\111 \111\102 \097 \100\101\115\116\114\111\121\101\100 \097\117\100\105\111 \112\108\097\121\101\114\046"))assert(C~=nil,"\091\065\117\100\105\111 \080\108\097\121\101\114 \'"..(d.Name.."\'\093 \080\108\097\121\065\117\100\105\111\040\041 \058 \065\117\100\105\111\078\097\109\101 \101\120\112\101\099\116\101\100\044 \103\111\116 \110\105\108\046"))assert(typeof(C)=="\115\116\114\105\110\103","\091\065\117\100\105\111 \080\108\097\121\101\114 \'"..(d.Name..("\'\093 \080\108\097\121\065\117\100\105\111\040\041 \058 \115\116\114\105\110\103 \101\120\112\101\099\116\101\100 \102\111\114 \065\117\100\105\111\078\097\109\101\044 \103\111\116 "..(typeof(C).." \105\110\115\116\101\097\100\046"))))if p~=nil then assert(typeof(p)=="\116\097\098\108\101","\091\065\117\100\105\111 \080\108\097\121\101\114 \'"..(d.Name..("\'\093 \080\108\097\121\065\117\100\105\111\065\116\073\110\100\101\120\040\041 \058 \116\097\098\108\101 \101\120\112\101\099\116\101\100 \102\111\114 \065\117\100\105\111\083\101\116\116\105\110\103\115\044 \103\111\116 "..(typeof(p).." \105\110\115\116\101\097\100\046"))))end local x,I=d:FindAudioByName(C)assert(x==true,"\091\065\117\100\105\111 \080\108\097\121\101\114 \'"..(d.Name..("\'\093 \080\108\097\121\065\117\100\105\111\040\041 \058 \067\111\117\108\100 \110\111\116 \102\105\110\100 \097\110 \097\117\100\105\111 \119\105\116\104 \116\104\101 \110\097\109\101 \'"..(C.."\'\046"))))d:JumpToIndex(I)d:Play(p)end function C.Stop(p,C)assert(p._Destroyed==false,"\091\065\117\100\105\111 \080\108\097\121\101\114 \'"..(p.Name.."\'\093 \083\116\111\112\040\041 \058 \067\097\110\110\111\116 \115\116\111\112 \097\110 \097\117\100\105\111 \111\102 \097 \100\101\115\116\114\111\121\101\100 \097\117\100\105\111 \112\108\097\121\101\114\046"))if C~=nil then local x=d:Create(p.Sound,unpack(C))x:Play()spawn(function()x.Completed:wait()p.Sound:Stop()p.Sound.TimePosition=0 end)else p.Sound:Stop()p.Sound.TimePosition=0 end end function C.Resume(p,C)assert(p._Destroyed==false,"\091\065\117\100\105\111 \080\108\097\121\101\114 \'"..(p.Name.."\'\093 \082\101\115\117\109\101\040\041\041 \058 \067\097\110\110\111\116 \114\101\115\117\109\101 \097\110 \097\117\100\105\111 \111\102 \097 \100\101\115\116\114\111\121\101\100 \097\117\100\105\111 \112\108\097\121\101\114\046"))if C~=nil then assert(typeof(C)=="\116\097\098\108\101","\091\065\117\100\105\111 \080\108\097\121\101\114 \'"..(p.Name..("\'\093 \082\101\115\117\109\101\040\041 \058 \116\097\098\108\101 \101\120\112\101\099\116\101\100 \102\111\114 \065\117\100\105\111\083\101\116\116\105\110\103\115\044 \103\111\116 "..(typeof(C).." \105\110\115\116\101\097\100\046"))))end if C~=nil then for C,d in pairs(C)do if C~="\084\119\101\101\110"then p.Sound[C]=d end end if C.Tween~=nil then local x=d:Create(p.Sound,unpack(C.Tween))x:Play()end end p.Sound:Resume()end function C.Pause(p,C)assert(p._Destroyed==false,"\091\065\117\100\105\111 \080\108\097\121\101\114 \'"..(p.Name.."\'\093 \080\097\117\115\101\040\041 \058 \067\097\110\110\111\116 \112\097\117\115\101 \097\110 \097\117\100\105\111 \111\102 \097 \100\101\115\116\114\111\121\101\100 \097\117\100\105\111 \112\108\097\121\101\114\046"))if C~=nil then local x=d:Create(p.Sound,unpack(C))x:Play()spawn(function()x.Completed:wait()p.Sound:Pause()end)else p.Sound:Pause()end end function C.JumpToIndex(p,C)assert(p._Destroyed==false,"\091\065\117\100\105\111 \080\108\097\121\101\114 \'"..(p.Name.."\'\093 \074\117\109\112\084\111\073\110\100\101\120\040\041 \058 \067\097\110\110\111\116 \106\117\109\112 \116\111 \097\110 \105\110\100\101\120 \111\102 \097 \100\101\115\116\114\111\121\101\100 \097\117\100\105\111 \112\108\097\121\101\114\046"))assert(C~=nil,"\091\065\117\100\105\111 \080\108\097\121\101\114 \'"..(p.Name.."\'\093 \074\117\109\112\084\111\073\110\100\101\120\040\041 \058 \073\110\100\101\120\078\117\109\098\101\114 \101\120\112\101\099\116\101\100\044 \103\111\116 \110\105\108\046"))assert(typeof(C)=="\110\117\109\098\101\114","\091\065\117\100\105\111 \080\108\097\121\101\114 \'"..(p.Name..("\'\093 \074\117\109\112\084\111\073\110\100\101\120\040\041 \058 \110\117\109\098\101\114 \101\120\112\099\116\101\100 \102\111\114 \073\110\100\101\120\078\117\109\098\101\114\044 \103\111\116 "..(typeof(C).." \105\110\115\116\101\097\100\046"))))assert(p.Playlist[C]~=nil,"\091\065\117\100\105\111 \080\108\097\121\101\114 \'"..(p.Name.."\'\093 \074\117\109\112\084\111\073\110\100\101\120\040\041 \058 \073\110\100\101\120 \111\117\116 \111\102 \098\111\117\110\100\115\046"))if x then print("")print("\091\065\117\100\105\111 \080\108\097\121\101\114 \'"..(p.Name..("\'\093 \074\117\109\112\105\110\103 \116\111 \105\110\100\101\120 "..(C.."\046"))))print("")end p:Stop()p.PlaylistPosition=C p.CurrentAudio=p.Playlist[C]if p.AutoPlay then p:Play()end end function C.Next(C)assert(C._Destroyed==false,"\091\065\117\100\105\111 \080\108\097\121\101\114 \'"..(C.Name.."\'\093 \078\101\120\116\040\041 \058 \067\097\110\110\111\116 \103\111 \116\111 \110\101\120\116 \105\110\100\101\120 \105\110 \100\101\115\116\114\111\121\101\100 \097\117\100\105\111\112\108\097\121\101\114\046"))if C.Playlist[C.PlaylistPosition+1]~=nil then C:JumpToIndex(C.PlaylistPosition+1)else if C.Looped then C:JumpToIndex(1)else warn("\091\065\117\100\105\111 \080\108\097\121\101\114 \'"..(C.Name.."\'\093 \078\101\120\116\040\041 \058 \082\101\097\099\104\101\100 \101\110\100 \111\102 \112\108\097\121\108\105\115\116\044 \100\105\100 \110\111\116 \106\117\109\112 \116\111 \110\101\120\116 \105\110\100\101\120\046"))end end end function C.Previous(C)assert(C._Destroyed==false,"\091\065\117\100\105\111 \080\108\097\121\101\114 \'"..(C.Name.."\'\093 \080\114\101\118\105\111\117\115\040\041 \058 \067\097\110\110\111\116 \103\111 \116\111 \112\114\101\118\105\111\117\115 \105\110\100\101\120 \105\110 \100\101\115\116\114\111\121\101\100 \097\117\100\105\111\112\108\097\121\101\114\046"))if C.Playlist[C.PlaylistPosition-1]~=nil then C:JumpToIndex(C.PlaylistPosition-1)else if C.Looped then C:JumpToIndex(#C.Playlist)else warn("\091\065\117\100\105\111 \080\108\097\121\101\114 \'"..(C.Name.."\'\093 \080\114\101\118\105\111\117\115\040\041 \058 \082\101\097\099\104\101\100 \098\101\103\105\110\110\105\110\103 \111\102 \112\108\097\121\108\105\115\116\044 \100\105\100 \110\111\116 \106\117\109\112 \116\111 \112\114\101\118\105\111\117\115 \105\110\100\101\120\046"))end end end function C.FindAudioByName(p,C)assert(p._Destroyed==false,"\091\065\117\100\105\111 \080\108\097\121\101\114 \'"..(p.Name.."\'\093 \070\105\110\100\065\117\100\105\111\066\121\078\097\109\101\040\041 \058 \067\097\110\110\111\116 \102\105\110\100 \097\117\100\105\111 \105\110 \100\101\115\116\114\111\121\101\100 \097\117\100\105\111\112\108\097\121\101\114\046"))assert(C~=nil,"\091\065\117\100\105\111 \080\108\097\121\101\114 \'"..(p.Name.."\'\093 \070\105\110\100\065\117\100\105\111\066\121\078\097\109\101\040\041 \058 \065\117\100\105\111\078\097\109\101 \101\120\112\101\099\116\101\100\044 \103\111\116 \110\105\108\046"))assert(typeof(C)=="\115\116\114\105\110\103","\091\065\117\100\105\111 \080\108\097\121\101\114 \'"..(p.Name..("\'\093 \070\105\110\100\065\117\100\105\111\066\121\078\097\109\101\040\041 \058 \115\116\114\105\110\103 \101\120\112\101\099\116\101\100 \102\111\114 \065\117\100\105\111\078\097\109\101\044 \103\111\116 "..(typeof(C).." \105\110\115\116\101\097\100\046"))))for d=1,#p.Playlist,1 do if p.Playlist[d].Name==C then return true,d end end return false end if x then warn("\091\065\117\100\105\111 \080\108\097\121\101\114\093 \068\101\098\117\103 \109\111\100\101 \101\110\097\098\108\101\100\046 \076\111\103\103\105\110\103 \119\105\108\108 \098\101 \118\101\114\098\111\115\101\046")end return C
--[[
	Audio Player

	Acts as a 'music player', allowing the easy deployment of audio on the client and server.

	Programmed by @Reshiram110
]]

local AudioPlayer={}

---------------------
-- Roblox Services --
---------------------
local HttpService=game:GetService("HttpService")
local TweenService=game:GetService("TweenService")

-------------
-- DEFINES --
-------------
local CLASS_DEBUG=false --Determines whether or not debug output will be displayed.

----------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- DEBUG CLASS METHODS
----------------------------------------------------------------------------------------------------------------------------------------------------------------------

----------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- @Name : SpitPlaylist
-- @Description : Spits the playlist table to the output in JSON format.
-- @Example : AudioPlayer:SpitPlaylist()
----------------------------------------------------------------------------------------------------------------------------------------------------------------------
function AudioPlayer:SpitPlaylist()
	for Index=1,#self.Playlist do
		if self.PlaylistPosition~=Index then
			print(Index.." :   "..HttpService:JSONEncode(self.Playlist[Index]))
		else
			print(Index.." : ->"..HttpService:JSONEncode(self.Playlist[Index]))
		end
	end
end

----------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- CLASS METHODS
----------------------------------------------------------------------------------------------------------------------------------------------------------------------

----------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- @Name : new
-- @Description : Creates and returns a new instance of the audioplayer class.
-- @Returns : table "NewAudioPlayer" - The new instance of the audio player.
-- @Example : local MyAudioPlayer=AudioPlayer.new()
----------------------------------------------------------------------------------------------------------------------------------------------------------------------
function AudioPlayer.new()
	local NewAudioPlayer={

		--[[ Properties ]]--
		Name="AudioPlayer",

		Playlist={}, --Contains all of the information about the different sounds
		PlaylistPosition=0, --The current position in the playlist.

		CurrentAudio={ --Information about the current song
			Name="",
			ID="rbxassetid://0",
			--AudioOptions={} --Contains properties and other options for the audio.
		},

		AutoPlay=false, --Determines whether or not the audioplayer will autoplay when moving to a new index in the playlist.
		Looped=false, --Determines whether or not the audioplayer will loop through the playlist.

		Sound=Instance.new('Sound',Workspace),

		_Destroyed=false, --Used to prevent further usage after this object is destroyed.

		--[[ Events ]]--
		_Events={
			AudioAdded=Instance.new('BindableEvent'), --Fired when an audio is added to the playlist.
			AudioRemoved=Instance.new('BindableEvent'), --Fired when an audio is removed from the playlist.
		}

	}
	NewAudioPlayer.AudioAdded=NewAudioPlayer._Events.AudioAdded.Event
	NewAudioPlayer.AudioRemoved=NewAudioPlayer._Events.AudioRemoved.Event
	setmetatable(NewAudioPlayer,{__index=AudioPlayer})

	NewAudioPlayer.Sound.Ended:connect(function()
		if NewAudioPlayer.AutoPlay then
			NewAudioPlayer:Next()
		end
	end)

	return NewAudioPlayer
end

----------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- @Name : Destroy
-- @Description : Destroys the audio player.
-- @Example : AudioPlayer:Destroy()
----------------------------------------------------------------------------------------------------------------------------------------------------------------------
function AudioPlayer:Destroy()
	assert(self._Destroyed==false,"[Audio Player '"..self.Name.."'] Destroy() : Cannot destroy an already destroyed audioplayer.")

	self._Destroyed=true

	--[[ Clean up instances ]]--
	self.Sound:Destroy()
	for _,BindableEvent in pairs(self._Events) do
		BindableEvent:Destroy()
	end
end

----------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- @Name : AddAudioAtIndex
-- @Description : Adds an audio with the given name and ID at the specified playlist index to the playlist.
-- @Params : int "IndexNumber" - Then index of the song to add to the playlist.
--           string "AudioName" - The name to assign to the audio being added.
--           string "ID" - The rbxasset id of the audio being added.
-- @Example : AudioPlayer:AddAudioAtIndex(#AudioPlayer.Playlist+1,"LobbyMusic","18300397")
--            AudioPlayer:AddAudio(#AudioPlayer.Playlist+1,"LobbyMusic","rbxassetid://183003997")
----------------------------------------------------------------------------------------------------------------------------------------------------------------------
function AudioPlayer:AddAudioAtIndex(IndexNumber,AudioName,ID)

	----------------
	-- ASSERTIONS --
	----------------
	assert(self._Destroyed==false,"[Audio Player '"..self.Name.."'] AddAudioAtIndex() : Cannot add audio to destroyed audioplayer.")
	assert(IndexNumber~=nil,"[Audio Player '"..self.Name.."'] AddAudioAtIndex() : IndexNumber expected, got nil.")
	assert(typeof(IndexNumber)=="number","[Audio Player '"..self.Name.."'] AddAudioAtIndex() : number expected for IndexNumber, got "..typeof(IndexNumber).." instead.")
	if IndexNumber~=1 then
		assert(self.Playlist[IndexNumber-1]~=nil,"[Audio Player '"..self.Name.."'] AddAudioAtIndex() : Index out of bounds.")
	end
	assert(AudioName~=nil,"[Audio Player '"..self.Name.."'] AddAudioAtIndex() : AudioName expected, got nil.")
	assert(typeof(AudioName)=="string","[Audio Player '"..self.Name.."'] AddAudioAtIndex() : string expected for AudioName, got "..typeof(AudioName).." instead.")
	assert(ID~=nil,"[Audio Player '"..self.Name.."'] AddAudioAtIndex() : Audio ID expected, got nil.")
	assert(typeof(ID)=="string","[Audio Player '"..self.Name.."'] AddAudioAtIndex(): String expected for ID, got "..typeof(ID).." instead.")
	assert(self:FindAudioByName(AudioName)==false,"[Audio Player '"..self.Name.."'] AddAudioAtIndex() : An audio with the name '"..AudioName.."' already exists!")

	----------------------
	-- Adding the audio --
	----------------------
	if string.find(ID,"rbxassetid://")==nil then
		ID="rbxassetid://"..ID
	end
	table.insert(self.Playlist,IndexNumber,{
		Name=(AudioName or "NewAudio"),
		ID=ID,
	})

	------------------------------------------------
	-- Update current audio and playlist position --
	------------------------------------------------
	if IndexNumber<=self.PlaylistPosition then --Adjust playlist position to point to current audio.
		self.PlaylistPosition=self.PlaylistPosition+1
	end
	if self.PlaylistPosition==0 then --First audio added.
		self:JumpToIndex(1)
	end

	if CLASS_DEBUG then
		print("")
		print("[Audio Player '"..self.Name.."'] Audio added.")
		print("Added audio : "..HttpService:JSONEncode(self.Playlist[IndexNumber]))
		print("New audio list :")
		self:SpitPlaylist()
		print("")
	end

	self._Events.AudioAdded:Fire(AudioName,IndexNumber)
end

----------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- @Name : AddAudio
-- @Description : Adds an audio with the given name and ID at the end of the playlist.
-- @Params : string "AudioName" - The name to assign to the audio being added.
--           string "ID" - The rbxasset id of the audio being added.
-- @Example : AudioPlayer:AddAudio("LobbyMusic","18300397")
--            AudioPlayer:AddAudio("LobbyMusic","rbxassetid://183003997")
----------------------------------------------------------------------------------------------------------------------------------------------------------------------
function AudioPlayer:AddAudio(AudioName,ID)
	----------------
	-- ASSERTIONS --
	----------------
	assert(self._Destroyed==false,"[Audio Player '"..self.Name.."'] AddAudio() : Cannot add audio to destroyed audioplayer.")
	assert(AudioName~=nil,"[Audio Player '"..self.Name.."'] AddAudio() : AudioName expected, got nil.")
	assert(typeof(AudioName)=="string","[Audio Player '"..self.Name.."'] AddAudio() : string expected for AudioName, got "..typeof(AudioName).." instead.")
	assert(ID~=nil,"[Audio Player '"..self.Name.."'] AddAudio() : Audio ID expected, got nil.")
	assert(typeof(ID)=="string","[Audio Player '"..self.Name.."'] AddAudio(): String expected for ID, got "..typeof(ID).." instead.")
	assert(self:FindAudioByName(AudioName)==false,"[Audio Player '"..self.Name.."'] AddAudioAtIndex() : An audio with the name '"..AudioName.."' already exists!")

	------------------------
	-- Adding the audio --
	------------------------
	self:AddAudioAtIndex(#self.Playlist+1,AudioName,ID)
end

----------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- @Name : RemoveAudioAtIndex
-- @Description : Removes an audio at the specified playlist index from the playlist.
-- @Params : int "IndexNumber" - Then index of the song to remove from the playlist.
-- @Example : AudioPlayer:RemoveAudioAtIndex(2)
----------------------------------------------------------------------------------------------------------------------------------------------------------------------
function AudioPlayer:RemoveAudioAtIndex(IndexNumber)

	----------------
	-- ASSERTIONS --
	----------------
	assert(self._Destroyed==false,"[Audio Player '"..self.Name.."'] RemoveAudioAtIndex() : Cannot remove audio from destroyed audioplayer.")
	assert(IndexNumber~=nil,"[Audio Player '"..self.Name.."'] RemoveAudioAtIndex() : IndexNumber expected, got nil.")
	assert(typeof(IndexNumber)=="number","[Audio Player '"..self.Name.."'] number expected for IndexNumber, got "..typeof(IndexNumber).." instead.")
	assert(self.Playlist[IndexNumber]~=nil,"[Audio Player '"..self.Name.."'] RemoveAudioAtIndex() : Index out of bounds.")

	-------------
	-- DEFINES --
	-------------
	local AudioName=self.Playlist[IndexNumber].Name

	------------------------
	-- Removing the audio --
	------------------------
	if CLASS_DEBUG then
		print("")
		print("[Audio Player '"..self.Name.."'] Audio removed.")
		print("Removed audio : "..HttpService:JSONEncode(self.Playlist[IndexNumber]))
	end

	table.remove(self.Playlist,IndexNumber)

	------------------------------------------------
	-- Update current audio and playlist position --
	------------------------------------------------
	if IndexNumber<self.PlaylistPosition then --Adjust playlist position to point to current audio.
		self.PlaylistPosition=self.PlaylistPosition-1
	elseif IndexNumber==self.PlaylistPosition then --Current audio was removed.
	    if #self.Playlist==0 then --Destroyed audio was the only audio in the playlist.
			self.CurrentSong={Name="",ID="rbxassetid://0"}
			self.PlaylistPosition=0
		elseif self.PlaylistPosition>#self.Playlist then --Destroyed audio was last in playlist.
			self:JumpToIndex(#self.Playlist)
		else
			self:JumpToIndex(self.PlaylistPosition)
		end
	end

	if CLASS_DEBUG then
		print("New audio list :")
		self:SpitPlaylist()
		print("")
	end

	self._Events.AudioRemoved:Fire(AudioName,IndexNumber)
end

----------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- @Name : RemoveAudio
-- @Description : Removes an audio with the given name from the playlist.
-- @Params : string "AudioName" - The name of the audio to be removed from the playlist.
-- @Example : AudioPlayer:RemoveAudio("LobbyMusic")
----------------------------------------------------------------------------------------------------------------------------------------------------------------------
function AudioPlayer:RemoveAudio(AudioName)

	----------------
	-- ASSERTIONS --
	----------------
	assert(self._Destroyed==false,"[Audio Player '"..self.Name.."'] RemoveAudio() : Cannot remove audio from destroyed audioplayer.")
	assert(AudioName~=nil,"[Audio Player '"..self.Name.."'] RemoveAudio() : Name expected, got nil.")
	assert(typeof(AudioName)=="string","[Audio Player '"..self.Name.."'] RemoveAudio() : string expected for Name, got "..typeof(AudioName).." instead.")

	-------------
	-- DEFINES --
	-------------
	local AudioFound,AudioIndex=self:FindAudioByName(AudioName)

	------------------------
	-- Removing the audio --
	------------------------
	assert(AudioFound==true,"[Audio Player '"..self.Name.."'] RemoveAudio() : Could not remove audio '"..AudioName.."', audio was not found.")
	self:RemoveAudioAtIndex(AudioIndex)
end

----------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- @Name : RemoveAllAudio
-- @Description : Removes all audio from the playlist.
-- @Example : AudioPlayer:RemoveAllAudio()
----------------------------------------------------------------------------------------------------------------------------------------------------------------------
function AudioPlayer:RemoveAllAudio()

	----------------
	-- ASSERTIONS --
	----------------
	assert(self._Destroyed==false,"[Audio Player '"..self.Name.."'] RemoveAudio() : Cannot remove audio from destroyed audioplayer.")

	------------------------
	-- Removing all audio --
	------------------------
	for Count=1,#self.Playlist do
		self:RemoveAudioAtIndex(1)
	end
end

----------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- @Name : Play
-- @Description : Plays the audio that is at the current playlist position.
-- @Params : OPTIONAL table "AudioSettings" - A dictionary table containing the properties to apply to the audio.
--                                            Can also include a tween.
-- @Example : AudioPlayer:Play({
--                Volume=0,
--                Tween={
--                    TweenInfo.new(5,Enum.EasingStyle.Linear),
--                    {Volume=1}
--                }
--            })
----------------------------------------------------------------------------------------------------------------------------------------------------------------------
function AudioPlayer:Play(AudioSettings)

	----------------
	-- ASSERTIONS --
	----------------
	assert(self._Destroyed==false,"[Audio Player '"..self.Name.."'] Play() : Cannot play an audio of a destroyed audio player.")
	if AudioSettings~=nil then
		assert(typeof(AudioSettings)=="table","[Audio Player '"..self.Name.."'] Play() : table expected for AudioSettings, got "..typeof(AudioSettings).." instead.")
	end

	-----------------------
	-- Playing the audio --
	-----------------------
	self:Stop()

	--[[ Apply audio properties if specified ]]--
	if AudioSettings~=nil then
		for PropertyName,PropertyValue in pairs(AudioSettings) do
			if PropertyName~="Tween" then
				self.Sound[PropertyName]=PropertyValue
			end
		end

		--[[ Running tween if specified ]]--
		if AudioSettings.Tween~=nil then
			local AudioTween=TweenService:Create(
				self.Sound,
				unpack(AudioSettings.Tween)
			)

			AudioTween:Play()
		end
	end

	self.Sound.SoundId=self.CurrentAudio.ID
	self.Sound:Play()
end

----------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- @Name : PlayAudioAtIndex
-- @Description : Plays an audio in the audio playlist at the specified index, with the given options.
-- @Params : int "IndexNumber" - The index of the song to play.
--           OPTIONAL table "AudioSettings" - A dictionary table containing the properties to apply to the audio.
--                                            Can also include a tween.
-- @Example : AudioPlayer:PlayAudioAtIndex(2,{
--                Volume=0,
--                Tween={
--                    TweenInfo.new(5,Enum.EasingStyle.Linear),
--                    {Volume=1}
--                }
--            })
----------------------------------------------------------------------------------------------------------------------------------------------------------------------
function AudioPlayer:PlayAudioAtIndex(IndexNumber,AudioSettings)

	----------------
	-- ASSERTIONS --
	----------------
	assert(self._Destroyed==false,"[Audio Player '"..self.Name.."'] PlayAudioAtIndex() : Cannot play an audio of a destroyed audio player.")
	assert(IndexNumber~=nil,"[Audio Player '"..self.Name.."'] PlayAudioAtIndex() : IndexNumber expected, got nil.")
	assert(typeof(IndexNumber)=="number","[Audio Player '"..self.Name.."'] PlayAudioAtIndex() : number expcted for IndexNumber, got "..typeof(IndexNumber).." instead.")
	assert(self.Playlist[IndexNumber]~=nil,"[Audio Player '"..self.Name.."'] PlayAudioAtIndex() : Index out of bounds.")
	if AudioSettings~=nil then
		assert(typeof(AudioSettings)=="table","[Audio Player '"..self.Name.."'] PlayAudioAtIndex() : table expected for AudioSettings, got "..typeof(AudioSettings).." instead.")
	end

	-----------------------
	-- Playing the audio --
	-----------------------
	self:JumpToIndex(IndexNumber)
	self:Play(AudioSettings)
end

----------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- @Name : PlayAudio
-- @Description : Plays an audio in the audio playlist with the given name, with the given options.
-- @Params : string "AudioName" - The name of the song to play.
--           OPTIONAL table "AudioSettings" - A dictionary table containing the properties to apply to the audio.
--                                            Can also include a tween.
-- @Example : AudioPlayer:PlayAudio("LobbyMusic",{
--                Volume=0,
--                Tween={
--                    TweenInfo.new(5,Enum.EasingStyle.Linear),
--                    {Volume=1}
--                }
--            })
----------------------------------------------------------------------------------------------------------------------------------------------------------------------
function AudioPlayer:PlayAudio(AudioName,AudioSettings)

	----------------
	-- ASSERTIONS --
	----------------
	assert(self._Destroyed==false,"[Audio Player '"..self.Name.."'] PlayAudio() : Cannot play an audio of a destroyed audio player.")
	assert(AudioName~=nil,"[Audio Player '"..self.Name.."'] PlayAudio() : AudioName expected, got nil.")
	assert(typeof(AudioName)=="string","[Audio Player '"..self.Name.."'] PlayAudio() : string expected for AudioName, got "..typeof(AudioName).." instead.")
	if AudioSettings~=nil then
		assert(typeof(AudioSettings)=="table","[Audio Player '"..self.Name.."'] PlayAudioAtIndex() : table expected for AudioSettings, got "..typeof(AudioSettings).." instead.")
	end

	-------------
	-- DEFINES --
	-------------
	local AudioFound,AudioIndex=self:FindAudioByName(AudioName)

	-----------------------
	-- Playing the audio --
	-----------------------
	assert(AudioFound==true,"[Audio Player '"..self.Name.."'] PlayAudio() : Could not find an audio with the name '"..AudioName.."'.")
	self:JumpToIndex(AudioIndex)
	self:Play(AudioSettings)
end

----------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- @Name : Stop
-- @Description : Stops the currently playing audio.
-- @Params : OPTIONAL table "Tween" - A table containing the properties for a tween that will run before the
--                                    audio is stopped.
-- @Example : AudioPlayer:Stop()
--            AudioPlayer:Stop({
--                TweenInfo.new(5,Enum.EasingStyle.Linear),
--                {Volume=1}
--            })
----------------------------------------------------------------------------------------------------------------------------------------------------------------------
function AudioPlayer:Stop(Tween)

	----------------
	-- ASSERTIONS --
	----------------
	assert(self._Destroyed==false,"[Audio Player '"..self.Name.."'] Stop() : Cannot stop an audio of a destroyed audio player.")

	------------------------
	-- Stopping the audio --
	------------------------

	--[[ Running tween if specified ]]--
	if Tween~=nil then
		local AudioTween=TweenService:Create(
			self.Sound,
			unpack(Tween)
		)

		AudioTween:Play()
		spawn(function() --We spawn the function so the calling thread doesn't yield.
			AudioTween.Completed:wait()
			self.Sound:Stop()
			self.Sound.TimePosition=0
		end)
	else
		self.Sound:Stop()
		self.Sound.TimePosition=0
	end
end

----------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- @Name : Resume
-- @Description : Resumes the currently paused audio.
-- @Params : OPTIONAL table "AudioSettings" - A dictionary table containing the properties to apply to the audio.
--                                            Can also include a tween.
-- @Example : AudioPlayer:Resume({
--                Volume=0,
--                Tween={
--                    TweenInfo.new(5,Enum.EasingStyle.Linear),
--                    {Volume=1}
--                }
--            })
----------------------------------------------------------------------------------------------------------------------------------------------------------------------
function AudioPlayer:Resume(AudioSettings)

	----------------
	-- ASSERTIONS --
	----------------
	assert(self._Destroyed==false,"[Audio Player '"..self.Name.."'] Resume()) : Cannot resume an audio of a destroyed audio player.")
	if AudioSettings~=nil then
		assert(typeof(AudioSettings)=="table","[Audio Player '"..self.Name.."'] Resume() : table expected for AudioSettings, got "..typeof(AudioSettings).." instead.")
	end

	------------------------
	-- Resuming the audio --
	------------------------

	--[[ Apply audio properties if specified ]]--
	if AudioSettings~=nil then
		for PropertyName,PropertyValue in pairs(AudioSettings) do
			if PropertyName~="Tween" then
				self.Sound[PropertyName]=PropertyValue
			end
		end

		--[[ Running tween if specified ]]--
		if AudioSettings.Tween~=nil then
			local AudioTween=TweenService:Create(
				self.Sound,
				unpack(AudioSettings.Tween)
			)

			AudioTween:Play()
		end
	end

	self.Sound:Resume()
end

----------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- @Name : Pause
-- @Description : Pauses the currently playing audio.
-- @Params : OPTIONAL table "Tween" - A table containing the properties for a tween that will run before the
--                                    audio is paused.
-- @Example : AudioPlayer:Pause({
--                TweenInfo.new(5,Enum.EasingStyle.Linear),
--                {Volume=1}
--            })
----------------------------------------------------------------------------------------------------------------------------------------------------------------------
function AudioPlayer:Pause(Tween)

	----------------
	-- ASSERTIONS --
	----------------
	assert(self._Destroyed==false,"[Audio Player '"..self.Name.."'] Pause() : Cannot pause an audio of a destroyed audio player.")

	-----------------------
	-- Pausing the audio --
	-----------------------

	--[[ Running tween if specified ]]--
	if Tween~=nil then
		local AudioTween=TweenService:Create(
			self.Sound,
			unpack(Tween)
		)

		AudioTween:Play()
		spawn(function() --We spawn the function so the calling thread doesn't yield.
			AudioTween.Completed:wait()
			self.Sound:Pause()
		end)
	else
		self.Sound:Pause()
	end
end

----------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- @Name : JumpToIndex
-- @Description : Sets the current song to the specified index in the playlist.
--                If audio is currently being played, the audio will be stopped.
--                If autoplay is true, the song at the specified index will be automatically played.
-- @Params : int "IndexNumber" - The index to jump to in the playlist.
-- @Example : AudioPlayer:JumpToIndex(2)
----------------------------------------------------------------------------------------------------------------------------------------------------------------------
function AudioPlayer:JumpToIndex(IndexNumber)

	----------------
	-- ASSERTIONS --
	----------------
	assert(self._Destroyed==false,"[Audio Player '"..self.Name.."'] JumpToIndex() : Cannot jump to an index of a destroyed audio player.")
	assert(IndexNumber~=nil,"[Audio Player '"..self.Name.."'] JumpToIndex() : IndexNumber expected, got nil.")
	assert(typeof(IndexNumber)=="number","[Audio Player '"..self.Name.."'] JumpToIndex() : number expcted for IndexNumber, got "..typeof(IndexNumber).." instead.")
	assert(self.Playlist[IndexNumber]~=nil,"[Audio Player '"..self.Name.."'] JumpToIndex() : Index out of bounds.")

	----------------------
	-- Jumping to index --
	----------------------
	if CLASS_DEBUG then
		print("")
		print("[Audio Player '"..self.Name.."'] Jumping to index "..IndexNumber..".")
		print("")
	end

	self:Stop()
	self.PlaylistPosition=IndexNumber
	self.CurrentAudio=self.Playlist[IndexNumber]

	if self.AutoPlay then self:Play() end
end

----------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- @Name : Next
-- @Description : Jumps to the next song in the playlist if available.
--                If the looped property of the audioplayer is true, it will wrap to the beginning of the playlist.
-- @Example : AudioPlayer:Next()
----------------------------------------------------------------------------------------------------------------------------------------------------------------------
function AudioPlayer:Next()

	----------------
	-- ASSERTIONS --
	----------------
	assert(self._Destroyed==false,"[Audio Player '"..self.Name.."'] Next() : Cannot go to next index in destroyed audioplayer.")

	if self.Playlist[self.PlaylistPosition+1]~=nil then
		self:JumpToIndex(self.PlaylistPosition+1)
	else
		if self.Looped then
			self:JumpToIndex(1)
		else
			warn("[Audio Player '"..self.Name.."'] Next() : Reached end of playlist, did not jump to next index.")
		end
	end
end

----------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- @Name : Previous
-- @Description : Jumps to the previous song in the playlist if available.
--                If the looped property of the audioplayer is true, it will wrap to the end of the playlist.
-- @Example : AudioPlayer:Previous()
----------------------------------------------------------------------------------------------------------------------------------------------------------------------
function AudioPlayer:Previous()

	----------------
	-- ASSERTIONS --
	----------------
	assert(self._Destroyed==false,"[Audio Player '"..self.Name.."'] Previous() : Cannot go to previous index in destroyed audioplayer.")

	if self.Playlist[self.PlaylistPosition-1]~=nil then
		self:JumpToIndex(self.PlaylistPosition-1)
	else
		if self.Looped then
			self:JumpToIndex(#self.Playlist)
		else
			warn("[Audio Player '"..self.Name.."'] Previous() : Reached beginning of playlist, did not jump to previous index.")
		end
	end
end

----------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- @Name : FindAudioByName
-- @Description : Finds an audio in the playlist with the given name and returns its position in the playlist.
-- @Params : string "AudioName" - The name of the audio to find.
-- @Returns : bool "Found" - Determines whether or not the audio was found.
--            int "Index" - The index of where the audio is in the playlist. Is nil if the requested audio is not found.
-- @Example : local SongFound=AudioPlayera:FindAudioByName("LobbyMusic")
----------------------------------------------------------------------------------------------------------------------------------------------------------------------
function AudioPlayer:FindAudioByName(AudioName)

	----------------
	-- ASSERTIONS --
	----------------
	assert(self._Destroyed==false,"[Audio Player '"..self.Name.."'] FindAudioByName() : Cannot find audio in destroyed audioplayer.")
	assert(AudioName~=nil,"[Audio Player '"..self.Name.."'] FindAudioByName() : AudioName expected, got nil.")
	assert(typeof(AudioName)=="string","[Audio Player '"..self.Name.."'] FindAudioByName() : string expected for AudioName, got "..typeof(AudioName).." instead.")

	-----------------------
	-- Finding the audio --
	-----------------------
	for Index=1,#self.Playlist do
		if self.Playlist[Index].Name==AudioName then return true,Index end
	end

	return false
end

----------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- CLASS INITIALIZATION
----------------------------------------------------------------------------------------------------------------------------------------------------------------------
if CLASS_DEBUG then warn("[Audio Player] Debug mode enabled. Logging will be verbose.") end

return AudioPlayer