improving soundcloud integration

This commit is contained in:
Egor 2015-10-14 00:08:45 -07:00
parent b962611d67
commit 3f3466aa6f
8 changed files with 110 additions and 92 deletions

View file

@ -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')
});

View file

@ -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}}

View file

@ -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');
});
}
},

View file

@ -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++ ) {

View file

@ -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';

View file

@ -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>

View file

@ -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
View file

@ -484,7 +484,7 @@
this.source = this.context.createMediaElementSource(this.audio);
}
} catch (err) {
console.log('Dancer: '+ err);
console.info('Dancer: '+ err);
return;
}