spotify models.Track object - spotify

is the spotify models.Track object restricted to non-local tracks only?
I've built a little spotify app that will calculate the total play time of some random assortment of tracks that are dropped into the sidebar, but it seems like the Track object doesn't get any information from local files.
Here's what I got so far:
models.application.observe(models.EVENT.LINKSCHANGED, function () {
totalTime = 0;
var links = models.application.links;
if (links.length) {
for (var i = 0; i < links.length; i++) {
var track = models.Track.fromURI(links[i], function(t) {
totalTime = totalTime + t.duration;
});
}
}
document.getElementById("time").innerHTML = secondsToString(Math.round(totalTime/1000)) ;
});
Everything is firing correctly and working great on spotify tracks, but the whole reason i wrote this little app was so that I could calculate the total time of some of my really long audiobook files. Anyone know of a solution?
Link to the documentation page.

If this is indeed the case, I think you've found a bug/oversight.
However, local file URIs look like this: spotify:local:Coldplay:Mylo+Xyloto:Paradise:277
That last parameter is the length of the track, in integral seconds. It's a hacky workaround, but you could parse the URI and use the figure from that instead of models.Track.

Related

CosmosDB insertion loop stops inserting after a certain number of iterations (Node.js)

I'm doing a few tutorials on CosmosDB. I've got the database set up with the Core (SQL) API, and using Node.js to interface with it. for development, I'm using the emulator.
This is the bit of code that I'm running:
const CosmosClient = require('#azure/cosmos').CosmosClient
process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
const options = {
endpoint: 'https://localhost:8081',
key: REDACTED,
userAgentSuffix: 'CosmosDBJavascriptQuickstart'
};
const client = new CosmosClient(options);
(async () => {
let cost = 0;
let i = 0
while (i < 2000) {
i += 1
console.log(i+" Creating record, running cost:"+cost)
let response = await client.database('TestDB').container('TestContainer').items.upsert({}).catch(console.log);
cost += response.requestCharge;
}
})()
This, without fail, stops at around iteration 1565, and doesn't continue. I've tried it with different payloads, without much difference (it may do a few more or a few less iterations, but seems to almsot always be around that number)
On the flipside, a similar .NET Core example works great to insert 10,000 documents:
double cost = 0.0;
int i = 0;
while (i < 10000)
{
i++;
ItemResponse<dynamic> resp = await this.container.CreateItemAsync<dynamic>(new { id = Guid.NewGuid() });
cost += resp.RequestCharge;
Console.WriteLine("Created item {0} Operation consumed {1} RUs. Running cost: {2}", i, resp.RequestCharge, cost);
}
So I'm not sure what's going on.
So, after a bit of fiddling, this doesn't seem to have anything to do with CosmosDB or it's library.
I was running this in the debugger, and Node would just crap out after x iterations. I noticed if I didn't use a console.log it would actually work. Also, if I ran the script with node file.js it also worked. So there seems to be some sort of issue with debugging the script while also printing to the console. Not exactly sure whats up with that, but going to go ahead and mark this as solved

VIDEOJS: playing a pre-roll add before each playlist item

I'm using the videojs-playlist plugin along with Google's videojs-ima plugin. Everything works swimmingly except I am only getting a preload ad before the first video. I want one before each video in the playlist.
Basic setup is boilerplate, but for reference:
this.player = videojs('currentvideo', { autoplay : true, fluid : true });
this.player.playlist(this.playlist);
this.player.playlist.autoadvance(5);
const skippable_linear = {google's test ad};
const options = {
id: 'currentvideo',
adTagUrl: skippable_linear,
debug : true
};
this.player.ima(
options
);
this.player.ima.requestAds();
I have tried various ways of manually calling ads from inside an 'ended' event handler, such as calling requestAds again:
const _this = this;
this.player.on( 'ended', function(){
/* some other stuff */
_this.player.ima.requestAds();
});
This does play an ad where I want it, but
this breaks playlist's 'autoadvance' setting (next video doesn't start playing when the ad is finished), and
this puts the player into "ad display" mode (scrubber is unavailable, etc).
Is there a simple way to just say, "play an ad now" programmatically? I've tried, without joy, to use all of the seemingly applicable methods exposed by both the ima plugin and the contrib-ads plugin it relies on. I'll admit here that this is the first time I've ever had to deal with videos that run ads, so I'm kind of a noob.
I am trying to do the same thing. Just like you I failed when calling player.ima.requestAds() on events. I dug deeper and the best I could come up with is what I share bellow.
According to the videojs-ima API you have to use the setContentWithAdTag method instead of whatever you are using to switch the player content. In our case it is the player.playlist.next method.
I combined the code found in the videojs-ima examples with the original playlist.next to write my own next.
Then quite brutally I overrode the original plugin method.
Here's the code:
player.playlist(myPlayilst);
player.playlist.autoadvance(2);
player.playlistUi(); //videojs-playlist-ui
player.ima({
id: 'video5',
adTagUrl: 'thy adserver request'
});
//override playlist.next
player.playlist.next = function(){
var nextIndex = 0,
playlist = this.player_.playlist,
list = this.player_.playlist();
//everything below is copied directly from the original `next` (except for the "//load with ad")
// Repeat
if (playlist.repeat_) {
nextIndex = playlist.currentIndex_ + 1;
if (nextIndex > list.length - 1) {
nextIndex = 0;
}
} else {
// Don't go past the end of the playlist.
nextIndex = Math.min(playlist.currentIndex_ + 1, list.length - 1);
}
// Make the change
if (nextIndex !== playlist.currentIndex_) {
//load with ad
this.player_.playlist.currentItem(nextIndex);
this.player_.ima.setContentWithAdTag(
this.player_.playlist.currentItem(),
null,
true);
this.player_.ima.requestAds();
/////
return list[playlist.currentItem()];
}
}
You will probably need to override other methods that change the current playback, like playlist.previous.
I use videojs-playlist-ui so in my case it was neccessary to change the onclick handler called switchPlaylistItem_. I used some good old brute force to do that like this:
videojs.getComponent('PlaylistMenuItem').prototype.switchPlaylistItem_ = function(e){
this.player_.playlist.currentItem(this.player_.playlist().indexOf(this.item));
this.player_.ima.setContentWithAdTag(
this.player_.playlist.currentItem(),
null,
true);
this.player_.ima.requestAds();
};
PlaylistMenuItem's prototype should be changed before initializing the player.
This solution works, but it feels hacky, so if anyone can come up with something cleaner, please share!
I ended up forking videojs-playlist, and adding the option to override the player.src method. Feel free to use it:
fw-videojs-playlist
Details on how to use it are all in the github readme (including an example with ima.setContentWithAdTag)

How can you detect if ANY sounds are currently playing in soundJS?

How can you detect if any sounds are playing in soundJS?
I have lots of sounds firing on and off sometimes legitimately over the top of each other. I need a way to find out if any sounds are playing at any given time
ie. something like
createjs.Sound.isPlaying()
or
createjs.Sound.status()
Nothing exists like this in SoundJS currently.
You can look it up yourself, but it involves digging into private members, which is not recommended, and could break content down the road. Here is a quick sample:
function countActiveSounds() {
var s = createjs.Sound.activePlugin,
count = 0;
for (var n in s._soundInstances) {
var inst = s._soundInstances[n];
for (var i=0, l=inst.length; i<l; i++) {
var p = inst[i];
if (p.playState == "playSucceeded") { count++; }
}
}
return count;
}
This involves reading the private _soundInstances hash, and checking if the sound state is "playSucceeded". Once it is complete, the state will changed to "playFinished".
Again, use this with caution :)
It might make sense to log a feature request to the SoundJS GitHub.

Node.js, For loop

in node.js I am using for loop on server.js but it is not working and cause error
var myEasyrtcApp = function(err, appObj) {
for (i = 0; i < 10; i++) {
appObj.createRoom("room" + i ,null,function(err, roomObj){});
};
}
Please advice how can I use for loop to call appObj.createRoom several time to open different conference room
Sorry, but you almost not give any information... Asuming the last function is a Callback you need to make a Recursive "Loop" something like:
http://pastebin.com/LrKqLgyV
And to use it you can do this:
http://pastebin.com/L1bZZis0
To learn more about this, just google "recursive functions". (I can't post more than 2 links XD)
Hope It works for you ;)

Xively and Node-Red

I'm fairly new at all this but have muddled my way to getting my Arduino to post values to a Xively stream I've named "Lux and Temp." Three values; count, lux, and temperature.
Now what I want to do is take those values and do something with them using Node-Red.
http://nodered.org
I have Node-Red up and running, but I'll be danged if I can figure out how to parse the data from the Xively API feed. https://api.xively.com/v2/feeds/1823833592
Sadly, I don't have enough reputation points to be able to actually post the data it returns to here, since it has more than 3 URLs embedded in the data. It's a LONG string of data too. ;)
I'm just stumped though as to how to write the function to extract the parts I want.
My initial want is to make a simple Twitter feed out of it. Something like;
"Count 40, Lux 30, Temp 78.3"
I'll eventually want to recycle the code for other things like making my RasPi do something; maybe a display or some LEDs. In either case I need to parse the data and build various messages with it.
Anybody have any experience with the Node-Red functions that can walk me through a solution? The Node-Red site is pretty awesome, but I think it assumes I'm a MUCH more experienced user than I really am. It gives hints, but frankly about all I know is fairly basic Arduino and trivial level Python.
OK, it shouldn't be too tricky, but try putting this in a function block:
var newPayload = "";
var count, lux, temp;
var data = msg.payload.datastreams;
for (var i = 0 ; i< data.length; i++) {
if (data[i].id === 'Count') {
count = data[i].current_value;
}else if (data[i].id === 'Lux') {
lux = data[i].current_value;
} else if (data[i].id === 'Temp') {
temp = data[i].current_value;
}
}
newPayload = util.format('Count: %s, Lux: %s, Temp: %s', count, lux, temp);
msg.payload = newPayload;
return msg;
You may need to add a msg.payload = JSON.parse(msg.payload); to the start if however your getting the feed from xively is not already considered to be json.
[edit]
You could also just run the flow through a JSON parse node. (I always forget the converter nodes)
You should be able to wire that to a twitter output node.

Resources