mirror of
https://github.com/Poniverse/Pony.fm.git
synced 2024-11-23 21:47:59 +01:00
f64400c46d
This changeset's key new feature is allowing web browsers to display media player notifications for Pony.fm by implementing the media session API. These notifications display Play/Pause, Previous, and Next controls that control Pony.fm's playback. This also makes Pony.fm controllable by automotive audio systems and other Bluetooth devices that expose their own (often physical) playback controls. Other improvements in this changeset include: - Update the automated dev environment setup to work in 2021 - Remove extraneous frontend logging - Fix to consistently include album data with a track's data
220 lines
8.1 KiB
CoffeeScript
220 lines
8.1 KiB
CoffeeScript
# 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 <http://www.gnu.org/licenses/>.
|
|
|
|
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()))
|
|
)
|
|
|
|
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
|
|
])
|