278 lines
8.7 KiB
CoffeeScript
278 lines
8.7 KiB
CoffeeScript
class window.Player
|
|
|
|
bar_width: 263
|
|
jp: null
|
|
scrobbled: false
|
|
albums: []
|
|
playlist: []
|
|
library: {}
|
|
|
|
initJplayer: ->
|
|
self = this
|
|
|
|
@jp = $("#jplayer")
|
|
@jp.jPlayer
|
|
swfPath: "/js"
|
|
supplied: "mp3"
|
|
cssSelectorAncestor: ""
|
|
cssSelector:
|
|
play: ".player .play"
|
|
pause: ".player .pause"
|
|
stop: ""
|
|
videoPlay: ""
|
|
seekBar: ""
|
|
playBar: ""
|
|
mute: ""
|
|
unmute: ""
|
|
volumeBar: ""
|
|
volumeBarValue: ""
|
|
currentTime: ""
|
|
duration: ""
|
|
|
|
@jp.bind $.jPlayer.event.timeupdate, (e) ->
|
|
data = e.jPlayer.status
|
|
if not _player.scrobbled and data.currentPercentAbsolute > 50
|
|
$obj = $('.playlist li.now')
|
|
self.scrobble _player.getTrackInfo $obj.attr('data-id')
|
|
_player.scrobbled = true
|
|
$('.player .progress .loaded').width(data.seekPercent * self.bar_width / 100)
|
|
$('.player .progress .played').width(data.currentPercentAbsolute * self.bar_width / 100)
|
|
|
|
@jp.bind $.jPlayer.event.ended, (e) ->
|
|
next = self.nextTrack()
|
|
if not next
|
|
$('#jplayer').jPlayer 'clearMedia'
|
|
$('.player .now-playing').html 'Nothing left to <strike>lose</strike> play'
|
|
$('.player .loaded, .player .played').width 0
|
|
$('.playlist li').removeClass 'now'
|
|
else
|
|
self.setTrack next
|
|
false
|
|
|
|
addTrack: (item, autoplay) ->
|
|
if typeof item in ["number", "string"]
|
|
item = @library[item]
|
|
if not autoplay?
|
|
autoplay = false
|
|
initial_count = $('.playlist li').length
|
|
len = parseInt(item.length, 10)
|
|
m = Math.floor(len / 60)
|
|
s = len - Math.floor(len / 60) * 60
|
|
duration = m + ':' + (if s < 10 then '0' else '') + s
|
|
item_class = (if item.available == false then 'unavailable' else '')
|
|
$('.playlist').append "
|
|
<li id='i#{Math.round(Math.random() * 999999)}' data-id='#{item.id}' class='#{item_class}'>
|
|
<div class='song-duration'>#{duration}</div>
|
|
<div class='label important remove'>remove</div>
|
|
<div class='artist-name'><a class='data artist'>#{item.artist}</a></div>
|
|
<div class='song-title'>#{item.name}</div>
|
|
</li>"
|
|
_player.playlist.push item
|
|
$('.playlist').sortable axis: 'y', cursor: 'move'
|
|
if initial_count == 0 and not _player.hasTrack()
|
|
_player.setTrack($('.playlist li').first().attr('id').split('i')[1])
|
|
false
|
|
|
|
getDataFromLi: (obj) ->
|
|
id = $(obj).attr 'data-id'
|
|
track_name = $(obj).find('.trackname').html()
|
|
length = $(obj).find('.length').html()
|
|
id: id, name: track_name, length: length
|
|
|
|
setTrack: (id) ->
|
|
$obj = $('#i' +id)
|
|
track = _player.getTrackInfo $obj.attr('data-id')
|
|
query = track.artist+ ' — ' +track.name
|
|
|
|
$('.player .loaded, .player .played').width 0
|
|
$('.player .now-playing').html query
|
|
$('.playlist li').removeClass 'now'
|
|
$obj.addClass 'now'
|
|
_vk_music.search track.artist, track.name, track.length, (audio) ->
|
|
if audio is null
|
|
_session.query '/track/report', { id: track.id }, (r) ->
|
|
if r.result is 'success'
|
|
$(".playlist li[data-id='#{track.id}']").addClass("unavailable")
|
|
$($(".album div[data-id='#{track.id}']").siblings()[0]).addClass("unavailable")
|
|
_player.setTrack _player.nextTrack()
|
|
else
|
|
_player.playSource audio.url
|
|
if track.length == 0
|
|
len = parseInt(audio.duration, 10)
|
|
m = Math.floor(len / 60)
|
|
s = len - Math.floor(len / 60) * 60
|
|
duration = m + ':' + (if s < 10 then '0' else '') + s
|
|
_session.query '/track/update_length', { track_id: track.id, length: len }, (r) ->
|
|
if r.result is 'success'
|
|
$(".playlist li[data-id='#{track.id}'] .song-duration").text(duration)
|
|
$($(".album div[data-id='#{track.id}']").siblings()[0]).text(duration)
|
|
_player.updateNowListening track
|
|
false
|
|
false
|
|
|
|
getTrackInfo: (id) ->
|
|
@library[id]
|
|
|
|
getAlbumInfo: (id) ->
|
|
for album in _player.albums
|
|
if parseInt(album.id, 10) == parseInt(id, 10)
|
|
return album
|
|
false
|
|
|
|
hasTrack: ->
|
|
if $('#jplayer audio').length > 0
|
|
return $('#jplayer audio').attr('src')? and $('#jplayer audio').attr('src') != ''
|
|
else if $('#jplayer object').length > 0
|
|
$('#jplayer').jPlayer 'play'
|
|
true
|
|
false
|
|
|
|
playSource: (url) ->
|
|
@scrobbled = false
|
|
$('#jplayer').jPlayer 'setMedia', mp3: url
|
|
$('#jplayer').jPlayer 'play'
|
|
false
|
|
|
|
nextTrack: (manual) ->
|
|
manual = manual?
|
|
cnt = $('.playlist li').length
|
|
if not this.onShuffle() # Shuffle off
|
|
if $('.playlist .now').next().length == 0 # Last track and repeat is on
|
|
if _player.onRepeat() or manual # Repeat or manual click
|
|
return $('.playlist li').first().attr('id').split('i')[1]
|
|
else
|
|
false
|
|
else
|
|
return $('.playlist .now').next().attr('id').split('i')[1]
|
|
else if cnt == 1 # Single track in the playlist
|
|
return $('.playlist li').first().attr('id').split('i')[1]
|
|
else # Shuffle on
|
|
while true
|
|
rnd = Math.floor(Math.random() * (cnt + .999))
|
|
$li = $('.playlist li').eq rnd
|
|
if $li.length > 0 and not $li.hasClass 'now'
|
|
return $li.attr('id').split('i')[1]
|
|
false
|
|
|
|
prevTrack: ->
|
|
cnt = $('.playlist li').length
|
|
if not _player.onShuffle() # Shuffle off
|
|
if $('.playlist .now').prev().length == 0 # First track in the playlist
|
|
return $('.playlist li').last().attr('id').split('i')[1]
|
|
else
|
|
return $('.playlist .now').prev().attr('id').split('i')[1]
|
|
else if cnt == 1 # Single track in the playlist
|
|
return $('.playlist li').first().attr('id').split('i')[1]
|
|
else # Shuffle on
|
|
while true
|
|
rnd = Math.floor(Math.random() * (cnt + .999))
|
|
$li = $('.playlist li').eq rnd
|
|
if $li.length > 0 and not $li.hasClass 'now'
|
|
return $li.attr('id').split('i')[1]
|
|
false
|
|
|
|
onShuffle: ->
|
|
return $('.shuffle').hasClass 'on'
|
|
|
|
onRepeat: ->
|
|
return $('.repeat').hasClass 'on'
|
|
|
|
updateNowListening: (track) ->
|
|
if _session.getUser().lastfm_username
|
|
_session.query '/lastfm/listening?r=' +Math.random(), track
|
|
false
|
|
|
|
scrobble: (track) ->
|
|
if _session.getUser().lastfm_username
|
|
_session.query '/lastfm/scrobble?r=' +Math.random(), track
|
|
false
|
|
|
|
emptyPlaylist: ->
|
|
$('.playlist li').remove()
|
|
$('#jplayer').jPlayer 'clearMedia'
|
|
$('.player .now-playing').text 'Add some music to playlist'
|
|
$('.player .loaded, .player .played').width 0
|
|
false
|
|
|
|
setPlaylist: (data) ->
|
|
this.emptyPlaylist()
|
|
for track in data.tracks
|
|
this.addTrack track
|
|
false
|
|
|
|
updateLibrary: (data) ->
|
|
if data.albums?
|
|
for album in data.albums
|
|
for track in album.tracks
|
|
@library[track.id] = track
|
|
if data.tracks?
|
|
for track in data.tracks
|
|
@library[track.id] = track
|
|
false
|
|
|
|
|
|
# Player Controls
|
|
|
|
$('.player .prev').live 'click', ->
|
|
_player.setTrack _player.prevTrack()
|
|
false
|
|
|
|
$('.player .next').live 'click', ->
|
|
_player.setTrack _player.nextTrack(true)
|
|
false
|
|
|
|
$('.player .play').live 'click', ->
|
|
if $('.playlist li').length > 0 and not _player.hasTrack()
|
|
_player.setTrack $('.playlist li').first().attr('id').split('i')[1]
|
|
false
|
|
|
|
$('.player .progress').live 'click', (e) ->
|
|
$('#jplayer').jPlayer 'playHead', Math.round((e.offsetX / _player.bar_width) * 100)
|
|
false
|
|
|
|
# Player Additional Controls
|
|
|
|
$('.repeat, .shuffle').live 'click', ->
|
|
$(this).toggleClass 'on'
|
|
false
|
|
|
|
$('.do_empty').live 'click', ->
|
|
if confirm('Are you sure?')
|
|
_player.emptyPlaylist()
|
|
false
|
|
|
|
# Playlist Actions
|
|
|
|
$('.playlist li .remove').live 'click', (e) ->
|
|
$li = $(this).parent()
|
|
if $li.hasClass 'now'
|
|
$('#jplayer').jPlayer 'clearMedia'
|
|
$('.player .now-playing').text '...'
|
|
$('.player .loaded, .player .played').width 0
|
|
$li.remove()
|
|
e.preventDefault()
|
|
false
|
|
|
|
$('.playlist li').live 'click', ->
|
|
_player.setTrack $(this).attr('id').split('i')[1]
|
|
false
|
|
|
|
# Adding To Playlist actions
|
|
|
|
$('.add-album').live 'click', ->
|
|
for id in $(this).data('tracks').split(",")
|
|
_player.addTrack id
|
|
false
|
|
|
|
$('.s-add').live 'click', ->
|
|
_player.addTrack $(this).data('id')
|
|
false
|
|
|
|
$('.set-playlist').live 'click', ->
|
|
_search.showSpinner()
|
|
$.get "/playlist/#{$(this).data('playlist')}", (response) ->
|
|
_player.setPlaylist response.data
|
|
_search.hideSpinner()
|
|
false
|
|
false
|