Welcome to the Second Life Forums Archive

These forums are CLOSED. Please visit the new forums HERE

Scripting Streaming

Samhain Broom
Registered User
Join date: 1 Aug 2004
Posts: 298
11-08-2004 07:43
I've seen some scripts that will set up a device that can be used like a "Juke Box" for setting up some URL's that stream music.

Can someone tell me if there is something similar to that, only the stream stays the same, but the music itself can be selected from feed that you have, for instance from your "WinAmp"?

I'm betting that this is something best handled by a XMLRPC server, but do not know.

If this is possible, can you make it so that the name of the song is displayed, and the time of the song programmed in so that the next tune can be prompted and queued?
_____________________
rm -rf /bin/ladden #beware of geeks bearing grifts
Water Rogers
Registered User
Join date: 1 May 2003
Posts: 286
11-09-2004 09:51
From: Samhain Broom
I've seen some scripts that will set up a device that can be used like a "Juke Box" for setting up some URL's that stream music.

Can someone tell me if there is something similar to that, only the stream stays the same, but the music itself can be selected from feed that you have, for instance from your "WinAmp"?

I'm betting that this is something best handled by a XMLRPC server, but do not know.

If this is possible, can you make it so that the name of the song is displayed, and the time of the song programmed in so that the next tune can be prompted and queued?

Sorry, Samhain. The method in which you're wanting isn't possible with LSL and winamp running your own shoutcast server as far as i know. And i haven't seen any php/asp-style url tags for streaming music URL's (like www.blahwhatever.com/connection.php?songNumber=1)
I've used Shoutcast on my land with my own streaming server, and couldn't figure a way to A) Detect Song Info OR B) Jukebox a playlist in one connection through SL.

That's my personal experience with it, anyway.

--Water.
_____________________
From: Philip Linden

For the more technically minded - the problem is actually NOT the asset server (or 'asshat' as you prefer to affectionately call it herein).
Trimda Hedges
Creator of Useless Prims
Join date: 19 Nov 2003
Posts: 247
11-09-2004 10:03
Well, first of all, you are very vague with what you are trying to do.

Are you,

1/ Trying to create a system that allows you to change what song is currently playing?

2/ Have something that selects what URL stream you are listening to and display the song info?

3/ Want to replicate the functionality of winamp into SL?

4/ Something else?

5/ All of the above?

On a side note, for all of the above, XMLRPC could be used, but Email would be a better fit.
_____________________
C. Create useless prims... Then delete... Rinse... Repeat.

"The problem is us, and the solution is within us all."
-- Merwan Marker

"Trimda - do us both a favor and please put me on ignore."
-- blaze Spinnaker
Samhain Broom
Registered User
Join date: 1 Aug 2004
Posts: 298
11-09-2004 12:39
Sorry for the sloppy wording in the original question...

I would like to use WINAMP (or something like it) with a list of songs and stream from it to my land, and be able to select the songs from a list of some sort.

As each song plays, I'd like to do some kind of HoverText to show the artist, the name of the tune, and the duration of the song.

I know that would be kind of complicated. Anyone think that's possible? Impossible?
_____________________
rm -rf /bin/ladden #beware of geeks bearing grifts
Moleculor Satyr
Fireflies!
Join date: 5 Jan 2004
Posts: 2,650
11-09-2004 13:44
You'd be able to do it, but it'd require a bit of XML-RPC on your part, I'm betting.
_____________________
</sarcasm>
Trimda Hedges
Creator of Useless Prims
Join date: 19 Nov 2003
Posts: 247
11-09-2004 13:56
From: Samhain Broom
Sorry for the sloppy wording in the original question...

I would like to use WINAMP (or something like it) with a list of songs and stream from it to my land, and be able to select the songs from a list of some sort.

As each song plays, I'd like to do some kind of HoverText to show the artist, the name of the tune, and the duration of the song.

I know that would be kind of complicated. Anyone think that's possible? Impossible?



Ahh ok! :) Thats a fairly big project you speak of actually. Effectively you wish to creation options 1 and 3... I'll divide into two parts to make it easier to understand the two major componants.

Part A - Getting your stream data to SL (Option 1)

This part involves some type of "proxy" program that reads the XML stats from the shoutcast server and either emails or uses XMLRPC to transmit the data to the LSL object. The most easy way to do this would be to use email. Now as for the application, you would have to develop it using some type of third party language (perl, Delphi, Visual C, Java, et cetra). This applications job is to simply read the XML information from the shoutcast server (using an HTTP get and XML parse it) and email the results to your LSL object.

There are other ways to do this (the proxy interacting with WinAmp directly) but the above is probably the most simplistic and easy to deploy.

As a note, there is an object in world that is already doing this, only difference is the creater has it set for a specific number of stations (it sets the URL for the music on the land for you) and displays the station name and what is playing. I can't remember who the creator is. He might have found a better way.

Part B - Interfacing the Object in world with WinAmp (Option 3)

The easiest way to do this is using email and a POP3(or IMAP or whatever) account dedicated to this use. This once again involves a "proxy" program that acts as the go-between the LSL object and Winamp itself. Whenever the LSL object wants to go to the next track, it sends an email to the POP3 account. The proxy checks the email and retreives the details of the LSL objects request. From there, it issues the command to winamp (either using API or via WMI). This proxy also would be charged with sending the playlist details as well to the LSL object.

The above is a sample design I'd work with. Mind you, somoneone else might have their own ideas on how to do it better. As for XMLRPC, it is very limited in what it can do for us at this time. Objects are the XMLRPC servers and remote apps are the clients. Basically, the client must initiate the requests. The XMLRPC server cannot start its own connection.

If it were the other way around, then it would be much easier! Basically, the LSL object could query an app on a webserver (perl, ASP, whatever!) that would go and get the playlist from winamp and the stream info from SC all at the same time, and return the data. Instead, we have to run around like mice to get everything together and use archaic communications mediums to communicate. Tres un-cool.

As for doing this little thing, well, good luck. I'm a senior windows and unix s/w developer, and even I see this is a fairly big pain the <beeep> of a project. Its very doable, just very assbackwords to make it all happen... Well, I shouldn't say that, should I? We should be happy that we can even communicate LSL objects with external systems in the first place :D
_____________________
C. Create useless prims... Then delete... Rinse... Repeat.

"The problem is us, and the solution is within us all."
-- Merwan Marker

"Trimda - do us both a favor and please put me on ignore."
-- blaze Spinnaker
Trimda Hedges
Creator of Useless Prims
Join date: 19 Nov 2003
Posts: 247
11-09-2004 14:00
From: Moleculor Satyr
You'd be able to do it, but it'd require a bit of XML-RPC on your part, I'm betting.

Huh?
_____________________
C. Create useless prims... Then delete... Rinse... Repeat.

"The problem is us, and the solution is within us all."
-- Merwan Marker

"Trimda - do us both a favor and please put me on ignore."
-- blaze Spinnaker
MSo Lambert
Registered User
Join date: 16 Aug 2004
Posts: 101
11-09-2004 20:56
From: someone
As a note, there is an object in world that is already doing this, only difference is the creater has it set for a specific number of stations (it sets the URL for the music on the land for you) and displays the station name and what is playing. I can't remember who the creator is. He might have found a better way

Yes I have an object like this, I won't go into details couse we're not in the Classifieds, but it uses XML-RPC to relay song information to scripts in world. Basically, there is a server that collects and caches song information from stations that are "registered" on it (by clients in world) and sends updates whenever the station information changes. XML-RPC being a bit unreliable at times, and e-mails having delays at times makes it a pain to maintain such a server (i'm rewriting the server side logic for the 3rd time now, to implement more fail-safe features etc, and it still doesn't work as I'd like it to).

But to get back on the topic, I'm writing a plugin for WinAmp/SAM2 Broadcaster that will be able to accept song requests from in world objects and relay the song and playlist info directly to the clients in world, without the need to use the server mentioned above. Its meant for DJs and people that own their own shoutcast servers, as you still need to stream the music from WinAmp/SAM2 to the shoutcast server, which in turn provides music for your land in world.

I'll post some updates and maybe some how-tos when I get it working reliably (or semi-working, like all the other xml-rpc stuff is at the moment =)
_____________________
MSo
Jack Moseley
Registered User
Join date: 24 Aug 2004
Posts: 39
I've been working on such an object
11-09-2004 21:05
I've been working on a "track" display item for my own land music... I currently use something called tunez (search www.freshmeat.net) to control/manage an icecast streamer. It lets you vote on which song gets played, etc.

I have an XML-RPC LSL script that registers with my server via email. The icecast streamer then uses this data (the rpc channel key from email) to send NOWPLAYING announcements to the inworld objects via XMLRPC.

That part works reasonably well...

However my main goal was to do exactly what the original post described... Something that would let you control the content of the stream in world... So my object can also email specific commands (it's authenticated) to SKIP the current song.

This works fine, however email tends to get.. erm... we'll be nice and call it slow...

So you're listening to the music... some song you despise comes on... You tell it to skip... 6 min later when the next song, which you adore, is already playing... Bam it skips...

When email isn't being a pain its almost useable...

I guess the only other option at this point would be to have my system poll the objects in world via XMLRPC for waiting commands... but thats still rather klunky.

Also, in Hank's MegaTower there is a person selling a shoutcast track announcer that simply reads the info off the shoutcast stream and displays it... No control, but it works without you having to do anything :)
Samhain Broom
Registered User
Join date: 1 Aug 2004
Posts: 298
11-10-2004 10:38
Thanks everyone, Thanks Jack. That sounds like something I might want to see in action.
_____________________
rm -rf /bin/ladden #beware of geeks bearing grifts
Jack Moseley
Registered User
Join date: 24 Aug 2004
Posts: 39
11-10-2004 12:19
I considered selling it as a hosted land music service, but until there is a more reliable way to send commands OUT of SL, I don't feel comfortable with that...

-jwb
Jack Moseley
Registered User
Join date: 24 Aug 2004
Posts: 39
11-10-2004 12:20
I guess the question would be... You gonna use email to send the commands back to your plugin, or poll for them via RPC?

I moved on to writing a generic XMLRPC registry thingy while I await a better outgoing solution.

-jwb
MSo Lambert
Registered User
Join date: 16 Aug 2004
Posts: 101
11-10-2004 12:33
XML-RPC solution seems way more reliable (and faster most of the time) than e-mail, and since I'm addicted to XML-RPC, I'll use that for requests also.

I was thinking about the same problems you are having with your e-mail based control - the time it takes for the plugin to actually receive the commands is just not acceptable at times (when the e-mail queue goes out of control, for example), and on the other hand, I don't want to send an xml-rpc message to the script every couple of seconds just to see if there are any pending commands...

So I was thinking of doing this a little bit differently... I'll post it here, maybe you can get some ideas for your already working request system.

My Hi-Fi systems that are displaying the song info are already using xml-rpc more or less successfuly, and the xml-rpc messages only get sent when something actually changes (new song starts playing, listener count changes, etc...), so I was thinking of using the same system for the request plugin... instead of polling the commands every couple of seconds from the scripts, the plugin will also only send an message when a song changes (so 1 message per song, or every couple of minutes), but it will also include the next couple of songs that are queued to be played.

With this approach, the scripts get the queued songs before they actually start playing, and the user can choose to skip the next song, while the current one is still playing. Commands that are queued on the SL side (user chooses to skip the next song, etc...) are returned with the xml-rpc reply (also only once per couple of minutes).

This approach of course has a few drawbacks, and I still have some details to sort out, but basically it solves the main problem... how to skip the song before the whole song is actually played =)
_____________________
MSo
Samhain Broom
Registered User
Join date: 1 Aug 2004
Posts: 298
11-10-2004 13:07
Since you can get the time of the day, and match that to the duration of the tune (you can get that from the player right?)

Would it do any good to keep the time of the song, match that to the time of day, and then use that time to know where in time you are so you do not make the mistake of stopping the wrong song? That way even if there is lag, the system clock still trudges on, and you can have a higher degree of synchronization right?
_____________________
rm -rf /bin/ladden #beware of geeks bearing grifts
Jack Moseley
Registered User
Join date: 24 Aug 2004
Posts: 39
11-10-2004 15:19
MSo, thats not a bad idea... Prolly the best solution unless the changes to email polling Linden made do anything to speed up mail delivery (I doubt it)...

So you just poll every 1 or 2min for pending commands via XMLRPC from the outside?

I think I'll give that a try... gotta see how to hack my streamer so it sends more than 1 song... Currently if there are no songs in queue it simply selects a single random track to play next.
Samhain Broom
Registered User
Join date: 1 Aug 2004
Posts: 298
11-10-2004 20:38
Well, if you send an email from the SL side, it's the NEXT message that might have the delay, so that might not have a bad effect...

From the SL side... you should be able to set a timing mechanism to wait for the duration of the song... Then send an initiatiating message to the XMPRPC platform right?

I'm not up on the XMLRPC thing.
_____________________
rm -rf /bin/ladden #beware of geeks bearing grifts
Water Rogers
Registered User
Join date: 1 May 2003
Posts: 286
11-11-2004 04:13
I actually got kinda curious with this the last couple of days. I wrote up some php on my webhost and came up with a way to show stream information on an object. It's kind of a weird way to approach it, being that the 'server' that i wrote is essentially a webpage that automatically refreshes itself sending / requestiing rpcxml data every 10 seconds. It seems to work pretty good (i tried this with an email approach that seemed to work a lot slower... rpcxml is much faster). The only downfall is that you have to keep the page open, or it won't send any info - thus timing out the connection with the object.

However, i think it's a pretty good start in the right direction. There isn't control implemented yet as to changing songs - i was thinking of whipping up an application in C++ for that... however, if keeping it web-based - i did notice that wwwinamp might be useful for that.

So can i get some people to check out this script... i already have the webpage/server implemented. All you have to do is drop this script into an object, it spits out the data connection key, then copy/paste that into the textfield at http://www.midnightstudios.net/shoutcast/index.htm, enter in the ip and port and then connect. Note that the IP addy has to point to the actual shoutCAST server IP, and not just a host site. Here's my shoutCAST station running if you wanted to use it to test: 24.118.199.56 and port 8000

Some feedback would be cool :)
CODE
//  Streaming Music Reader v1.0
// By Water Rogers
//
// This script will display stream information as Text above the object while connected to the web server.
// Information displayed while connected:
// Stream Output Bitrate
// Song Name and Title
// Current Listeners listening to the stream
// How many listeners allowed
// and Peak listeners
// The web server also displays this information.
// If the object is deleted, or removed from the world (into inventory etc) or reset, the server connection will timeout and
// the server will stop refreshing itself.
// If the server is closed out or does not connect to a suiteable shoutCAST host ip, the object will diconnect and the server
// will stop refreshing itself.
// The server refreshes itself every 10 seconds - so it works fine minimized in your taskbar.
//
//-----------------------------------------------
// To connect
// Pretty simple actually. You don't need webspace or anything, I provided all that dynamically for you.
// The script will tell you what the data channel is and what web address to point to in your browser (mozilla compatible)
// simply copy that data channel, go to the web address, fill out the 3 text fields, and click connect. If there are any
// errors, the server will let you know.
//
// TIP: when entering the IP address of the stream, do NOT include "http://" or the PORT (number after the ":")
// Also note that the IP address must point to the actual shoutCAST Server IP address that is running the stream.
// For example:
// This will work (because it points to the IP address)
// 24.118.199.56
//
// These will not work (yet)
// http://24.118.199.56 <--There is an "http://" here
// http://64.236.34.97:80/stream/1006 <--This does not point to the actual server hosting the stream
//
// Also don't include the port number with the IP number, there's a seperate field for that.
// So don't do this:
// 24.118.199.56:8000 <--Port number with ip = BAD :)
//
//------------------------------------------------
// Any other issues let me know... and i'll see if i can incoporate more on the server side.
// Enjoy

key gChannel;
list gMessageList;
string gSongTitle;
string gMaxListeners;
string gPeakListeners;
string gCurrListeners;
string gBitrate;
string setText;

default {
state_entry() {
llSetText( "Streaming Music Reader \nNot Connected", <1, 0, 0>, 1 );
llOpenRemoteDataChannel();
}

touch_start( integer t ){
if( llDetectedKey( 0 ) == llGetOwner() ){
llInstantMessage( llGetOwner(), "Data Channel: " + (string)gChannel );
llInstantMessage( llGetOwner(), "Connect here: http://www.midnightstudios.net/shoutcast/index.htm" );
}
}

remote_data( integer e_type, key c, key m, string s, integer i_data, string s_data ){
if( e_type == REMOTE_DATA_CHANNEL ){
gChannel = c;
llInstantMessage( llGetOwner(), "Data Channel: " + (string)gChannel );
llInstantMessage( llGetOwner(), "Connect here: http://www.midnightstudios.net/shoutcast/index.htm" );
}
if( e_type == REMOTE_DATA_REQUEST ){
if( s_data == "activity request" ){
llSetText( "Streaming Music Reader \nWaiting on Web Server...", <0, 1, 0>, 1 );
llRemoteDataReply( gChannel, llGetKey(), "Connection With Object Successful", 1 );
llSetTimerEvent( 120 );
return;
}
else{

//0 = Song Name and Title | 1 = Current Listener Count | 2 = Max Listeners Allowed
//3 = Peak Listeners | 4 = Output Bitrate of the Stream

gMessageList = llParseString2List( s_data, ["."], [] );
gSongTitle = llList2String( gMessageList, 0 );
gCurrListeners = llList2String( gMessageList, 1 );
gMaxListeners = llList2String( gMessageList, 2 );
gPeakListeners = llList2String( gMessageList, 3 );
gBitrate = llList2String( gMessageList, 4 );

setText = "Streaming Music Reader (" + gBitrate + "kbs)\n";
setText += "Song: " + gSongTitle + "\n";
setText += "Listeners: " + gCurrListeners + "/" + gMaxListeners + " | Peak: " + gPeakListeners;

llSetText( setText, <0, 1, 0>, 1 );
llRemoteDataReply( gChannel, llGetKey(), llGetKey(), 1 );
llSetTimerEvent( 30 );
}
}
}

timer() {
llSetText( "Streaming Music Reader \nNot Connected", <1, 0, 0>, 1 );
llSetTimerEvent( 0 );
}
}

--Water
_____________________
From: Philip Linden

For the more technically minded - the problem is actually NOT the asset server (or 'asshat' as you prefer to affectionately call it herein).