Welcome to the Second Life Forums Archive

These forums are CLOSED. Please visit the new forums HERE

Streaming music script

Theora Aquitaine
Registered User
Join date: 12 Feb 2006
Posts: 266
06-12-2006 16:28
OK I have a very basic music streaming script now... You need to install python, python-pcapy and run the following as root: (note change the file to show your username, and music player of choice)

CODE

#!/usr/bin/python
import pcapy
import os
import re

#edit to add your username and mediaplayer:
user='username'
musicplayer='xmms'
#

def recv_pkts(hdr, data):
b=data.find('http')
if b>-1:
c=data[data.find('http'):data.find(' ',data.find('http'))]
colon=c.find(":",7)
if colon>-1:
pat=re.compile('[.:~/a-zA-z0-9]')
g=pat.findall(c)
d=''.join(g)
print g
if d.find('.',colon)>-1:
d=d[0:d.find('.',colon)]
if d.find(':',colon+1)>-1:
d=d[0:d.find(':',colon+1)]
print d
pipe=os.popen('su '+user, 'w')
pipe.write(musicplayer+' '+d)
dev='any'
p = pcapy.open_live(dev, 1500, 0, 100)
p.setfilter('udp')
p.loop(-1, recv_pkts)


It is very hacky, relying on the music stream having an extra colon in the url (which not all of them do), and you have to manually close xmms for it to find a new stream, but it should automatically launch xmms when it finds a new music url.... Also it runs xmms as a normal user, so at least it is semi secure (no not at all, I know!!) ;)

Edit: slight improvement to parsing of url. Also.. please note, ctrl-c will only work if the network is active, so if you have pressed ctrl-c and the above script is not terminating, just load up a web page or something!

Edit2: more hacky url parsing fixes.. Note it is best not to browse the web until you have your chosen stream up and running, or this script will try to play some webpages in xmms!

Edit3: added udp filter so web pages are ignored.

Edit4: added a few nasty hacks (if d.find.. bit) to remove specific rubbish from end of some urls..
ninjafoo Ng
Just me :)
Join date: 11 Feb 2006
Posts: 713
06-13-2006 03:41
*ewwww* functional whitespace :P

Have to give this a whirl when i get home:)
_____________________
FooRoo : clothes,bdsm,cages,houses & scripts

QAvimator (Linux, MacOS X & Windows) : http://qavimator.org/
Christine Montgomery
Registered User
Join date: 23 May 2006
Posts: 56
06-13-2006 04:57
Lovely hack!

It works for some places for me, but not for others. I'll see if I can work out why.
Theora Aquitaine
Registered User
Join date: 12 Feb 2006
Posts: 266
06-13-2006 05:14
From: Christine Montgomery
Lovely hack!

It works for some places for me, but not for others. I'll see if I can work out why.


Thanks :)

In my experience, the main reason it fails is if the url has some extraneous characters appended to it. You can add some lines to specifically remove the characters in question (as I have done), but this strikes me a a peculiarly ugly way to do it. It seems python tries too hard to convert non-ascii chars into ascii... If I can get it to fail on non-printing characters in a more consistent manner, it should work perfectly... still trying!

Edit: actually. I think I cannot go much further with this without starting to reverse engineer the SL packets.. This is really beyond me (though I know the libsecondlife people are doing it). Still, I am pretty happy with the functionality the current script adds... at last I can listen to SL streams with the linux client!
Christine Montgomery
Registered User
Join date: 23 May 2006
Posts: 56
A little bit of reverse engineering
06-14-2006 00:39
I've never done any python before so this is a bit messy.

The URLs are zero-terminated strings preceded by a tag byte and a length. So this new script searches for "http" in the packet, checks that the tag byte is "1" (movies seem to use tag of 8 if anyone wants those) and uses the length.

I've also changed it to use os.system() so that it will continue without killing xmms. Running xmms twice doesn't give you two instances it passeds the URL to the already running one. This works for me in all the places I've tried.

CODE
#!/usr/bin/python
import pcapy
import os
import re

#edit to add your username and mediaplayer:
user='christine'
musicplayer='xmms'
#

def recv_pkts(hdr, data):
b=data.find('http')
while b>-1:
len=ord(data[b-1])
tag=ord(data[b-2])
d=data[b:b+len-1]
if tag==1:
print "launching ",d
cmd='su '+user+' -c "'+musicplayer+' '+d+'&"'
os.system(cmd)
b=-1
else:
b=data.find('http', b+1)
dev='any'
p = pcapy.open_live(dev, 1500, 0, 100)
p.setfilter('udp')
p.loop(-1, recv_pkts)
Theora Aquitaine
Registered User
Join date: 12 Feb 2006
Posts: 266
06-14-2006 06:06
Brilliant stuff, Christine!

Really nice! :)
Theora Aquitaine
Registered User
Join date: 12 Feb 2006
Posts: 266
06-14-2006 07:34
Here is a (somewhat long) verion with keypress handling: t switches tv streaming on/off r switches radio streaming on/off. q (or ctrl-c) quits. Not had a chance to test it as the grid is down, but should work fine! Still like the simplicity of Christine's version tho!

CODE

#!/usr/bin/python
import pcapy
import os
import thread
import curses
import sys
import signal

#edit to add your username and mediaplayer:
user='username'
musicplayer='xmms'
videoplayer='mplayer'
radio=True
tv=False
#

def recv_pkts(hdr, data):
b=data.find('http')
while b>-1:
len=ord(data[b-1])
tag=ord(data[b-2])
d=data[b:b+len-1]
if tag==1 and radio:
stdscr.addstr('launching '+d+'\n')
cmd='su '+user+' -c "'+musicplayer+' '+d+'&"'
os.system(cmd)
b=-1
elif tag==8 and tv:
stdscr.addstr ('launching '+d+'\n')
cmd='su '+user+' -c "'+videoplayer+' '+d+'&"'
os.system(cmd)
b=-1
else:
b=data.find('http', b+1)

def quitnow(*sig):
curses.nocbreak()
stdscr.keypad(0)
curses.echo()
curses.endwin()
sys.exit()

dev='any'
p = pcapy.open_live(dev, 1500, 0, 100)
p.setfilter('udp')
thread.start_new_thread(p.loop, (-1, recv_pkts))
stdscr=curses.initscr()
curses.cbreak()
stdscr.keypad(0)
curses.noecho()
signal.signal(signal.SIGINT, quitnow)

while 1:
key=stdscr.getch()
quit=0
try: keypress=chr(key)
except: continue
if keypress=='r':
radio=not(radio)
stdscr.addstr('radio on:'+str(radio)+'\n')
if keypress=='t':
tv=not(tv)
stdscr.addstr('tv on:'+str(tv)+'\n')
if keypress=='q':
quitnow()
Drake Bacon
Linux is Furry
Join date: 13 Jul 2005
Posts: 443
06-14-2006 11:02
I just worked up a test Perl version. You must have at least version 0.12 of Net::Pcap installed. Gentoo users need to throw "dev-perl/Net-Pcap" into /etc/portage/package.keywords and emerge Net-Pcap.

CODE
#!/usr/bin/perl

use Net::Pcap;

sub tracker {
my ($ud, $header, $packet) = @_;
if($packet =~ /(.)(.)(http.+?)\0/s) {
$tag=ord($1);
$len=ord($2);
$url=$3;
print "Tag: $tag\tLen: $len\tURL: $url\n";
}
}

$err='';
$dev=Net::Pcap::lookupdev(\$err);
if($err) { die $err; };
$pcap=Net::Pcap::open_live($dev,1500,0,100,\$err);
if($err) { die $err; };
$filter='';
Net::Pcap::compile($pcap,\$filter,'udp',0,0);
Net::Pcap::setfilter($pcap,$filter);
Net::Pcap::loop($pcap,-1,\&tracker,'');


Intresting enough, tag value of 1 is for audio URL's, 8 for video URL's, and 236 for website URLs.
Theora Aquitaine
Registered User
Join date: 12 Feb 2006
Posts: 266
06-14-2006 16:06
Nice stuff Drake.

I have implemented your web url bit and made some other refinements to the python program and uploaded it here:

Edit: <snip>

(scroll to the bottom of the page to find download link)

Edit: New url: http://stux.wikiinfo.org/moin.py/Tools#slstream
Rizzermon Sopor
Registered User
Join date: 15 Mar 2006
Posts: 43
06-14-2006 17:00
From: Theora Aquitaine
Nice stuff Drake.

I have implemented your web url bit and made some other refinements to the python program and uploaded it here:

http://stux.wikiinfo.org/moin.py/LinuxClient

(scroll to the bottom of the page to find download link)


I tried out this script Theora, but continue to receive these errors:

Xlib: connection to ":0.0" refused by server
Xlib: No protocol specified

Sometimes I can spot an error in a script despite me not being someone who writes code to any significant degree. I'll look to see if I can figure it out, otherwise, will report the error in hopes of someone else figuring it out. Thanks. :)

Edit: Here is another error that I received while wandering through SL with this python script actvated:

Unhandled exception in thread started by <built-in method loop of Reader object at 0xb7bf8380>

Traceback (most recent call last):
File "./SLStream.py", line 41, in recv_pkts
stdscr.addstr ('opening site '+d+'\n'+tag+'\n')
TypeError: cannot concatenate 'str' and 'int' objects
Theora Aquitaine
Registered User
Join date: 12 Feb 2006
Posts: 266
06-14-2006 23:54
From: Rizzermon Sopor
I tried out this script Theora, but continue to receive these errors:

Xlib: connection to ":0.0" refused by server
Xlib: No protocol specified


Aah I think I can fix this... try the new version.

From: someone

Edit: Here is another error that I received while wandering through SL with this python script actvated:

Unhandled exception in thread started by <built-in method loop of Reader object at 0xb7bf8380>

Traceback (most recent call last):
File "./SLStream.py", line 41, in recv_pkts
stdscr.addstr ('opening site '+d+'\n'+tag+'\n')
TypeError: cannot concatenate 'str' and 'int' objects


Oops! delete the +tag+'\n' part of line 41... (fixed in new version)..
Vinci Calamari
Free Software Promoter
Join date: 27 Feb 2006
Posts: 192
06-15-2006 01:31
From: Theora Aquitaine
Nice stuff Drake.

I have implemented your web url bit and made some other refinements to the python program and uploaded it here:

http://stux.wikiinfo.org/moin.py/LinuxClient

(scroll to the bottom of the page to find download link)


Hi,
I moved to the tools page at: http://stux.wikiinfo.org/moin.py/Tools where similar stuff (tools for SL on Linux) is already there.
_____________________
The SecondTux Linux User Wiki:
http://stux.wikiinfo.org
Vinci Calamari
Free Software Promoter
Join date: 27 Feb 2006
Posts: 192
free license for this script?
06-15-2006 01:48
From: Theora Aquitaine
OK I have a very basic music streaming script now... You need to install python, python-pcapy and run the following as root: (note change the file to show your username, and music player of choice)



Ho Theora, what do you think about licensing this script under a free license? I would suggest using one of the Creative Commons licenses:

* http://creativecommons.org/licenses/by-sa/2.5/

This allows others to copy and modify it as long as they distribute it under the same conditions. Otherwise, everybody would have to ask you personally if he can use or modify this script.

If you want you just have to add this bit of text somewhere to the script:

"""
This work is licensed under the Creative Commons Attribution-ShareAlike 2.5 License. To view a copy of this license, visit http://creativecommons.org/licenses/by-sa/2.5/ or send a letter to Creative Commons, 543 Howard Street, 5th Floor, San Francisco, California, 94105, USA.
"""

Why this license? Because it is much simpler than GPL (that requires that you provide the license itself with the script).


Vinci
_____________________
The SecondTux Linux User Wiki:
http://stux.wikiinfo.org
Theora Aquitaine
Registered User
Join date: 12 Feb 2006
Posts: 266
06-15-2006 04:23
Sounds fine. It is supposed to be GPL but as you point out, it can't really be without a copy of the license. Feel free to change the script to show a CC sharealike license (and remove the bit about GPL).

Theora
ninjafoo Ng
Just me :)
Join date: 11 Feb 2006
Posts: 713
06-15-2006 04:29
From: Theora Aquitaine
Sounds fine. It is supposed to be GPL but as you point out, it can't really be without a copy of the license. Feel free to change the script to show a CC sharealike license (and remove the bit about GPL).


Although standard GPL boiler plate does state that if you did not receive a copy of licence with software, "here is where you get one" - implies acceptance that not everybody distributing under GPL wish to burden release with a copy of licence thats so widely available - its not as if its going to make any difference should any violation issues arise.
_____________________
FooRoo : clothes,bdsm,cages,houses & scripts

QAvimator (Linux, MacOS X & Windows) : http://qavimator.org/
Rizzermon Sopor
Registered User
Join date: 15 Mar 2006
Posts: 43
06-15-2006 11:30
From: Theora Aquitaine
Aah I think I can fix this... try the new version.



Oops! delete the +tag+'\n' part of line 41... (fixed in new version)..


OK, now it brings up xmms, but xmms just continually says connecting to whatever server and does nothing else. When I do a cut and paste on the server and try playing it with mplayer, it works, most times. When I change the player from xmms to mplayer for the radio, it spawns two mplayers and they also do not play, just show themselves as processes running (well not even running, but designated S+ or Sl+ ) and nothing more. Edit: I also noticed that xmms has this Sl+ designation, so it seems to be a process that is sleeping rather than running if I understand correctly? Any thoughts on what I need to do , or is there a need for more alteration of the script? Thanks.
Theora Aquitaine
Registered User
Join date: 12 Feb 2006
Posts: 266
06-15-2006 14:58
From: Rizzermon Sopor
OK, now it brings up xmms, but xmms just continually says connecting to whatever server and does nothing else. When I do a cut and paste on the server and try playing it with mplayer, it works, most times. When I change the player from xmms to mplayer for the radio, it spawns two mplayers and they also do not play, just show themselves as processes running (well not even running, but designated S+ or Sl+ ) and nothing more. Edit: I also noticed that xmms has this Sl+ designation, so it seems to be a process that is sleeping rather than running if I understand correctly? Any thoughts on what I need to do , or is there a need for more alteration of the script? Thanks.


Its a weird problem.. this doesn't happen on my system.

Try the new version, uploaded to:

http://stux.wikiinfo.org/moin.py/Tools

If the problem still remains, try uncommenting line 30. This will kill xmms each time a new stream is encountered.. It is slightly annoying because the SL viewer keeps losing focus as the new xmms is launched, but I suppose it is better than nothing. The default setting _should_ launch the new stream without having to restart xmms.
Rizzermon Sopor
Registered User
Join date: 15 Mar 2006
Posts: 43
Still Not for XMMS, but may be local issue
06-15-2006 22:07
No, it is still not working properly here. First, when it comes to opening a web site URL in firefox, the script works fine, but xmms is choking for some reason. Now, I switched to using mplayer for the audio, and it is working fine. Not sure what xmms problem is since I use it, but notice at times it doesn't seem to parse url's properly, like for instance if I try to listen to a shoutcast stream, xmms goes to using close to 100% cpu and just set there using up all my cpu, but no audio playing. That seems to be ultimately what is happening here, so more a problem locally than anything else I suppose since mplayer is working fine. I did have to uncomment the line you mentioned Theora, otherwise, it was just spawning more and more mplayers without closing out the one's already playing. Interestingly it spawns two mplayer processes each time which seem odd.
Theora Aquitaine
Registered User
Join date: 12 Feb 2006
Posts: 266
06-16-2006 00:17
Oh well.. after some experimentation I prefer mplayer for the audio streams..

I have made a further amendment to the code to use mplayer as default and to automatically kill all mplayer instances when the script finishes.
Christine Montgomery
Registered User
Join date: 23 May 2006
Posts: 56
06-16-2006 01:40
I've made a small edit to the script (I've only done the in-wiki one, not sure how to edit the linked one, sorry!) so always display the status on the screen.
ragarth Doolittle
Registered User
Join date: 18 Nov 2005
Posts: 28
06-16-2006 02:04
Theora, have you integrated Christie's code into your script to pass the new url to the currently running thread? Also, later today after I sleep I'll test all this out with Amarok, my preferred player.

Also, I always have amarok open, even when I'm not using it, so I may have to crashcourse myself in python to edit the script and set it up to use my existing amarok thread. That would be nifty. ^^
Theora Aquitaine
Registered User
Join date: 12 Feb 2006
Posts: 266
06-16-2006 02:45
From: ragarth Doolittle
Theora, have you integrated Christie's code into your script to pass the new url to the currently running thread? Also, later today after I sleep I'll test all this out with Amarok, my preferred player.

Also, I always have amarok open, even when I'm not using it, so I may have to crashcourse myself in python to edit the script and set it up to use my existing amarok thread. That would be nifty. ^^


Yes.. The script is the combination of mine and Christine's work.. Amarok seems to work alright with the script although it seems a little temperamental.. leaving some weird processes called kio_file hanging around. I would recommend xmms or mplayer really. I have just made another alteration to allow you to select whether to kill the audio and video players at shutdown (within the user editable section), and to integrate Christine's new alteration above.
Sven Takashi
Registered User
Join date: 21 Feb 2006
Posts: 13
beep-media-player
06-16-2006 07:21
I got the script working with beep-media-player(the xmms based one, not the new one coming out) but changing the su line to su -l.

For some reason bmp wouldn't run outside a login shell.
Christine Montgomery
Registered User
Join date: 23 May 2006
Posts: 56
06-18-2006 01:34
Here's a small fix that prevents the media player being reloaded if the URL hasn't changed. I get this in some places when zooming around.

I'll post this as a patch cos I'm not sure about the python - I don't know why it seems to need the 'global' declarations; so if you know what's going on, Theora, please feel free to fix it!

CODE

--- slstream_0.6.py 2006-06-17 15:31:27.000000000 +0100
+++ slstream.py 2006-06-17 16:35:10.000000000 +0100
@@ -28,14 +28,21 @@
musshutdown=True

####End configuration section###
+lastradio=''
+lastvideo=''
+lastweb=''

def recv_pkts(hdr, data):
+ global lastradio
+ global lastvideo
+ global lastweb
b=data.find('http')
while b>-1:
len=ord(data[b-1])
tag=ord(data[b-2])
d=data[b:b+len-1]
- if tag==1 and radio==1:
+ if tag==1 and radio==1 and d!=lastradio:
+ lastradio=d
curseserase()
stdscr.addstr('launching '+d+'\n')
stdscr.refresh()
@@ -43,7 +50,8 @@
os.system('pkill -9 '+musicplayer)
cmd='su '+user+' -c "'+musicplayer+' '+d+'&>/dev/null &"'
os.system(cmd)
- elif tag==8 and tv==1:
+ elif tag==8 and tv==1 and d!=lastvideo:
+ lastvideo=d
curseserase()
stdscr.addstr('launching '+d+'\n')
stdscr.refresh()
@@ -51,7 +59,8 @@
os.system('pkill -9 '+videoplayer)
cmd='su '+user+' -c "'+videoplayer+' '+d+'&>/dev/null &"'
os.system(cmd)
- elif tag==236 and web==1:
+ elif tag==236 and web==1 and d!=lastweb:
+ lastweb=d
curseserase()
stdscr.addstr ('opening site '+d+'\n')
stdscr.refresh()

Theora Aquitaine
Registered User
Join date: 12 Feb 2006
Posts: 266
06-18-2006 02:50
From: Christine Montgomery
Here's a small fix that prevents the media player being reloaded if the URL hasn't changed. I get this in some places when zooming around.

I'll post this as a patch cos I'm not sure about the python - I don't know why it seems to need the 'global' declarations; so if you know what's going on, Theora, please feel free to fix it!


Very nice! I think this should be version 0.7 to upload to the wiki..

I did not know about the global declaration, but apparently it is needed if you reassign the value of a global variable within a function (otherwise python tries to create a local variable with the same name, which is only present while the function is running).
1 2