User:Kephra Nurmi/lsDeejay
lsDeejay Home Edition
The lsDeejay Home Edition is a client server media control for music, video, youtube, pictures, and texture animations, started as a low lag, no gimmick version of my former lsDeejay Club Edition. The system is also known as lsDeejay SL5B Edition, as it was first distributed during SL5B.
The system is using a client server architecture, with a parcel server owned by the parcel owner (deeded to group) and clients to display and manage the media that could be distributed on the sim. Its possible to control several parcels on a sim from same display or to have several displays on a parcel.
lsDeejay parcel 08258
The lsDeejay parcel object can be an object of any form and size, that must be owned by the parcel owner. e.g. by deeding it to the group. The object should have the channel number as object description. The parcel server will check ownership and might request deeding it to a group. The first one who touches it, to activate it, will be able to command it via chat or objects like the lsDeejay media.
Script: .lsDeejay parcel 08258
<lsl> // .lsDeejay parcel 08258 // lsDeejay shoutcast management (c) Kephra Nurmi 2007 // published under Creative Commons Attribution-Share Alike 3.0 License
integer CHANNEL = 0; list uuids = [ ]; key djKey = NULL_KEY; string djName = ""; string owner;
default {
state_entry() { llSetText("Reset",<1,0,0>,0); llSetObjectName(llGetSubString(llGetScriptName(),1,-1)); CHANNEL = (integer)llGetObjectDesc(); if (0 == CHANNEL) CHANNEL = -17; owner = (string)llGetOwner(); uuids = [ owner ]; if ((string)llGetLandOwnerAt(llGetPos()) != owner) state deedme; else if (llGetSubString(owner,14,14) == "4") state ready; else state waiting; }
}
state deedme {
state_entry() { if (llGetSubString((string)llGetLandOwnerAt(llGetPos()),14,14) != "4") llSetText("Deed me to parcel owner group",<1,0,0>,1); else llSetText("Sell me to parcel owner",<1,0,0>,1); } on_rez(integer start_param) { llResetScript(); }
changed( integer change ) { if (( change == CHANGED_INVENTORY ) || ( change == CHANGED_OWNER )) llResetScript(); }
} state waiting {
state_entry() { llSetText("touch to activate",<1,0,0>,1); } touch_start(integer n) { key av = llDetectedKey(0); if (llSameGroup(av)) { owner = (string)av; uuids = [ owner ]; state ready; } } on_rez(integer start_param) { llResetScript(); }
changed( integer change ) { if (( change == CHANGED_INVENTORY ) || ( change == CHANGED_OWNER )) llResetScript(); }
}
state ready {
state_entry() { llSetText("",<1,0,0>,1); if (0 != CHANNEL) { if (0 < CHANNEL) CHANNEL = 0-CHANNEL; llListen( CHANNEL, "", NULL_KEY, "" ); llListen( 0-CHANNEL, "", NULL_KEY, "" ); llRegionSay( CHANNEL, "Request,Status" ); } llInstantMessage((key)owner,"Ready, listening on channel: "+(string)CHANNEL+" free memory: "+(string)llGetFreeMemory()); } listen( integer channel, string name, key id, string message ) { key k = id; if (llGetAgentInfo(k)<=0) k = llGetOwnerKey(k); if (llListFindList(uuids + [ (string)djKey ], [ (string)k ])<0) return; list tmp = llCSV2List(message); string cmd = llList2String(tmp,0); string val = llList2String(tmp,1); if (("DJ" == cmd) && (llGetListLength(tmp) == 3)) { djKey=(key)val; djName=llList2String(tmp,2); } if (("Parcel" == cmd) || ("Music" == cmd)) llSetParcelMusicURL(val); if ("Video" == cmd) llParcelMediaCommandList([ PARCEL_MEDIA_COMMAND_TYPE, "video/*", PARCEL_MEDIA_COMMAND_TEXTURE, val, PARCEL_MEDIA_COMMAND_URL, llList2String(tmp,2) ]); if ("Web" == cmd) llParcelMediaCommandList([ PARCEL_MEDIA_COMMAND_TYPE, "text/html", PARCEL_MEDIA_COMMAND_SIZE, 1024, 768, PARCEL_MEDIA_COMMAND_AUTO_ALIGN, TRUE, PARCEL_MEDIA_COMMAND_TEXTURE, val, PARCEL_MEDIA_COMMAND_URL, llList2String(tmp,2)]); }
on_rez(integer start_param) { llResetScript(); }
changed( integer change ) { if (( change == CHANGED_INVENTORY ) || ( change == CHANGED_OWNER )) llResetScript(); }
} </lsl>
lsDeejay media (Home) 08258
The lsDeejay media screen must be owned by a normal avatar. Its based on a my lsDialog script with a link message as hard coded action. The dialog for the media is defined in a notecard called '.lsDeejay media'
Script: lsDeejay dialog 08258
<lsl> // .lsDeejay dialog 08258 // lsDeejay shoutcast management (c) Kephra Nurmi 2007 // published under Creative Commons Attribution-Share Alike 3.0 License
string configName = ".lsDeejay media"; string configKey = NULL_KEY; integer configLine = 0; key configReq = NULL_KEY; integer avChannel;
list dialogNames = []; list dialogLines = []; string currentName = ""; string currentLines = ""; string currentMenu = ""; list currentOptions = []; list currentValues = []; list simpleOptions = []; list simpleActions = [];
integer djChannel = 0; key djKey = NULL_KEY; string djName = ""; list guests = [ ]; integer everybody = FALSE; integer samegroup = FALSE; integer again = FALSE; integer linked = FALSE;
integer permissions(key id) {
return (everybody || (samegroup && llSameGroup(id)) || (llGetOwner() == id) || ((NULL_KEY != djKey) && (djKey == id)) || (llListFindList(guests, [ llKey2Name(id) ])>=0));
}
configRestart() {
configName = ".lsDeejay media"; key conf = llGetInventoryKey(configName); if ((string)conf == configKey) return; if ((NULL_KEY != configKey) && (llGetFreeMemory() < 6000)) llResetScript(); dialogNames = []; dialogLines = []; simpleOptions = []; simpleActions = []; currentName = ""; currentLines = ""; djChannel = 0; djKey = NULL_KEY; djName = ""; guests = [ ]; everybody = FALSE; samegroup = FALSE; if (conf == NULL_KEY) return; configKey = conf; configLine = 0; configReq = llGetNotecardLine(configName,configLine);
}
flushDialog() {
if ("" == currentName) return; if ("" == currentLines) return; integer i = llListFindList(dialogNames,[ currentName ]); if (i>=0) { dialogNames = llDeleteSubList(dialogNames,i,i); dialogLines = llDeleteSubList(dialogLines,i,i); } dialogNames = dialogNames + [ currentName ]; dialogLines = dialogLines + [ currentLines ]; currentName = ""; currentLines = "";
}
parseDialogRC(string data) {
if (llStringLength(data) == 0) return; if (llGetSubString(data,0,0) == "#") return; if ((llGetSubString(data,0,0) == "[") && (llSubStringIndex(data,"]") >= 0)) { flushDialog(); currentName = llGetSubString(data,1,llSubStringIndex(data,"]")-1); return; } if ("" == currentName) { if ("Allow=Owner" == data) { everybody = FALSE; samegroup = FALSE; } else if ("Allow=Group" == data) { everybody = FALSE; samegroup = TRUE; } else if ("Allow=All" == data) { everybody = TRUE; samegroup = FALSE; } else if ("Allow=" == llGetSubString(data,0,5)) { guests = guests + [ llGetSubString(data,6,-1) ]; } else if ("Channel=" == llGetSubString(data,0,7)) { djChannel = (integer)llGetSubString(data,8,-1); } else if ("Dialog=Again" == data) { again = TRUE; } else if ("Dialog=Once" == data) { again = FALSE; } else if ("Dialog=Link" == data) { linked = TRUE; } } else if ("*" == currentName) { integer p = llSubStringIndex(data,"="); if (0 < p) { simpleOptions = simpleOptions + [ llGetSubString(data, 0, p-1) ]; simpleActions = simpleActions + [ llGetSubString(data, p+1, -1) ]; } } else if (llSubStringIndex(data,"=") >= 0) { if ("" == currentLines) currentLines = data; else currentLines = currentLines+"\n"+data; }
}
parseDialogLines(string menu) {
currentMenu = menu; currentOptions = []; currentValues = []; integer i = llListFindList(dialogNames, [ menu ]); if (i < 0) return; list l = llParseString2List(llList2String(dialogLines,i),[ "\n" ], []); integer n = llGetListLength(l); integer k; string s; for (i = 0; i<n; i++) { s = llList2String(l, i); k = llSubStringIndex(s,"="); if (k>0) { currentOptions = currentOptions + [ llGetSubString(s,0,k-1) ]; currentValues = currentValues + [ llGetSubString(s,k+1,-1) ]; } }
}
action(string message, key id) {
llMessageLinked(LINK_THIS,djChannel,message,id);
}
default {
state_entry() { configRestart(); avChannel = 1000+(integer)llFrand(3000.0); llListen( avChannel, "", NULL_KEY, "" ); } changed(integer type) { if (type & CHANGED_OWNER) llResetScript(); if (type & CHANGED_INVENTORY) configRestart(); } dataserver(key queryId, string data) { if (queryId != configReq) return; if (data != EOF) { llSetText("parsing line "+(string)configLine,<1,0,0>,1); parseDialogRC(data); configReq = llGetNotecardLine(configName,++configLine); } else { string nextConf = llList2String(llCSV2List(llGetScriptName()),1); if (("" != nextConf) && (configName != nextConf)) { configName = nextConf; configLine = 0; configReq = llGetNotecardLine(configName,++configLine); } else { if (0 != djChannel) { if (0 < djChannel) djChannel = 0-djChannel; llListen( 0-djChannel, "", NULL_KEY, "" ); llListen( djChannel, "", NULL_KEY, "" ); } llSetText("",<1,0,0>,1); flushDialog(); llOwnerSay("Ready, listening on channel: "+(string)djChannel+ " free memory: "+(string)llGetFreeMemory()); } } } touch_start(integer num) { key id = llDetectedKey(0); if (!permissions(id)) return; if (linked) { integer l = llDetectedLinkNumber(0); integer p = llListFindList(simpleOptions, [ llGetLinkName(l) ]); if (0 <= p) action(llList2String(simpleActions, p), id); else { p = llListFindList(dialogNames, [ llGetLinkName(l) ]); if (p >= 0) { parseDialogLines(llList2String(dialogNames,p)); llDialog(id,llList2String(dialogNames,p),currentOptions,avChannel); } } } else if ((llGetListLength(dialogNames) > 1) || (llGetListLength(simpleActions) > 0)) { currentMenu = ""; llDialog(id,llGetObjectDesc(),dialogNames+simpleOptions,avChannel); } else if (llGetListLength(dialogNames) == 1) { parseDialogLines(llList2String(dialogNames,0)); llDialog(id,llList2String(dialogNames,0),currentOptions,avChannel); } } listen(integer channel, string name, key id, string message) { key k = id; if (llGetAgentInfo(id)<=0) k = llGetOwnerKey(k); if (!permissions(k)) return; if (avChannel != channel) { llMessageLinked(LINK_THIS,0,message,id); if (llGetOwner() != k) return; list tmp = llCSV2List(message); if ("DJ" == llList2String(tmp,0)) djKey = llList2String(tmp,1); return; } if ("" == currentMenu) { integer i = llListFindList(simpleOptions,[ message ]); if (i>=0) action(llList2String(simpleActions, i), id); else { parseDialogLines(message); llDialog(id,currentMenu,currentOptions + [ "Back" ],channel); } } else if ("Back" == message) { currentMenu = ""; llDialog(id,llGetObjectDesc(),dialogNames+simpleOptions,channel); } else { integer i = llListFindList(currentOptions,[ message ]); if (i>=0) action(llList2String(currentValues, i), id); if (again) { if (llGetListLength(dialogNames) > 1) llDialog(id,currentMenu,currentOptions + [ "Back" ],channel); else llDialog(id,currentMenu,currentOptions,channel); } } }
} </lsl>
Script: .lsDeejay media 08258
<lsl> // .lsDeejay media 08258 // lsDeejay shoutcast management (c) Kephra Nurmi 2007 // published under Creative Commons Attribution-Share Alike 3.0 License
integer active = 0; integer side = 0;
default {
link_message(integer sender_num, integer num, string message, key id) { if (0 != num) { list y = [ "http://www.youtube.com/watch?v=", "http://de.youtube.com/watch?v=", "http://youtube.com/watch?v=" ]; integer j; for (j = 0; j < 3; j++) { integer i = llSubStringIndex(message,llList2String(y,j)); integer l = llStringLength(llList2String(y,j)); if (0 < i) { message = llGetSubString(message,0,i-1)+ "http://youtubemp4.com/video/"+ llGetSubString(message,i+l,i+l+10)+ ".mp4"; j = 3; } } llRegionSay(num, message); } list tmp = llCSV2List(message); if (llGetListLength(tmp) < 2) return; string cmd = llList2String(tmp,0); string val = llList2String(tmp,1); if (cmd == "Side") side = (integer)val; if (-2 < side) { if (("Profile" == cmd) && (llGetListLength(tmp) == 4)) { llSetTexture(llList2String(tmp,3),side); llSetTextureAnim(0,0,0,0,0,0,0); } if (("Picture" == cmd) || ("Web" == cmd) || ("Video" == cmd)) { llSetTexture((key)val,side); llSetTextureAnim(0,0,0,0,0,0,0); } if (("Movie" == cmd) && (llGetListLength(tmp) == 5)) { llSetTexture(val,side); llSetTextureAnim(ANIM_ON | LOOP, side,llList2Integer(tmp,2),llList2Integer(tmp,3),0,0,llList2Float(tmp,4)); } } }
on_rez(integer start_param) { llResetScript(); }
changed( integer change ) { if (( change == CHANGED_INVENTORY ) || ( change == CHANGED_OWNER )) llResetScript(); }
} </lsl>
Notecard: .lsDeejay media
# Define a channel to talk Channel=-17 # Allow either one of those Allow=Owner #Allow=Group #Allow=All # and several avatars by Callname Surename Allow=Kephra Nurmi Allow=Hixor Blumenthal Allow=Stratosphere Boelcke Allow=Alez Ember [Streams] Kephra Nurmi=Music,http://stream.kephra.de:8392 Alazarin=Music,http://stream.kephra.de:8438 [Radio] BBS=Music,http://bbstreamfr.ath.cx:8000 Pure Dj=Music,http://212.204.214.69:9000 Pulse Radio=Music,http://stream.pulsradio.com:5000 SLR2=Music,http://81.169.170.252:11001 Tags Trance Trip=Music,http://205.188.215.230:8012 Techno Base=Music,http://89.149.245.216:80 [Pictures] ClubSchool=Picture,71367ad7-5b93-9bfe-3373-cfee04a5b164 VooDoo=Picture,05562a37-e85b-2559-8484-7012946d597b NightFly=Picture,9286492d-507c-3fe3-0e61-f8464cf3466a Oxygen=Picture,90975ac6-38e5-9bdb-5bce-183e2a58521e Unser CLub=Picture,8db8af5b-6d80-fde4-7477-ae92325d9d3a The Cube=Picture,ad4e9a95-cab1-dbee-3589-01f48bcaf5ee [Web] Status=Web,fc5b5054-bf15-0585-c149-88b6694a6600,http://status.secondlifegrid.net/ Copyleft=Web,c443742b-e760-9241-b4b0-f64cfca501cb,http://www.gnu.org/copyleft/copyleft.de.html [Animation] Autobahn=Movie,a5f8bd07-c516-a257-498d-17b674dda64d,6,8,8 Achterbahn=Movie,88c294a9-3033-c829-f275-99b7def2eb3c,8,8,8 Typo=Movie,52ab3b42-5797-391c-89bc-e37e5ab73b89,6,6,8 Money=Movie,f49ecdae-d0a1-a8a8-afed-ad549dd7027f,1,2,0.2 Jenny=Movie,a1e8a7fb-34a3-c610-4c8e-43faef2c06cd,4,8,6 Traveller=Movie,e00fb005-6497-acb4-5d76-225bdba7b3c9,6,8,8 Burning=Movie,fca18caa-8436-07c7-e96f-b88a8fd9cb72,6,6,6 [Quicktime] Future is Hear=Video,52f10a42-2112-485d-2ff6-c026bc2c5d3b,http://blip.tv/file/get/Jimgustafson-TheFutureIsHear245.mov Store Wars=Video,938a7be4-8191-47a2-37b1-991c05089020,http://www.archive.org/download/StoreWars/sw_3M.mov [MPEG4] Freeware=Video,3b5da8cb-b273-20ab-267c-b5c30121243a,http://www.archive.org/download/FREEWARE2001/FREEWARE2001_64kb.mp4 Zappa=Video,ec2e7cb3-5db2-7730-f0a6-df7ef6389f59,http://www.archive.org/download/FrankZappaOnCrossfire/zappaOnCrossfire_64kb.mp4 Nosferatu=Video,9f7f63b5-31fb-64d4-e09f-85a417e9ac73,http://www.archive.org/download/Nosferatu_most_complete_version_93_mins./Nosferatu_1922_Symphony_of_Horror_64kb.mp4 [YouTube] DrH=Video,c443742b-e760-9241-b4b0-f64cfca501cb,http://www.youtube.com/watch?v=wYSlYENS_0w Anarchie=Video,33a53da1-5a19-0683-087e-2cd8722a6699,http://www.youtube.com/watch?v=hRoMxVdYL8w Stuttgart=Video,59d15c11-d91d-477d-7cd1-4d4dab843faa,http://de.youtube.com/watch?v=FjjorqwUhvY Panopti 1= Video,813e158c-00fa-3eba-3bb9-cfead222aa2d,http://de.youtube.com/watch?v=1oeVBjr0fwc Panopti 2= Video,1212537c-819e-ac24-3ad4-57e7dfee373b,http://de.youtube.com/watch?v=zWpzTxkHt8s
Sorry several of the videos are no longer available ;-(
You can pick a ready to use lsDeejay Home Edition at my Deejay Sandbox in [Apoda].