improving soundcloud integration
This commit is contained in:
parent
b962611d67
commit
3f3466aa6f
8 changed files with 110 additions and 92 deletions
|
|
@ -27,6 +27,6 @@ export default Em.Component.extend({
|
|||
},
|
||||
|
||||
saveDisabled: function(){
|
||||
return Em.isEmpty(this.get('url').trim())
|
||||
return Em.isNone(this.get('url')) || Em.isEmpty(this.get('url').trim());
|
||||
}.property('url')
|
||||
});
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
{{paper-input label="SoundCloud URL" icon="search" value=url}}
|
||||
|
||||
{{#paper-button action="close"}}Close{{/paper-button}}
|
||||
{{#paper-button class="pull-right" action="add" primary=true}}Add Music{{/paper-button}}
|
||||
{{#paper-button class="pull-right" action="add" disabled=saveDisabled primary=true}}Add Music{{/paper-button}}
|
||||
|
||||
{{/modal-dialog}}
|
||||
{{/if}}
|
||||
|
|
@ -67,29 +67,33 @@ export default Em.Component.extend({
|
|||
init() {
|
||||
this._super();
|
||||
|
||||
if(this.get('bridgeIp') === null){
|
||||
var self = this;
|
||||
if(this.get('bridgeIp') === null) {
|
||||
Em.$.ajax('https://www.meethue.com/api/nupnp', {
|
||||
timeout: 30000
|
||||
})
|
||||
.done((result, status)=> {
|
||||
var bridgeFindStatus = 'fail';
|
||||
|
||||
Em.$.get('https://www.meethue.com/api/nupnp', function (result, status) {
|
||||
var bridgeFindStatus = 'fail';
|
||||
if (status === 'success' && result.length === 1) {
|
||||
this.set('bridgeIp', result[0].internalipaddress);
|
||||
localStorage.setItem('huegasm.bridgeIp', result[0].internalipaddress);
|
||||
bridgeFindStatus = 'success';
|
||||
} else if (result.length > 1) {
|
||||
var multipleBridgeIps = this.get('multipleBridgeIps');
|
||||
|
||||
if (status === 'success' && result.length === 1) {
|
||||
self.set('bridgeIp', result[0].internalipaddress);
|
||||
localStorage.setItem('huegasm.bridgeIp', result[0].internalipaddress);
|
||||
bridgeFindStatus = 'success';
|
||||
} else if(result.length > 1) {
|
||||
var multipleBridgeIps = self.get('multipleBridgeIps');
|
||||
result.forEach(function (item) {
|
||||
multipleBridgeIps.push(item.internalipaddress);
|
||||
});
|
||||
|
||||
result.forEach(function(item) {
|
||||
multipleBridgeIps.push(item.internalipaddress);
|
||||
});
|
||||
bridgeFindStatus = 'multiple';
|
||||
} else {
|
||||
bridgeFindStatus = 'fail';
|
||||
}
|
||||
|
||||
bridgeFindStatus = 'multiple';
|
||||
} else {
|
||||
bridgeFindStatus = 'fail';
|
||||
}
|
||||
|
||||
self.set('bridgeFindStatus', bridgeFindStatus);
|
||||
this.set('bridgeFindStatus', bridgeFindStatus);
|
||||
})
|
||||
.fail(()=>{
|
||||
this.set('bridgeFindStatus', 'fail');
|
||||
});
|
||||
}
|
||||
},
|
||||
|
|
|
|||
|
|
@ -20,35 +20,39 @@ export default Em.Component.extend(musicControlMixin, visualizerMixin, {
|
|||
window.open(URL, '_blank');
|
||||
},
|
||||
handleNewSoundCloudURL(URL){
|
||||
SC.resolve(URL).then((resultObj)=>{
|
||||
var processResult = (result)=>{
|
||||
if(result.kind === 'user'){
|
||||
this.get('notify').alert({html: this.get('scUserNotSupportedHtml')});
|
||||
} else if(result.kind === 'track') {
|
||||
if(result.streamable === true){
|
||||
this.get('playQueue').pushObject({url: result.stream_url + '?client_id=' + this.get('SC_CLIENT_ID'), artist: result.user.username, artistUrl: result.user.permalink_url, title: result.title, artworkUrl: result.artwork_url, fromSoundCloud: true });
|
||||
// make sure to init the first song
|
||||
if(this.get('playQueue').length > 0 && this.get('playQueuePointer') === -1){
|
||||
this.send('goToSong', 0, true);
|
||||
if(URL) {
|
||||
SC.resolve(URL).then((resultObj)=>{
|
||||
var processResult = (result)=>{
|
||||
if(result.kind === 'user'){
|
||||
this.get('notify').alert({html: this.get('scUserNotSupportedHtml')});
|
||||
} else if(result.kind === 'track') {
|
||||
if(result.streamable === true){
|
||||
this.get('playQueue').pushObject({url: result.stream_url + '?client_id=' + this.get('SC_CLIENT_ID'), fileName: result.title + ' - ' + result.user.username, artist: result.user.username, artistUrl: result.user.permalink_url, title: result.title, artworkUrl: result.artwork_url, fromSoundCloud: true });
|
||||
// make sure to init the first song
|
||||
if(this.get('playQueue').length > 0 && this.get('playQueuePointer') === -1){
|
||||
this.send('goToSong', 0, true);
|
||||
}
|
||||
} else {
|
||||
this.get('notify').alert({html: this.get('notStreamableHtml')(result.title)});
|
||||
}
|
||||
} else if(result.kind === 'playlist'){
|
||||
if(result.streamable === true){
|
||||
result.tracks.forEach(processResult);
|
||||
} else {
|
||||
this.get('notify').alert({html: this.get('notStreamableHtml')(result.title)});
|
||||
}
|
||||
}
|
||||
} else {
|
||||
this.get('notify').alert({html: this.get('notStreamableHtml')(result.title)});
|
||||
}
|
||||
} else if(result.kind === 'playlist'){
|
||||
if(result.streamable === true){
|
||||
result.tracks.forEach(processResult);
|
||||
} else {
|
||||
this.get('notify').alert({html: this.get('notStreamableHtml')(result.title)});
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
if(resultObj instanceof Array){
|
||||
resultObj.forEach(processResult);
|
||||
} else {
|
||||
processResult(resultObj);
|
||||
if(resultObj instanceof Array){
|
||||
resultObj.forEach(processResult);
|
||||
} else {
|
||||
processResult(resultObj);
|
||||
}
|
||||
}, () => {
|
||||
this.get('notify').alert({html: this.get('urlNotFoundHtml')(URL)});
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
this.set('isShowingAddSoundCloudModal', false);
|
||||
},
|
||||
|
|
@ -92,7 +96,26 @@ export default Em.Component.extend(musicControlMixin, visualizerMixin, {
|
|||
goToSong(index, playSong){
|
||||
var dancer = this.get('dancer'), audio = new Audio();
|
||||
audio.src = this.get('playQueue')[index].url;
|
||||
|
||||
audio.crossOrigin = "anonymous";
|
||||
audio.oncanplay = ()=>{
|
||||
this.set('timeTotal', Math.floor(audio.duration));
|
||||
};
|
||||
audio.onerror = ()=>{
|
||||
var playQueuePointer =this.get('playQueuePointer'),
|
||||
song = this.get('playQueue')[playQueuePointer];
|
||||
|
||||
this.send('next');
|
||||
this.send('removeAudio', playQueuePointer);
|
||||
|
||||
this.get('notify').alert({html: this.get('failedToPlayFileHtml')(song.fileName)});
|
||||
};
|
||||
audio.ontimeupdate = ()=>{
|
||||
this.set('timeElapsed', Math.floor(audio.currentTime));
|
||||
};
|
||||
audio.onended = ()=> {
|
||||
this.send('next');
|
||||
};
|
||||
|
||||
if(dancer.audio) {
|
||||
this.clearCurrentAudio(true);
|
||||
|
|
@ -112,7 +135,7 @@ export default Em.Component.extend(musicControlMixin, visualizerMixin, {
|
|||
},
|
||||
removeAudio(index){
|
||||
if(index === this.get('playQueuePointer')) {
|
||||
this.clearCurrentAudio(true);
|
||||
this.clearCurrentAudio();
|
||||
}
|
||||
|
||||
this.get('playQueue').removeAt(index);
|
||||
|
|
@ -138,7 +161,6 @@ export default Em.Component.extend(musicControlMixin, visualizerMixin, {
|
|||
if(playQueuePointer !== -1 ) {
|
||||
if (this.get('playing')) {
|
||||
dancer.pause();
|
||||
clearInterval(this.get('incrementElapseTimeHandle'));
|
||||
|
||||
if(!replayPause){
|
||||
this.set('timeElapsed', Math.floor(dancer.getTime()));
|
||||
|
|
@ -146,6 +168,8 @@ export default Em.Component.extend(musicControlMixin, visualizerMixin, {
|
|||
|
||||
this.set('dimmerOn', false);
|
||||
} else {
|
||||
var timeTotal = this.get('timeTotal');
|
||||
|
||||
if(this.get('volumeMuted')) {
|
||||
dancer.setVolume(0);
|
||||
} else {
|
||||
|
|
@ -153,7 +177,7 @@ export default Em.Component.extend(musicControlMixin, visualizerMixin, {
|
|||
}
|
||||
|
||||
// replay song
|
||||
if(this.get('timeElapsed') === this.get('timeTotal')){
|
||||
if(this.get('timeElapsed') === timeTotal && timeTotal !== 0){
|
||||
this.send('seekChanged', 0);
|
||||
}
|
||||
|
||||
|
|
@ -162,8 +186,6 @@ export default Em.Component.extend(musicControlMixin, visualizerMixin, {
|
|||
if(this.get('dimmerEnabled')){
|
||||
this.set('dimmerOn', true);
|
||||
}
|
||||
|
||||
this.set('incrementElapseTimeHandle', window.setInterval(this.incrementElapseTime.bind(this), 1000));
|
||||
}
|
||||
|
||||
this.toggleProperty('playing');
|
||||
|
|
@ -333,13 +355,6 @@ export default Em.Component.extend(musicControlMixin, visualizerMixin, {
|
|||
this.get('storage').set('huegasm.' + name, value);
|
||||
},
|
||||
|
||||
incrementElapseTime(){
|
||||
this.incrementProperty('timeElapsed');
|
||||
if(this.get('timeElapsed') === this.get('timeTotal')){
|
||||
this.send('next');
|
||||
}
|
||||
},
|
||||
|
||||
saveSongBeatPreferences() {
|
||||
var song = this.get('playQueue')[this.get('playQueuePointer')],
|
||||
title = Em.isEmpty(song.artist) ? song.filename : song.artist + '-' + song.title,
|
||||
|
|
@ -385,7 +400,6 @@ export default Em.Component.extend(musicControlMixin, visualizerMixin, {
|
|||
|
||||
if(dancer.audio && dancer.audio.pause) {
|
||||
dancer.pause();
|
||||
clearInterval(this.get('incrementElapseTimeHandle'));
|
||||
}
|
||||
|
||||
this.setProperties({
|
||||
|
|
@ -436,8 +450,6 @@ export default Em.Component.extend(musicControlMixin, visualizerMixin, {
|
|||
dancer.pause();
|
||||
}
|
||||
|
||||
clearInterval(this.get('incrementElapseTimeHandle'));
|
||||
|
||||
if(resetPointer){
|
||||
this.set('playQueuePointer', -1);
|
||||
}
|
||||
|
|
@ -574,12 +586,6 @@ export default Em.Component.extend(musicControlMixin, visualizerMixin, {
|
|||
|
||||
kick.on();
|
||||
|
||||
dancer.bind('loaded', () => {
|
||||
if(this.get('usingLocalAudio')){
|
||||
this.set('timeTotal', Math.round(dancer.audio.duration));
|
||||
}
|
||||
});
|
||||
|
||||
//dancer.bind('update', function(){
|
||||
// var waveform = this.getWaveform(), spectrum = this.getSpectrum(), sumS = 0, sumW = 0;
|
||||
// for (let i = 0, l = spectrum.length; i < l && i < 512; i++ ) {
|
||||
|
|
|
|||
|
|
@ -77,7 +77,7 @@ export default Em.Mixin.create({
|
|||
timeTotal: 0,
|
||||
lastLightBopIndex: 0,
|
||||
|
||||
usingMicSupported: true,
|
||||
usingMicSupported: false,
|
||||
// 0 - local, 1 - mic, possibly more to come
|
||||
audioMode: 0,
|
||||
usingLocalAudio: Em.computed.equal('audioMode', 0),
|
||||
|
|
@ -99,6 +99,12 @@ export default Em.Mixin.create({
|
|||
notStreamableHtml: function(fileName){
|
||||
return '<div class="alert alert-danger" role="alert">The owner of the file ( ' + fileName +' ) has not allowed for the the file to be streamed.</div>';
|
||||
},
|
||||
urlNotFoundHtml: function(url){
|
||||
return '<div class="alert alert-danger" role="alert">The URL ( ' + url + ' ) could not be resolved.</div>';
|
||||
},
|
||||
failedToPlayFileHtml: function(fileName){
|
||||
return '<div class="alert alert-danger" role="alert">Failed to play file ( ' + fileName + ' ).</div>';
|
||||
},
|
||||
|
||||
playQueueEmpty: Em.computed.empty('playQueue'),
|
||||
playQueueNotEmpty: Em.computed.notEmpty('playQueue'),
|
||||
|
|
@ -177,8 +183,6 @@ export default Em.Mixin.create({
|
|||
}
|
||||
}.property('onBeatBriAndColor'),
|
||||
|
||||
incrementElapseTimeHandle: null,
|
||||
|
||||
micIcon: function () {
|
||||
if (this.get('usingMicAudio')) {
|
||||
return 'mic';
|
||||
|
|
|
|||
|
|
@ -72,13 +72,14 @@
|
|||
<div
|
||||
class="playlistItem cursorPointer {{if (eq index playQueuePointer) "active"}} {{if dragging "hidden"}}" {{action "goToSong" index true bubbles=false}}>
|
||||
{{#if item.title}}
|
||||
{{item.title}}
|
||||
{{#if item.artistUrl}}
|
||||
<a href="#" {{action "gotoURL" item.artistUrl bubbles=false}}><div class="songArtist">{{item.artist}}</div></a>
|
||||
{{else}}
|
||||
<div class="songArtist">{{item.artist}}</div>
|
||||
{{/if}}
|
||||
|
||||
<p>{{item.title}}</p>
|
||||
<div class="songArtist">
|
||||
{{#if item.artistUrl}}
|
||||
<a href="#" {{action "gotoURL" item.artistUrl bubbles=false}}>{{item.artist}}</a>
|
||||
{{else}}
|
||||
{{item.artist}}
|
||||
{{/if}}
|
||||
</div>
|
||||
{{else}}
|
||||
{{item.filename}}
|
||||
{{/if}}
|
||||
|
|
@ -108,30 +109,30 @@
|
|||
|
||||
<div class="row">
|
||||
<div class="beatOption col-xs-3">
|
||||
<div class="text-center">{{threshold}}</div>
|
||||
<span data-toggle="tooltip" data-placement="bottom auto" data-title="The minimum sound intensity for the beat to register" class="optionDescription bootstrapTooltip">Beat Threshold</span>
|
||||
{{range-slider start=threshold orientation="vertical" step=beatOptions.threshold.step range=beatOptions.threshold.range slide="thresholdChanged" pips=beatOptions.threshold.pips}}
|
||||
<span data-toggle="tooltip" data-placement="bottom auto" data-title="The minimum sound intensity for the beat to register" class="optionDescription bootstrapTooltip">Beat Threshold</span>
|
||||
<div class="text-center">{{threshold}}</div>
|
||||
</div>
|
||||
|
||||
<div class="beatOption col-xs-3">
|
||||
<div class="text-center">{{interval}} sec</div>
|
||||
<span data-toggle="tooltip" data-placement="bottom auto" data-title="The minimum amount of time between each registered beat" class="optionDescription bootstrapTooltip">Beat Interval</span>
|
||||
{{range-slider start=interval orientation="vertical" step=beatOptions.interval.step range=beatOptions.interval.range slide="intervalChanged" pips=beatOptions.interval.pips}}
|
||||
<span data-toggle="tooltip" data-placement="bottom auto" data-title="The minimum amount of time between each registered beat" class="optionDescription bootstrapTooltip">Beat Interval</span>
|
||||
<div class="text-center">{{interval}} sec</div>
|
||||
</div>
|
||||
|
||||
<div class="beatOption col-xs-3">
|
||||
<div class="text-center">[{{#each frequency as |item index|}}{{item}}{{#unless index}}
|
||||
,{{/unless}}{{/each}}
|
||||
]
|
||||
</div>
|
||||
{{range-slider start=frequency orientation="vertical" step=beatOptions.frequency.step range=beatOptions.frequency.range connect=true slide="frequencyChanged" pips=beatOptions.frequency.pips}}
|
||||
<span data-toggle="tooltip" data-placement="bottom auto" data-title="The frequency range of the sound to listen on for the beat" class="optionDescription bootstrapTooltip">Frequency Range</span>
|
||||
{{range-slider start=frequency orientation="vertical" step=beatOptions.frequency.step range=beatOptions.frequency.range connect=true slide="frequencyChanged" pips=beatOptions.frequency.pips}}
|
||||
<div class="text-center">[{{#each frequency as |item index|}}{{item}}{{#unless index}}
|
||||
,{{/unless}}{{/each}}
|
||||
]
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="beatOption col-xs-3">
|
||||
<div class="text-center">{{transitionTime}} sec</div>
|
||||
{{range-slider start=transitionTime orientation="vertical" step=beatOptions.transitionTime.step range=beatOptions.transitionTime.range slide="transitionTimeChanged" pips=beatOptions.transitionTime.pips}}
|
||||
<span data-toggle="tooltip" data-placement="bottom auto" data-title="The time it takes for a light to change color or brightness" class="optionDescription bootstrapTooltip">Transition Time</span>
|
||||
{{range-slider start=transitionTime orientation="vertical" step=beatOptions.transitionTime.step range=beatOptions.transitionTime.range slide="transitionTimeChanged" pips=beatOptions.transitionTime.pips}}
|
||||
<div class="text-center">{{transitionTime}} sec</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
|
|||
|
|
@ -649,6 +649,9 @@ md-switch.md-default-theme.md-checked .md-thumb {
|
|||
right: 10px;
|
||||
font-size: 18px;
|
||||
}
|
||||
p {
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.playlistItem.active {
|
||||
|
|
@ -968,8 +971,8 @@ $vibrateblurouter: 2px;
|
|||
|
||||
#saveBeatPreferencesStar {
|
||||
position: absolute;
|
||||
top: 5px;
|
||||
left: 5px;
|
||||
top: 0;
|
||||
left: 0;
|
||||
color: #F12B24 !important;
|
||||
font-size: 35px;
|
||||
}
|
||||
|
|
|
|||
2
vendor/dancer.js
vendored
2
vendor/dancer.js
vendored
|
|
@ -484,7 +484,7 @@
|
|||
this.source = this.context.createMediaElementSource(this.audio);
|
||||
}
|
||||
} catch (err) {
|
||||
console.log('Dancer: '+ err);
|
||||
console.info('Dancer: '+ err);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
|||
Reference in a new issue