# Pony.fm - A community for pony fan music. # Copyright (C) 2015 Feld0 # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Affero General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Affero General Public License for more details. # # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . module.exports = angular.module('ponyfm').factory('player', [ '$rootScope', '$http', '$modal' ($rootScope, $http, $modal) -> readyDef = new $.Deferred() play = (track) -> self.currentTrack = track $rootScope.$broadcast 'player-starting-track', track streams = [] streams.push track.streams.mp3 streams.push track.streams.ogg if track.streams.ogg streams.push track.streams.aac if track.streams.aac track.progress = 0 track.progressSeconds = 0 track.loadingProgress = 0 self.currentSound = soundManager.createSound url: streams, volume: self.volume whileloading: () -> $rootScope.safeApply -> track.loadingProgress = (self.currentSound.bytesLoaded / self.currentSound.bytesTotal) * 100 whileplaying: () -> $rootScope.safeApply -> track.progressSeconds = self.currentSound.position / 1000 track.progress = (self.currentSound.position / (track.duration * 1000)) * 100 onload: (res) -> $rootScope.safeApply -> if !res # Track failed to load dialog = $modal templateUrl: '/templates/partials/track-load-fail-dialog.html', show: true onfinish: () -> $rootScope.safeApply -> if self.repeatState == 2 # Track repeat # Playlist repeat is handled # in self.playNext() self.currentSound.play() else track.isPlaying = false self.playNext() onstop: () -> $rootScope.safeApply -> track.isPlaying = false self.isPlaying = false onplay: () -> $rootScope.safeApply -> track.isPlaying = true broadcastMediaInfo track onresume: () -> $rootScope.safeApply -> track.isPlaying = true onpause: () -> $rootScope.safeApply -> track.isPlaying = false track.isPlaying = true self.isPlaying = true self.currentSound.play() updateCanGo = () -> self.canGoNext = self.playlistIndex < self.playlist.length - 1 self.canGoPrev = self.playlistIndex > 0 broadcastMediaInfo = (track) -> if 'mediaSession' of navigator navigator.mediaSession.metadata = new MediaMetadata( title: track['title'] artist: track.user.name album: if 'album' of track then track.album.title else 'Unknown Album' artwork: [ {src: track.covers.original, sizes: '350x350', type: 'image/png'}, {src: track.covers.small, sizes: '100x100', type: 'image/png'} {src: track.covers.thumbnail, sizes: '50x50', type: 'image/png'} ] ) navigator.mediaSession.setActionHandler( 'play' (() -> self.currentSound.play())) navigator.mediaSession.setActionHandler( 'pause' (() -> self.currentSound.pause())) navigator.mediaSession.setActionHandler( 'previoustrack' (() -> self.playPrev())) navigator.mediaSession.setActionHandler( 'nexttrack' (() -> self.playNext())) navigator.mediaSession.setPositionState( duration: track.duration playbackRate: 1 position: track.progressSeconds ); self = ready: false isPlaying: false currentTrack: null currentSound: null playlist: [] playlistIndex: 0 volume: 0 readyDef: readyDef.promise() canGoPrev: false canGoNext: false repeatState: 0 playPause: () -> return if !self.ready return if !self.isPlaying if self.currentSound.paused self.currentSound.play() else self.currentSound.pause() playNext: () -> return if !self.canGoNext && self.repeatState != 1 self.currentSound.stop() if self.currentSound != null self.playlistIndex++ if self.playlistIndex >= self.playlist.length if self.repeatState != 1 self.playlist.length = 0 self.currentTrack = null self.currentSong = null self.isPlaying = false return else self.playlistIndex = 0 play self.playlist[self.playlistIndex] updateCanGo() playPrev: () -> return if !self.canGoPrev self.currentSound.stop() if self.currentSound != null self.playlistIndex-- if self.playlistIndex < 0 self.playlist.length = 0 self.currentTrack = null self.currentSong = null self.isPlaying = false return play self.playlist[self.playlistIndex] updateCanGo() toggleRepeat: () -> if self.repeatState >= 2 self.repeatState = 0 else self.repeatState++ seek: (progress) -> return if !self.currentSound self.currentSound.setPosition(progress) setVolume: (theVolume) -> theVolume = 100 if theVolume > 100 self.currentSound.setVolume(theVolume) if self.currentSound $.cookie('pfm-volume', theVolume) self.volume = theVolume playTracks: (tracks, index) -> return if !self.ready return if tracks.length == 0 if tracks[index].isPlaying self.playPause() return self.currentSound.stop() if self.currentSound != null $rootScope.$broadcast 'player-stopping-playlist' self.playlist.length = 0 self.playlist.push track for track in tracks self.playlistIndex = index $rootScope.$broadcast 'player-starting-playlist', tracks play tracks[index] updateCanGo() pfm.soundManager.done () -> self.ready = true self.setVolume($.cookie('pfm-volume') || 100) readyDef.resolve() codeArray = [] codeKey = '38,38,40,40,37,39,37,39,66,65' $(document).keydown (e) -> codeArray.push e.keyCode if codeArray.toString().indexOf(codeKey) >= 0 $http.get('https://pony.fm/api/web/tracks/23453').success (trackResponse) => toPlay = trackResponse.track self.playTracks [toPlay], 0 codeArray = [] return self ])