Old 28th August 2004, 05:21   #1
shaneh
Major Dude
 
Join Date: Jan 2004
Location: Brisbane, Australia
Posts: 1,193
Winamp Scripting

Just a quick update cause I have to leave. This is the start of some scripting support I am adding to Winamp. You cant do much with it yet, and it can only run one script at a time (it currently stays running to recieve events, so the scripting object isnt deleted thus not freed etc). And is a fair bit buggy when the script borks.

Anyway, paste this into the scripting window to see it at least do something. Requires Word.

Set wd = CreateObject("Word.Basic")
wd.appshow
wd.filenew
WAobj.SayHi
WAobj.Play

Sub WAObj_ChangedTrack
wd.Insert "New Track...."
End Sub

Obviously this will be much more complete over time, and allow heaps of stuff. In particular the ability to run scripts concurrently, and to be invoked from menus with arguments etc.
Attached Files
File Type: zip gens.zip (21.1 KB, 1947 views)

Last edited by shaneh; 28th August 2004 at 05:49.
shaneh is offline   Reply With Quote
Old 30th August 2004, 07:36   #2
saivert
Banned
 
saivert's Avatar
 
Join Date: Jan 2001
Location: Norway
Posts: 927
The plug-in doesn't appear to be loaded. I tried to run "REGSVR32 gen_script1.dll", but that didn't work. Any suggestions?
saivert is offline   Reply With Quote
Old 30th August 2004, 07:54   #3
shaneh
Major Dude
 
Join Date: Jan 2004
Location: Brisbane, Australia
Posts: 1,193
Theres no registering involved, its all self contained. The type library is a resource in the .exe.

Its probably just a weird version thing. Im using xp sp2 with vs.net 2003 installed. Thus it uses all the latest CRTs etc.

Ill update a new version, its a bit buggy though. It does allow you to do some stuff with the playlist though:

Like;

set x = playlist
msgbox x(3)

msgbox playlist.count

for each track in playlist
msgbox track
next

and so forth. Im using standard names for automation where possible so you can use some of the nicer things in vbscript etc. (note it currently crashes for some reason when using the 'for each' stuff).

It currently leaks memory just to make life easier, I'll fix it up later. It kills the object after the script is finished currently so events will appear not to be working.
Attached Files
File Type: zip gens.zip (23.0 KB, 1074 views)
shaneh is offline   Reply With Quote
Old 30th August 2004, 08:23   #4
saivert
Banned
 
saivert's Avatar
 
Join Date: Jan 2001
Location: Norway
Posts: 927
I'm using Windows XP Professional with SP-1 only (Build 2600.xpsp2.030422-1633: Service Pack 1) as reported by winver.
It says xpsp2 cos' of Windows Update. I have not installed the complete Service Pack 2 (standalone installer), which is not out yet. And I don't have "vs.net 2003" either. What's the deal??
saivert is offline   Reply With Quote
Old 30th August 2004, 08:27   #5
shaneh
Major Dude
 
Join Date: Jan 2004
Location: Brisbane, Australia
Posts: 1,193
The standalone installer for sp2 has been out for some time... I installed it a few weeks ago. MS has it on their site.

But I doubt that would be the problem, its probably the lack of vs.net2003. Do you have MSVCR71.DLL in your windows system directory? (note the '1'). It requires that at the moment, I'll link it statically later on, or use the older CRT.
shaneh is offline   Reply With Quote
Old 30th August 2004, 10:15   #6
shaneh
Major Dude
 
Join Date: Jan 2004
Location: Brisbane, Australia
Posts: 1,193
Heres a version that links msvcr71 statically so the dll isnt needed. (the .dll should be able to be installed with the .net framework if you want it). It also fixes the crash when using 'for each'. Events will work in this one too.

EDIT: removed some .reg stuff form the .dll which wasnt needed. and fixed some windowing problems.
Attached Files
File Type: zip gens.zip (32.9 KB, 1039 views)

Last edited by shaneh; 30th August 2004 at 10:34.
shaneh is offline   Reply With Quote
Old 30th August 2004, 11:12   #7
saivert
Banned
 
saivert's Avatar
 
Join Date: Jan 2001
Location: Norway
Posts: 927
Thank! This helped a lot.
I didin't find SP-2 on Windows Update. They claimed it would be installed automatically if I had Automatic Updates turned on for Windows Update. I'll search for it on their search page. Maybe you have the URL??

You are using IActiveScript and IActiveScriptSite right?? Or are you just using "Microsoft Script Control" ActiveX Control?
saivert is offline   Reply With Quote
Old 30th August 2004, 11:15   #8
shaneh
Major Dude
 
Join Date: Jan 2004
Location: Brisbane, Australia
Posts: 1,193
http://www.microsoft.com/downloads/d...displaylang=en

Its 270mb though, the auto-update would come in at less than half that. But I have bandwidth to burn and want to slip stream it so I dont have to redownload it again if i ever format or install another machine.
shaneh is offline   Reply With Quote
Old 30th August 2004, 11:18   #9
saivert
Banned
 
saivert's Avatar
 
Join Date: Jan 2001
Location: Norway
Posts: 927
You are on, right this time with me huh!! Noticing the quick reply...

Can you explain what the lower edit box is for??
saivert is offline   Reply With Quote
Old 30th August 2004, 11:26   #10
shaneh
Major Dude
 
Join Date: Jan 2004
Location: Brisbane, Australia
Posts: 1,193
I was using it for testing running multiple scripts, its not used at all at the moment. When I start adding some multi-thread support I will make use of it. The final version wont use it at all, but will load stuff up from 'startup_xxx.vbs' and 'changedtrack_xxx.vbs' and 'playlistaction_xxx.js' files etc.

At the moment I am trying to get the object design done, its a bit tricky. For example enumerating the track list is complicated by the fact that the list can change at any time. I can cache a copy, but it could potentially be quite large. Currently the 'mediaitem' objects are created on demand, which is nice, but is difficult to manage when the playlist changes.

The same will be true of things like 'send to' selecions, media library queries etc.

The thread stuff shouldnt be too difficult, I already know how im going to do it, just a matter of actually doing it.

As for the replies.. I have my messenger account hooked up to the replies so I get a notification when theres a reply to my thread.
shaneh is offline   Reply With Quote
Old 30th August 2004, 11:38   #11
saivert
Banned
 
saivert's Avatar
 
Join Date: Jan 2001
Location: Norway
Posts: 927
Can you compile a list of the methods and properties of WAObj, as I don't have OleView (VC++ not installed at school computers).
saivert is offline   Reply With Quote
Old 30th August 2004, 11:47   #12
shaneh
Major Dude
 
Join Date: Jan 2004
Location: Brisbane, Australia
Posts: 1,193
Theres not really any at the moment, just 'Play' and 'SayHi'. Plus a 'ChangedTrack' event - I may change this to an event on the playlist object instead. The problem with that is it requires a 'playlist' object to be created - and I want to keep the objects as being created dynamically on demand so they arent created if theyre not needed.

Then again, theres likely to be only a couple objects that would need to be created like this, so the overhead would be low...

Adding new methods takes about 5 seconds, most of them are just sendmessage calls. I want to get the design done properly first.

The hard part is managing objects, and internal allocations etc. The playlist problem is a good example, I think I will just use a snapshot when the enumerator is first accessed.

+ the WAObj is going to be renamed the 'Application' object, in keeping with standard naming conventions.

EDIT: There is aslo a 'playlist' property on the waobj. On the playlist object there is a 'Item' 'Count' and a enumerator. The Item takes an index (can also be used like - playlist(index)) which returns a 'MediaItem'.

Currently the 'MediaItem' just has a 'Name' property. But I guess it will have stuff like 'Title' , 'Play()' etc.

I can submit the .tlb file, but it should be a resource of the .exe anyway.
shaneh is offline   Reply With Quote
Old 30th August 2004, 13:34   #13
saivert
Banned
 
saivert's Avatar
 
Join Date: Jan 2001
Location: Norway
Posts: 927
How do I get the title and the index of the current playing item, for use in the event WAObj_ChangedTrack.

code:

Sub WAObj_ChangedTrack
MsgBox "Playing " & WAObj.CurrentSong
End Sub

saivert is offline   Reply With Quote
Old 30th August 2004, 13:43   #14
shaneh
Major Dude
 
Join Date: Jan 2004
Location: Brisbane, Australia
Posts: 1,193
You cant :P

Not yet anyway. As I said, its just a prototype to show it can be done, not that it is actually done.

Eventually you will be able to do stuff like

playlist.currentitem
or
playlist.getcurrent()
or
playlist.item(playlist.currentpos())
or the current playlist position will be passed in the changedtrack event.

or whatever I choose to do.. theres many different ways of doing things. Once I get more things done, Ill post a complete list of the object model.
shaneh is offline   Reply With Quote
Old 31st August 2004, 05:14   #15
shaneh
Major Dude
 
Join Date: Jan 2004
Location: Brisbane, Australia
Posts: 1,193
A small update with some more interesting stuff. Has the ability to run and stop scripts to make life easier.

added:
position property to playlist get/set
position property to media items
filename property to media items
title property to media items
ATFString method to media items

An nice example of it in action:

------
Set ieo = CreateObject("InternetExplorer.Application")
ieo.visible = true

Sub WAObj_ChangedTrack
ieo.Navigate2 ("http://www.audioscrobbler.com/music/" + playlist(playlist.position).ATFString("%artist%"))
end sub
------

Will navigate IE to the artist page on Audioscrobbler on every song change. You could do any action you want on any song with any ATF stuff with whatever event. But this is just a nice example. I'll write something up which parses the page and attempts to enqueue the top song later on.

Another simple example:

Set wd = CreateObject("Word.Basic")
wd.appshow
wd.filenew

Sub WAObj_ChangedTrack
wd.insert playlist(playlist.position).ATFString ("%artist% - %album% '('%filename%')'") + vbNewLine
end sub


With ATF, a lot of possibilities already exist, so I will work on getting the threading and loading from files working soon. As well as adding items to the playlist right click and send to menu.
Attached Files
File Type: zip gens.zip (35.1 KB, 864 views)
shaneh is offline   Reply With Quote
Old 31st August 2004, 10:35   #16
saivert
Banned
 
saivert's Avatar
 
Join Date: Jan 2001
Location: Norway
Posts: 927
More examples and a suggestion

More examples
code:

Const ForReading = 1, ForWriting = 2, ForAppending = 8
Const LogFile = "c:\songlog.txt"
Set fso = CreateObject("Scripting.FileSystemObject")

Sub WAObj_ChangedTrack
Dim s, text
s = playlist(playlist.position).ATFString("%artist% - %album% '('%filename%')'")

If Not fso.FileExists(LogFile) Then
Set text = fso.CreateTextFile(LogFile)
Else
Set text = fso.OpenTextFile(LogFile, ForAppending)
End If
text.WriteLine s
text.Close
End Sub



Suggestion

Why not putting error messages in the lower edit box, instead of calling MessageBox() all the time. Very nasty if script contains a lot of errors (not that I have a lot of errors in my scripts).
saivert is offline   Reply With Quote
Old 31st August 2004, 10:43   #17
shaneh
Major Dude
 
Join Date: Jan 2004
Location: Brisbane, Australia
Posts: 1,193
That box wont exist at all eventually, or even the dialog. Well I might have one that could be called up for testing or whatever. If you want to avoid errors, just put

On Error Resume Next

At the start, or make your own error handler. I will probably make some kind of console output method for use by scripts evenutally though.

There still the complicated matter of events from dynamically created objects. (ie handling events on objects create by 'createobject'). This is a known 'problem' that involves a few different solutions, none of which are that great.
shaneh is offline   Reply With Quote
Old 31st August 2004, 11:14   #18
saivert
Banned
 
saivert's Avatar
 
Join Date: Jan 2001
Location: Norway
Posts: 927
Here is my final (for now) script:
code:

Const ForReading=1, ForWriting=2, ForAppending=8
Const LogFile="c:\songlog.txt"
Const FormatText="$if(%title%,[%artist% - ]%title%,$filepart(%filename%))"
Set fso=CreateObject("Scripting.FileSystemObject")
Set ieo=CreateObject("InternetExplorer.Application")
ieo.Navigate2("about:blank")
ieo.visible=True

Sub ShowPlaylist
Dim s, i
i=1
For Each file In playlist
s = s & "<br/>" & vbCrLf & i & ". " & file.ATFString(FormatText)
i = i + 1
Next

' The following line gives error. Why??
ieo.document.write("<pre>")

ieo.document.write(s)
ieo.document.write("<br/>" & vbCrLf)
ieo.document.write("<br/>" & vbCrLf)
ieo.document.write("Tracking played items:" & "<br/>" & vbCrLf)
End Sub

ShowPlaylist

Sub WAObj_ChangedTrack
Dim s, text
s = playlist(playlist.position).ATFString(FormatText)

If Not fso.FileExists(LogFile) Then
Set text = fso.CreateTextFile(LogFile)
Else
Set text = fso.OpenTextFile(LogFile, ForAppending)
End If
text.WriteLine s
text.Close

ieo.document.write(s & "<br/>")
End Sub


1. Why can't I write ieo.document.write("<pre>")?
2. Do you have a limit on how much script code to write?
3. And why do you have to use () around parameters when it's not on the right side. Like:
code:

' Here it is neccessary with the "()"
Dim var
var = function("param", 23)

' Here it is *not* neccessary:
function "param", 23



4. Please put the Scripting dialog inside the preferences, or put it inside a embedWindow thing (skinned frame).
saivert is offline   Reply With Quote
Old 31st August 2004, 12:27   #19
shaneh
Major Dude
 
Join Date: Jan 2004
Location: Brisbane, Australia
Posts: 1,193
Nice script, keep in mind this is just preview stuff though, so its just for playing with at the moment.

I had to replace

If Not fso.FileExists(LogFile) Then
Set text = fso.CreateTextFile(LogFile)
Else
Set text = fso.OpenTextFile(LogFile, ForAppending)
End If

with just
Set text = fso.CreateTextFile(LogFile)

to get it working though. Dunno vbscript that well, so Im not sure what the problem was. Ive got a version which outputs the error and line etc on the error which makes it easier to find bugs in scripts. Id like to make a similar script which highlights the current item and outputs album covers etc. its easy enough using %dir%\folder.jpg.

1. I dunno, it worked ok for me - try removing some other lines, its possible its just too much code for the buffer.

2. 1024 bytes currently, Ill increase this, but there wont be a limit eventually, it will just allocate as much space as necessary for the file.

3. I dunno, some vbscript quirk. vbscript.dll does all the parsing of code, I just handle my own object.

4. The dialog will dissapear completely and I will just load scripts from files. I wont waste time for now making it look pretty. There will be a dialog you can invoke which will list all the running scripts and let you stop them etc. Plus it will let you start new scripts.

Please dont view the interface as any indication of the finished project, its just a quick hack to expose what can potentially be done.

PS. I found John's site which has the source to Winamp COM.
http://www.adcock8.freeserve.co.uk/
It probably has some helpful stuff in there, but it seems quite different to my implementation, so I cant make too much use of it.
shaneh is offline   Reply With Quote
Old 31st August 2004, 12:41   #20
shaneh
Major Dude
 
Join Date: Jan 2004
Location: Brisbane, Australia
Posts: 1,193
I just doubled the buffer to 2048 bytes, your script runs fine with this new buffer. So it was just hitting the limit. You can try it out with this version with a bigger buffer.
Attached Files
File Type: zip gens.zip (35.3 KB, 819 views)
shaneh is offline   Reply With Quote
Old 2nd September 2004, 11:06   #21
shaneh
Major Dude
 
Join Date: Jan 2004
Location: Brisbane, Australia
Posts: 1,193
Have now modified it to allow getting the selected items. So you can now process items that are selected and do whatever you like on them. With a bit of polish this would already be quite a useful plugin, but I will work on making it more complete.

While you can do 'system' things on the items, it would also be useful to do 'winamp' things on the items (ie, remove from the playlist, randomize selection etc).

-------

k = playlist.getselection()
msgbox "You selected " + cstr(ubound(k,1)) + " items"

for each g in k
msgbox CStr(g.position) + ". " + g.ATFString("%title% / %album%")
next
shaneh is offline   Reply With Quote
Old 2nd September 2004, 11:10   #22
shaneh
Major Dude
 
Join Date: Jan 2004
Location: Brisbane, Australia
Posts: 1,193
forgot the attachment
Attached Files
File Type: zip gens.zip (36.0 KB, 771 views)

Last edited by shaneh; 2nd September 2004 at 11:38.
shaneh is offline   Reply With Quote
Old 2nd September 2004, 14:59   #23
Lord Darius
Senior Member
 
Lord Darius's Avatar
 
Join Date: Jul 2003
Posts: 248
hi there, i planned to offer scripting support to Winamp too, but at first i had thought about using SpiderMonkey as a scripting engine (Mozilla's javascript), and eventually switched to LUA.
Unhappily, my job has been taking too much time, so that project is stalling in a very early stage.

SM or LUA would allow a feature that may not be available with the VB runtime: running scripts in a sandbox disallowing unsecure operations in a customizable way.
I don't want to download a script that will install some spyware using kinda obfuscated code like VB code can be (especially with CreateObject() )
Lord Darius is offline   Reply With Quote
Old 2nd September 2004, 16:19   #24
shaneh
Major Dude
 
Join Date: Jan 2004
Location: Brisbane, Australia
Posts: 1,193
Hey,
adding scripting support using windows script hosting is quite easy, and flexible. Its literally one or two lines to add support for javascript, perl and any other language (once you have the support for actually hosting the scripting engine). Plus the whole 'createobject' thing makes it very powerful indeed.

Also, it has a quite extensible security model, IE uses the same one. Basically you can implement your own security manager and can choose to allow or disallow object creation at runtime. This allows you to let 'safe' objects the ability to still be scripted (ie like 'safe' activex objects in IE), or you can loosen the restrictions and let file system objects etc be created if necessary.

I have already done this in 'Winamp HTML', however I went out of my way to weaken the security to allow unsafe stuff.

My reasoning for this is there is already safe scripting support in Winamp, through wasabi or whatever. Anything interesting requires some kind of permissions.

If I wanted it to be truly safe, I would have to restrict it to just stop and play type stuff, with no execution, or even changing meta data in the media library, it would be quite an undertaking to make it truly safe. Plus this is already possible with modern skin scripting.

Basically I want it to be a way for people to write their own plugins or to script common tasks easily and quickly. Scripts that are actually able to do stuff. So therefore you should use the same caution installing other peoples scripts as you would plugins. Scripts certainly wouldnt be something that came bundled with skins or something like that.

Having said that, it probably wouldnt be too much trouble to at least selectivly block 'createobject' etc type stuff per script if necessary. Although I probably wouldnt bother flagging each of my objects methods as safe or not so there could still be holes.

Last edited by shaneh; 2nd September 2004 at 16:43.
shaneh is offline   Reply With Quote
Old 2nd September 2004, 20:35   #25
Lord Darius
Senior Member
 
Lord Darius's Avatar
 
Join Date: Jul 2003
Posts: 248
Quote:
Basically I want it to be a way for people to write their own plugins or to script common tasks easily and quickly. Scripts that are actually able to do stuff. So therefore you should use the same caution installing other peoples scripts as you would plugins.
That's exactly what i wanted to achieve with my plugin
I think you're very right in the way you're doing it.
To be honest I also considered using VB or JS (WSH...) but, there are two things that made be reject that idea.
1. I don't like VB and JS (that's why i also rejected SpiderMonkey) as programming languages... just personal tastes
2. It's not 100% certain that the WSH will be present on a particular windows box (i'm assuming you're actually using the Windows Script Host)
Lord Darius is offline   Reply With Quote
Old 3rd September 2004, 00:39   #26
shaneh
Major Dude
 
Join Date: Jan 2004
Location: Brisbane, Australia
Posts: 1,193
1. You can use any language that has an active script engine. Perl has one, and there are other languages (tcl, pascal etc). You can let the user decide which one to use by just having a standard name convention (ie .vb, .vbs, .pl).

I dont like VB that much either, but as it is MS' baby, it is the most powerful. And the more I learn about this scripting stuff, the more it makes sense to use a language such as VB (for scripting). Plus people know VBscript and JS thanks to the web and VB/VBA etc. It saves them from having to learn another language, which is kind of the point in the first place.

2. Its not actually WSH, its ActiveScript. WSH is just one host for the engine, in exactly the same way this project is a host for the engine. It would be available on any platform which has IE ~3+. Either way, you could always let people install it if they want it.

Last edited by shaneh; 3rd September 2004 at 01:16.
shaneh is offline   Reply With Quote
Old 3rd September 2004, 04:22   #27
shaneh
Major Dude
 
Join Date: Jan 2004
Location: Brisbane, Australia
Posts: 1,193
You may now do basic querying of the media library. I will make a much better implementation of this later on, but this one will still remain as it is still useful. It returns an array of initialised items rather than a collection to enumerate over. This isnt too efficient for large queries, but should be ok for smaller ones.

As the query returns much richer info, I will have it cache it in the items so you can obtain it without using ATFString and the like. Obviously items obtained from a media library query do not have a 'position' in the playlist.

---basic example----

Dim x, s

Set wd = CreateObject("Word.Basic")
wd.appshow
wd.filenew

wd.Insert "Songs by Metallica" + VbNewLine

mlq = medialibrary.runqueryarray("Metallica")
x = 0
s = ""

For each track in mlq
x = x + 1
s = s + track.ATFString("%album% - %title%") + VbNewLine
if x > 200 then
wd.Insert s
s = ""
x = 0
end if
next

wd.Insert s
Attached Files
File Type: zip gens.zip (36.6 KB, 808 views)

Last edited by shaneh; 3rd September 2004 at 04:57.
shaneh is offline   Reply With Quote
Old 3rd September 2004, 06:34   #28
saivert
Banned
 
saivert's Avatar
 
Join Date: Jan 2001
Location: Norway
Posts: 927
NxS Script Control

I have recently started out my own project called NxS Script Control. It is plug-in that uses Active Scripting like ShaneH's gen_script1.dll.

It integrates with the Winamp Preferences (adds it's own page) and you can load/save script files.

The object in script that controls Winamp is called "Winamp", and it currently has these methods:
- Play()
- Stop()
- Next()
- Prev()
- AddToLog("string to add")

It has a log list that outputs error messages and text passed to AddToLog.

I will eventually add more stuff, like in ShaneH's plug-in.

Download it and try it out...
Attached Files
File Type: zip gen_nxsscriptcontrol.zip (68.2 KB, 916 views)
saivert is offline   Reply With Quote
Old 3rd September 2004, 07:23   #29
saivert
Banned
 
saivert's Avatar
 
Join Date: Jan 2001
Location: Norway
Posts: 927
Here is more script for the masses!!
code:

Dim x, s, wd

Set wd = CreateObject("InternetExplorer.Application")
wd.Navigate2("about:blank")

wd.document.write "<html><head>"
wd.document.write "<title>Winamp Media Library</title>"
wd.document.write "</head>"
wd.document.write "<body bgcolor=black text=#CEFFCE>"
wd.document.write "<p>"

k = playlist.getselection()
wd.document.write "You selected " + CStr(UBound(k,1)) + " items: "
wd.document.write "</p><p>"

For Each g In k
wd.document.write CStr(g.position) + ". " + g.ATFString("%title% / %album%")
Next
wd.document.write "</p>"

wd.document.write vbNewLine & "<table border=1>" & vbNewLine

mlq = medialibrary.runqueryarray("?")
x = 0
s = ""

For Each track In mlq
x = x + 1
s = s & "<tr>" & _
track.ATFString("<td>[%artist%]</td>[<td>%title%</td>]") _
& "</tr>" & VbNewLine
' Write out in increments of 200 songs (buffer)
If x > 200 Then
wd.document.write s
s = ""
x = 0
End If
Next

wd.document.write s + vbNewLine

wd.document.write "</table>"

wd.document.write "<p><u>Result from ping command:</u></p>"
wd.document.write "<pre>" & CatchConsoleOutput("ping localhost") & "</pre>"

wd.document.write "</body></html>"

wd.visible = True ' All written, show IE
' I just love "InternetExplorer.Application" :-)

' How to execute an application
Sub RunApp(app)
Dim WshShell
Set WshShell = CreateObject("WScript.Shell")
WshShell.Run app, 5
End Sub
' Example:
' RunApp "notepad.exe"

' How to catch output from console apps
Function CatchConsoleOutput(app)
Dim WshShell, prog, s
Set WshShell = CreateObject("WScript.Shell")
Set prog = WshShell.Exec(app)
While (prog.Status = 0) And (Not prog.StdOut.AtEndOfStream)
s = s & prog.StdOut.Read(1)
Wend
CatchConsoleOutput = s
End Function



Hope you like it...
saivert is offline   Reply With Quote
Old 3rd September 2004, 09:44   #30
Lord Darius
Senior Member
 
Lord Darius's Avatar
 
Join Date: Jul 2003
Posts: 248
why not take the best of all worlds and make one plugin in a collaborative effort ?

IMHO, saivert's interface is better (the one i started was basically based on the same idea).
One good thing would be to have a list of the currently loaded scripts, and be able to stop and start them at will (like in the Winbot IRC bot).

For my plugin, my intent was to implement all the functionality of the SDK through some objects (Winamp, Winamp.mainwnd, Winamp.playlist etc), plus event handling.
i also wanted the ability to be able to add dynamic extensions to the plugin, for example to add some database or networking support, for instance. I guess it's not that useful here, as Active Scripting can use COM objects

As for languages, it would be nice also if a different script file extension (js, vbs...) would use the appropriate engine.

Last but not least, to make this plugin really useful, even though it's the most boring part in development, a big effort should be put on documentation, else, only few people will bother trying to learn the API from samples only.

These were my 2 cts
Lord Darius is offline   Reply With Quote
Old 3rd September 2004, 11:58   #31
shaneh
Major Dude
 
Join Date: Jan 2004
Location: Brisbane, Australia
Posts: 1,193
Added a few more methods and properties. Have changed the way the runqueryarray works, it now does a standard query. So queries are now of the form:
"type = 0", "artist HAS metall" etc

I will probably put the keyword query method back in under another name.

Have changed the base object to "Application" in keeping with standard automation naming conventions.

Can now create MediaItems by using "LoadItem" and a file name. Or using "GetItem" and a filename to retrieve stuff from the media library.

ATFString can now query for media library items. (rating,playcount etc)

Added basic play,pause etc operations, and a clear method for the playlist.

I have decided that the array mechanism of doing media library queries is ok, as you need to make a copy any way in case another plugin frees your query. But I will probably add another more efficient version of the query that doesnt make a copy, for cases where you want to enumerate the results straight away, and dont need the copy sticking around to process later in an event for example.

With that in mind, I am debating the merits of multi-threading the scripts, as it would require a lot of synchronisation, and I am not sure what is and isnt thread safe in winamp, plus there is the potential for deadlocks.

As the scripts can potentially do anything, it is potentially quite dangerous to make the scripts run in a separate thread to winamp - they would be likely to conflict with other plugins. Thus they will simply run synchronously, just like normal plugins.

Note that this will still allow events and so forth to run, they will just not run simultaneously. Just like normal plugins.

-----------

@Lord Darius. As Ive said numerous times, this is not the interface the plugin will use. As it is obviously still a work in progress, while I am developing it, the first thing I need to do when I fire up winamp is type some test script and test it. This interface allows that. Files arent of any use at the moment as I am constantly changing what I am testing.

The plugin will simply load scripts from files such as:

startup_1.vbs
plscommand_Upload to Ftp.js

etc. The extension will indicate the scripting engine to use. And the plugin will pick them up and run them and add menus etc as appropriate. I will still supply I similar interface to this debug one, for testing scripts, and a means to see what scripts are currently connected for events (running) and let you stop them etc, plus let you load arbitrary scripts etc. Plus supply some kind of console ouput which you can view or hide. It will also have a browser component to it which will let you make use of the scripting inside a browser window in the media library.

But I'll say it again just to be sure. This is not the interface the final plugin will use. It is for testing purposes only, do not draw judgement on it.

As for documentation, you may load the included .tlb in an object browser (any vb/vba/vis studio/ms word type app has one) and you will see all the methods and properties. (done so far, IT IS NOT COMPLETE - testing purposes only, yada yada.).
Attached Files
File Type: zip gens.zip (40.2 KB, 865 views)

Last edited by shaneh; 3rd September 2004 at 12:37.
shaneh is offline   Reply With Quote
Old 3rd September 2004, 13:39   #32
shaneh
Major Dude
 
Join Date: Jan 2004
Location: Brisbane, Australia
Posts: 1,193
This script will enqueue a random track from the artist of the current track every track change. I should probably have a test to check that it doesnt enqueue the same item. I will need to implement some ICompare type interface on the media items I guess.

If you iterate through the playlist to make sure your not adding a dupe, itd be a nice little script to generate an ever growing playlist of a selection of a couple artists.

Next up will be changing media library meta data, then working on the general interface. Then adding working on methods for manipulating 'send to' selections, then switching items about on the playlist and other less important commands. Afterwards, I will probably add an ID3 object for grabbing stuff out of those tags, prob a v2 thing. Wont be doing anything on it tomoorrow however.

----------

Sub Application_ChangedTrack
set p = playlist(playlist.position)
mlq = medialibrary.runqueryarray("artist HAS """ + p.ATFString("%artist%") + """")
if ubound(mlq,1) > 1 then
y = Int((ubound(mlq,1)) * Rnd + 1)
mlq(y).Enqueue
end if
end sub

Last edited by shaneh; 3rd September 2004 at 13:55.
shaneh is offline   Reply With Quote
Old 6th September 2004, 10:35   #33
saivert
Banned
 
saivert's Avatar
 
Join Date: Jan 2001
Location: Norway
Posts: 927
More chatting....

@Lord Darius: I like the idea of a collaborative effort.
I don't know about ShaneH - He may be working best on his own,
but I would be happy If you and me decided to share code,
and create something beatuful together ..hmmm, what's that suppose to mean ...

@ShaneH: I know that you don't intend to have a dialog in a finished version.
It will basically be the same with NxS Script Control, but I like to
give users the ability to edit and manage scripts inside Winamp, instead of
having both Explorer and Notepad open.
NxS Script Control (new version below) detects which script engine to use
by reading the script itself. The user must place a comment at the first line
to indicate which script type it is.
VBScript example:
code:

'@Language = VBScript


JScript (JavaScript) example:
code:

/*@Language = JScript*/



If such a comment isn't found then it will use the file's extension to select
the engine. But this sucks since I would have to maintain a list of known
extension like vbs, js, psc (PersScript) and more.
You could also just try to parse the script using one engine after the other until
an engine parsed it successfully, but then all scripts would have to be flawless.

I will always include the source code with my plugins keeping it open-source.
@Lord Darius: Please take time reading the source for NxS Script Control, and
give me feedback (private message on forum or e-mail) on it. It will help me improve my
coding skills and who know, maybe you will learn something too...
Attached Files
File Type: zip gen_nxsscriptcontrol.zip (90.8 KB, 929 views)
saivert is offline   Reply With Quote
Old 6th September 2004, 11:28   #34
shaneh
Major Dude
 
Join Date: Jan 2004
Location: Brisbane, Australia
Posts: 1,193
+settimeout method, used for callback on a timeout. Timer is cancelled after triggered.

ie.
settimeout 5000, getref("myfunc")
sub myfunc
msgbox "Called"
end sub

+quit method
Used to terminate the script and stop listening for events.

+Loads items from files plugins\scripts\startup_*.vbs and playlist_*.vbs. Items in startup* are run at startup, items in playlist* are run when selected from the playlist 'Scripts' menu.

+Experimental 'attachevents' method for binding the events of a dynamically created object. Works similar to 'connectobject' of wscript. Its use is not recommended at the moment, and it wont work with IE either.
ie.

Set calobj=CreateObject("MSCal.Calendar.7")
attachevents calobj, "CALE"
calobj.nextday
sub CALE_AfterUpdate
msgbox "calendar event"
end sub

+changed 'stop' to 'stopplayback' due to global name conflict

+Removed dialog for now, just uses files atm.

+enumerator on the medialibrary. Can also get any item in the media library through Item(). ie.

msgbox medialibrary(123).Title

+Can read and change rating and playcount through the rating propery of media items

+alubm,artist,title is cached when mediaitem is created through a media library query

There is still lots of static buffers and globals etc which need to be cleaned up. Plus an interface for managing scripts (editing,running,stopping etc). I may put some check marks against the menu items of currently running scripts to simplify the interface, so you can start and stop them easily.
Attached Files
File Type: zip gens.zip (49.8 KB, 807 views)

Last edited by shaneh; 6th September 2004 at 12:59.
shaneh is offline   Reply With Quote
Old 7th September 2004, 15:23   #35
shaneh
Major Dude
 
Join Date: Jan 2004
Location: Brisbane, Australia
Posts: 1,193
+Basic hot key support. Files named hotkey_*.vbs will be registered as hot key runnable. I will add a 'registerhotkey' type message later, with a callback for scripts that stay running.
[I will probably remove the hotkey_* type files, and just register all playlist_*/sendto_*/menu_* etc files as hot key assignable instead).

+Canceltimer(timerid). You can cancel a timer set by 'settimeout' by using the id received from 'settimeout'.

+playlist.Deleteindex - remove an item from the playlist

+playlist.Swapindex - swap two indexes in the playlist

+mediaitem.insert(index) - insert the item at the specified position in the playlist

+much improved 'changedtrack' event detection. avoids dupes without having to do filename comparisons etc.

Some other example scripts, including one which makes the playcount only increment if its been played for over 9 seconds.
Attached Files
File Type: zip gens.zip (50.5 KB, 809 views)
shaneh is offline   Reply With Quote
Old 9th September 2004, 15:59   #36
shaneh
Major Dude
 
Join Date: Jan 2004
Location: Brisbane, Australia
Posts: 1,193
Fixed many static buffers, much better loading from file support. Should support basically any size file. Removed hotkey_* type, all playlist_* files can be assigned hot keys.
Improved visual display of items in playlist menu.
Improved loading of playlist_* named files.
Fixed some internal object management and the way scripts quit.


+Added 'lastplay' property
+Getting selected items now re-parses the 'length' of playlist items correctly so it doesnt get reset.
(if the playlist hasnt yet loaded the extended file information, it will query the ML to avoid having ugly titles).

Quite a few example scripts, some of which make use of a fairly generic quicksort algorithm which has been used to sort selected playlist entries by rating, playcount, last played etc. Its a useful bit of script for sorting stuff in the playlist in general - it could use a little bit of tweaking but its generally pretty reasonable.

Plus some examples to just randomize a selection, reverse a selection, 'preview' a selection etc.
Attached Files
File Type: zip gens.zip (56.2 KB, 899 views)
shaneh is offline   Reply With Quote
Old 9th September 2004, 17:30   #37
neFAST
Member
 
Join Date: Sep 2004
Location: Montreal
Posts: 56
Send a message via ICQ to neFAST
[edit]
hello again,

I'd like to know if their a command the results of a quey in the library ?

In fact I'd like to export my songs list but this MyFile.WriteLine(track.ATFString("%artist% - %album% - %tracknumber% %title%"))

gives me this :

Zero 7 - When It Falls - 11 Morning Song
Zero 7 - When It Falls - 10 In Time
Zero 7 - When It Falls - 09 Look Up
Zero 7 - When It Falls - 08 Speed Dial No 2
Zero 7 - When It Falls - 07 The Space Between
Zero 7 - When It Falls - 06 When It Falls
Zero 7 - When It Falls - 05 Over Our Heads
Zero 7 - When It Falls - 04 Passing By
Zero 7 - When It Falls - 03 Somersault
Zero 7 - When It Falls - 02 Home
Zero 7 - When It Falls - 01 Warm Sound
Zebda - Utopie D'occase - 13 Le Répertoire
Zebda - Utopie D'occase - 12 Le Paranoïaque
Zebda - Utopie D'occase - 11 Le Bonhomme Derriè

...

so I'd like to kwno how winamp chose the order of the results of a query !

My other questions are : what does "ATFString" do ? And how can i make my vbs in a standalone script ?

Sorry for the "newbie inside" style !

Last edited by neFAST; 9th September 2004 at 18:24.
neFAST is offline   Reply With Quote
Old 10th September 2004, 00:50   #38
shaneh
Major Dude
 
Join Date: Jan 2004
Location: Brisbane, Australia
Posts: 1,193
The results from the media library are just returned as given by the media library, as far as I know there is no way to specify the sort order. The results will need to be sorted after you get them. I will write a quick script to demonstrate how to sort them, it is not too difficult.

If they are already in exact reverse sort order, you could always work your way backwards from mlq.Count to 1. Otherwise, if each item is on its own line, you can just run it through the 'sort' command and it should work fine.

ATFString takes a filename and a format string and parses it through 'advanced title formatting', similar to that used in the playlist. The filename is taken from the 'mediaitem' it is operating on. My "toaster" plugin has a readme which explains in more detail all the available tags etc.

Because items like 'album' 'artist' and 'title' are cached after a media library query, you are actually better off using:

track.artst + track.album + track.ATFString("%tracknumber%") + track.title

As it will not have to re-look it up if the mediaitem (track) has come from a media library query.

You cannot currently write a script standalone, although it wouldnt be too difficult for me to implement, though I hadnt planned it. You will eventually be able to run scripts by just choosing a 'run script' command from within winamp then browsing for the file, if that is all you are after. For now just call it "playlist_whatever.vbs" and run it from the playlist menu.
shaneh is offline   Reply With Quote
Old 10th September 2004, 01:02   #39
neFAST
Member
 
Join Date: Sep 2004
Location: Montreal
Posts: 56
Send a message via ICQ to neFAST
Thanks for the answer !
In fact I need the export to be a little quicker cause it takes something like 3mins for 16000 tracks.
And I think the quicksort could make this even longer !

I'm gonna test your trick "track.artst + track.album" to improve exporting time nad I'll tell ya.

in fact if I have perfect reverse order it's not a problem cause the export file is parsed with a php script. I just need to know it, that's why i did ask how the results are returned.

COuld you (quickly) tell me what does your plugin really do ? Is it something like a functions library ?
Plugins are in C++, aren't they ? and scripts in vb ...

Last question : %length% return length in seconds and *three* decimals !!! Is there any way to get h:m:s ?

And again : thanx !!
neFAST is offline   Reply With Quote
Old 10th September 2004, 01:15   #40
shaneh
Major Dude
 
Join Date: Jan 2004
Location: Brisbane, Australia
Posts: 1,193
Use lengthf as outlined in the Toaster readme. You said you just wanted to do a one time export, so therefore why does the time it takes matter? (remember to put a 'quit' statement after the export otherwise the script keeps running).

3 mins is quite slow, but I guess it depends on your machine speed. I exported about 8,000 items to file in about 2 seconds, though I have a fairly reasonable machine. A sort would take a split second to do, try running 'sort exported.txt' and see how quick it is. (I am not sure if sort is standard on XP, but I think so, otherwise get cygwin). But still 3mins seems strange, try posting your script and I'll test it and see if its the same and see how it can be sped up.

If you are planning on doing programmatic exports regularly, then this might not be the plugin for you. It is designed for adding a quick customisation to Winamp without having to develop or install heaps of frivolous plugins. Its not really meant for use by external plugins, as they could typically do everything the script does, only faster as they dont have to parse script.

This plugin is indeed written in C++, it makes use of COM to create an instance of MS vbscript engine, and adds my own automation object to the script which can be used to control winamp. Thus allowing you to control winamp through vbscript.
shaneh is offline   Reply With Quote
Reply
Go Back   Winamp & SHOUTcast Forums > Developer Center > Winamp Development

Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump