diff --git a/web/app/assets/javascripts/react-components/PopupJamTrackPlayer.js.jsx.coffee b/web/app/assets/javascripts/react-components/PopupJamTrackPlayer.js.jsx.coffee
index 4687320f3..7229934e6 100644
--- a/web/app/assets/javascripts/react-components/PopupJamTrackPlayer.js.jsx.coffee
+++ b/web/app/assets/javascripts/react-components/PopupJamTrackPlayer.js.jsx.coffee
@@ -75,14 +75,8 @@ mixins.push(Reflux.listenTo(JamTrackPlayerStore, 'onJamTrackPlayerStoreChanged')
disabled = true
if selectedMixdown.client_state?
switch selectedMixdown.client_state
- when 'cant_open'
- customMixName = `
{selectedMixdown.name}
`
- when 'keying_timeout'
- customMixName = `{selectedMixdown.name}
`
when 'download_fail'
customMixName = `{selectedMixdown.name}
`
- when 'keying'
- customMixName = `Loading selected mix... 
`
when 'downloading'
customMixName = `Loading selected mix... 
`
when 'ready'
@@ -110,6 +104,8 @@ mixins.push(Reflux.listenTo(JamTrackPlayerStore, 'onJamTrackPlayerStoreChanged')
switch selectedStem.client_state
when 'downloading'
customMixName = `Loading {trackName}... 
`
+ when 'download_fail'
+ customMixName = `{trackName}
`
when 'ready'
customMixName = `{trackName}
`
disabled = false
@@ -119,6 +115,8 @@ mixins.push(Reflux.listenTo(JamTrackPlayerStore, 'onJamTrackPlayerStoreChanged')
else
if jamTrack?.client_state == 'downloading'
downloader = `
`
+ else if jamTrack?.client_state == 'download_fail'
+ downloader = `
`
jamTrackTypeHeader = `Full JamTrack {downloader}`
diff --git a/web/app/assets/javascripts/react-components/stores/BrowserMediaStore.js.coffee b/web/app/assets/javascripts/react-components/stores/BrowserMediaStore.js.coffee
index 0eec9aaa0..a443fd289 100644
--- a/web/app/assets/javascripts/react-components/stores/BrowserMediaStore.js.coffee
+++ b/web/app/assets/javascripts/react-components/stores/BrowserMediaStore.js.coffee
@@ -14,8 +14,11 @@ BrowserMediaActions = @BrowserMediaActions
loading: false
playing: false
paused: false
+ load_error: false
id: null
media_type: null
+ cachedAudio: []
+ cache_size: 10
playbackState:(position, time) ->
state = {}
@@ -29,7 +32,6 @@ BrowserMediaActions = @BrowserMediaActions
state.playbackStateChanged = !@state? || @state.isPlaying != @playing || @state.paused != @paused
state.positionUpdateChanged = !@state? || @state.positionMs != position
state.currentTimeChanged = !@state? || @state.time != time
-
state
changed: () ->
@@ -39,38 +41,54 @@ BrowserMediaActions = @BrowserMediaActions
# XXX: how to deal with duration? no mention in Howler API
- target = {id: @id, isPlaying: @playing, loaded: @loaded, paused: @paused, positionMs: position, time: time, durationMs: @onGetPlayDuration()}
+ target = {id: @id, isPlaying: @playing, loaded: @loaded, paused: @paused, loading: @loading, load_error: @load_error, positionMs: position, time: time, durationMs: @onGetPlayDuration()}
$.extend(true, target, playbackState)
@state = target
@trigger(@state)
onLoad: (id, urls, media_type) ->
+
+ if @loading
+ logger.error("you can't switch to different audio while loading due to weird errors seen in Howler")
+ return
+
if @audio
@audio.stop()
- @audio.unload()
@loaded = false
@loading = false
@playing = false
@paused = false
+ @load_error = false
+ @audio = null
@id = id
@media_type = media_type
@loading = true
@playing = false
@paused = false
- console.log("URLS", urls)
- @audio = new Howl({
- src: urls,
- autoplay: false,
- loop: false,
- volume: 1,
- preload: true,
- onend: @onAudioEnded,
- onload: @onAudioLoaded,
- onpause: @onAudioPause,
- onplay: @onAudioPlay
- })
+
+ for cacheItem in @cachedAudio
+ if cacheItem.id == id
+ # items in our own cache are only there if we saw that it fully loaded
+ @audio = cacheItem.audio
+ @loaded = true
+ @loading = false
+
+ unless @audio?
+ @audio = new Howl({
+ src: urls,
+ autoplay: false,
+ loop: false,
+ volume: 1,
+ preload: true,
+ onend: @onAudioEnded,
+ onload: @onAudioLoaded,
+ onloaderror: @onAudioLoadError,
+ onpause: @onAudioPause,
+ onplay: @onAudioPlay
+ })
+ @audio.jkid = id
@changed()
@@ -135,13 +153,30 @@ BrowserMediaActions = @BrowserMediaActions
0
onAudioEnded: () ->
- logger.debug("onAudioEnded", this, arguments)
+ logger.debug("onAudioEnded")
@playing = false
@changed()
onAudioLoaded: () ->
- logger.debug("onAudioLoaded")
+ logger.debug("onAudioLoaded", arguments)
@loaded = true
+ @loading = false
+
+ # add audio to cache, and ageout cached audio items if more than 10 \
+ if @cachedAudio.length >= @cache_size
+ audio = @cachedAudio.shift()
+ try
+ audio.audio.unload()
+ catch e
+ logger.error("unable to unload aged audio", @audio)
+
+ @cachedAudio.push({id: @audio.jkid, audio: @audio})
+ @changed()
+
+ onAudioLoadError: () ->
+ logger.debug("onAudioLoadError", arguments)
+ @load_error = true
+ @loading = false
@changed()
onAudioPause: () ->
diff --git a/web/app/assets/javascripts/react-components/stores/JamTrackPlayerStore.js.coffee b/web/app/assets/javascripts/react-components/stores/JamTrackPlayerStore.js.coffee
index 244477b7f..c4ba3b6cf 100644
--- a/web/app/assets/javascripts/react-components/stores/JamTrackPlayerStore.js.coffee
+++ b/web/app/assets/javascripts/react-components/stores/JamTrackPlayerStore.js.coffee
@@ -167,6 +167,8 @@ BrowserMediaActions = @BrowserMediaActions
else
if @browserMediaState.loaded
@jamTrack.activeStem.client_state = 'ready'
+ else if @browserMediaState.load_error
+ @jamTrack.activeStem.client_state = 'download_fail'
else
@jamTrack.activeStem.client_state = 'downloading'
@@ -185,6 +187,8 @@ BrowserMediaActions = @BrowserMediaActions
else
if @browserMediaState.loaded
@jamTrack.activeMixdown.client_state = 'ready'
+ else if @browserMediaState.load_error
+ @jamTrack.activeMixdown.client_state = 'download_fail'
else
@jamTrack.activeMixdown.client_state = 'downloading'
@@ -202,6 +206,8 @@ BrowserMediaActions = @BrowserMediaActions
else
if @browserMediaState.loaded
@jamTrack.client_state = 'ready'
+ else if @browserMediaState.load_error
+ @jamTrack.client_state = 'download_fail'
else
@jamTrack.client_state = 'downloading'
else
@@ -278,6 +284,10 @@ BrowserMediaActions = @BrowserMediaActions
alert("stop playing")
onOpenMixdown: (mixdown) ->
+ if @browserMediaState.loading
+ logger.warn("can not activate mixdown while browser media is loading")
+ return
+
logger.debug("opening mixdown", mixdown)
# check if it's already available in the backend or not
@@ -295,6 +305,10 @@ BrowserMediaActions = @BrowserMediaActions
)
onOpenStem: (stem_id) ->
+ if @browserMediaState.loading
+ logger.warn("can not activate stem while browser media is loading")
+ return
+
logger.debug("opening stem", stem_id)
# check if it's already available in the backend or not
@@ -312,6 +326,11 @@ BrowserMediaActions = @BrowserMediaActions
)
onActivateNoMixdown: (jamTrack) ->
+
+ if @browserMediaState.loading
+ logger.warn("can not activate JamTrack while browser media is loading")
+ return
+
logger.debug("activating no mixdown")
rest.markMixdownActive({id: @jamTrack.id, mixdown_id: null})