captbaritone / webamp Goto Github PK
View Code? Open in Web Editor NEWWinamp 2 reimplemented for the browser
Home Page: https://webamp.org
License: MIT License
Winamp 2 reimplemented for the browser
Home Page: https://webamp.org
License: MIT License
TypeError: string is null
for (var i = 0, len = string.length; i < len; i++) {
In the native app (v2.91) when you pause or stop, the player actually does a very quick fade out. I believe when you resume play (from a paused state) it fades back in.
Hosting it myself killed my VPS, and rawgit.com seems to cause the position slider to not work in Firefox. Not sure why. Any ideas? Anyone want to host the file?
If the balance is less than 25 (24 or less) in either direction, it should stick to 0.
Many of the actions can do have hot keys in the native app, lets support them!
L
Play file (open file chooser)Ctrl-L
Play from URL (open prompt)Ctrl-T
Toggle remaining/elapsed timeZ
PreviousX
PlayC
PauseV
StopB
NextBoth in full and shade view the progress/elapsed time text blinks while paused. About 1 second on, one second off.
I would love to be able to have the user (or an internal function) supply the url of a directory containing the skin files and have the player start using that skin.
Currently I'm blocked, because I can't find a way to set values like these urls via Javascript:
https://github.com/captbaritone/winamp2-js/blob/master/winamp.css#L261
The real app ignores the previous/next button presses unless you have multiple files in your playlist. Since we don't have playlist yet, we should just ignore these inputs until we do.
Any chance this will play midi? I hope so :)
The real app hides all of these items when not either actively playing or paused.
The Canvas line drawing gives us too pretty of a line, complete with anti-aliasing. Let's try drawing it a pixel at a time to get a look that matches the native app's look better.
I've run into a strange problem. The the red pixels of the bottom right hand order of the PLAYPAUS.BMP don't seem to render correctly in FF or Chrome. On the left you will see Firefox, and the right OSX Preview. Chrome show the same thing. A while pixel where it should be black.
First reported in #17, but moved here to it's own issue.
Uncaught TypeError: Failed to set the 'currentTime' property on 'HTMLMediaElement': The provided double value is non-finite.
winamp.js:48
-> this.audio.currentTime = this.audio.duration * (percent/100);
Did this years ago myself, here is CSS you can rip the EQ/Playlist window stuff from:
https://gist.github.com/oneman/488f82898401b49c6a4e
https://www.youtube.com/watch?v=9WVrHbc-sMo
@PAEz noticed that the background texture for the visualization is specified in viscolor.txt. We should use those colors when rendering the visualization. Hopefully we can find a way to do it so that we don't have to re-render the background with each frame.
Row 0 is the background color of the visualization area.
Row 1 is the color of the dots that appear in the visualization area
-- http://wiki.winamp.com/wiki/Editing_the_Configuration_Files#Configuration_File_.7C_VisColor.txt
You could use node-webkit and make it into a real app ;-)
I have learned that I am by no means the first person to attempt this. There are many impressive examples that each focus on different aspects of Winamp. I would like to add a section to the readme linking to all the great work that's been done and where possible host a copy for posterity. Some seem to exist only as zip files posted to old forums. Many are surely lost to the ages.
I have a branch with this currently working (https://github.com/captbaritone/winamp2-js/tree/web-audio-api), but it's quite ugly.
I hope to have it ready some time this week so that we can move forward with the issues blocked by it, which are numerous. I'll also add a label to the issues blocked by this issue.
If we move the position slider while stopped, we should not begin playing.
I'm changing how the play/pause/stop state is stored. Wait to start work on this until I say so.
I know this one might be a bit too far, however the most of the music I listen to these days is comming from spotify.
Since we already support custom skins and are now working on implementing the visualizer, we will eventually need to be able to support the skin's colors for the visualizer as specified in VISCOLOR.TXT
.
Here is a sample:
3,1,76, // color 0 = black
55,0,188, // color 1 = grey for dots
3,1,76, // color 2 = top of spec
221,227,255, // 3
3,1,76, // 4
187,198,255, // 5
3,1,76, // 6
147,165,255, // 7
3,1,76, // 8
101,126,255, // 9
3,1,76, // 10
44,79,255, // 11
3,1,76, // 12
10,50,255, // 13
3,1,76, // 14
1,36,217, // 15
3,1,76, // 16
0,29,173, // 17 = bottom of spec
139,255,240, // 18 = osc 1
139,255,240, // 19 = osc 2 (slightly dimmer)
139,255,240, // 20 = osc 3
139,255,240, // 21 = osc 4
139,255,240, // 22 = osc 5
139,255,240, // 23 = analyzer peak dots
There is some documentation here: http://wiki.winamp.com/wiki/Editing_the_Configuration_Files#Configuration_File_.7C_VisColor.txt
When we click the time elapsed, it turns into time remaining and gets a minus sign in the main view. Replicate this in shade view.
Also, make sure click the time in shade view triggers the same elapsed/remaining toggle.
Why oh why did they deprecate the <marquee>
tag?
I'm hoping that this can be done with some clever application of CSS transitions.
Since we now require a javascript library, and we don't start requesting the skin asset until all the javascript has been downloaded, it can sometimes take quite a while before Winamp actually renders. I would like to see a few things happen to improve that experience.
#winamp
div some kind of content or default state that indicates that work is being done. Maybe the Windows hourglass cursor in the center? This state will be disabled once the skin is applied.Should probably implement MIME type/file extension limitations for opening.
This can easily be done with <input type="file" accept="audio/*" />
Not so sure how the drag and drop feature handles this.
Also take into consideration Web Audio API limitations on what files it can natively open.
Unless start finding libraries/codec for alternative file types such as FLAC/MIDI
Currently we have it it hard coded for the demo file, and ignore it for all other files. This is info we have, so let's use it.
There is support for PannerNode which lets you do the balance, as well as BiquadFilterNode which lets you build an eq.
I may look into doing this as I've been looking for an excuse to really use some of the web audio stuff.
The cursors we currently use are from an earlier version of Winamp. In 2.91 they have a pointer with the action icon in the lower right hand corner. Where can we find these assets
The oscilloscope visualization in the native app seems to draw waves with greater amplitude than ours does. Can we confirm that to be true, and figure out what they might be doing differently?
Im playing with ya stuff and want sprite sheets for all the bmp files.
Ive converted what was in your css and that skinspec pdf but that still leaves a bunch of files.
Id love the x/y position and names of elements. I can figure them out by hand I guess, but would rather not and Im totally crap at naming things.
Here's what I have so far incase anyone else wants to play...
/*
Reserved words
--------------
Width
Height
X
Y
Scale - not used yet but will be used to declare the scalling method and details (slice and all that)
*/
var spritesheet = {
"shufrep.bmp": {
URL:"https://cdn.rawgit.com/captbaritone/winamp-skins/master/v2/base-2.91/SHUFREP.BMP",
"repeat": {
Width: 28,
Height: 15,
"on": {
X: 0,
Y: 30,
"active": {
X: 0,
Y: 45
}
},
"off": {
X: 0,
Y: 0,
"active": {
X: 0,
Y: 15
}
}
},
"shuffle": {
Width: 47,
Height: 15,
"on": {
X: 28,
Y: 30,
"active": {
X: 28,
Y: 45
}
},
"off": {
X: 28,
Y: 0,
"active": {
X: 28,
Y: 15
}
}
},
"equalizer": {
Width: 23,
Height: 12,
"on": {
X: 0,
Y: 73,
"active": {
X: 46,
Y: 73
}
},
"off": {
X: 0,
Y: 61,
"active": {
X: 46,
Y: 61
}
}
},
"playlist": {
Width: 23,
Height: 12,
"on": {
X: 23,
Y: 73,
"active": {
X: 69,
Y: 73
}
},
"off": {
X: 23,
Y: 61,
"active": {
X: 69,
Y: 61
}
}
}
},
"cbuttons.bmp": {
URL:"https://cdn.rawgit.com/captbaritone/winamp-skins/master/v2/base-2.91/CBUTTONS.BMP",
Width: 23,
Height: 18,
"previous": {
X: 0,
Y: 0,
"active": {
X: 0,
Y: 18
}
},
"play": {
X: 23,
Y: 0,
"active": {
X: 23,
Y: 18
}
},
"pause": {
X: 46,
Y: 0,
"active": {
X: 46,
Y: 18
}
},
"stop": {
X: 69,
Y: 0,
"active": {
X: 69,
Y: 18
}
},
"next": {
Width: 22,
Height: 18,
X: 92,
Y: 0,
"active": {
X: 92,
Y: 18
}
},
},
"TITLEBAR.BMP": {
URL:"https://cdn.rawgit.com/captbaritone/winamp-skins/master/v2/base-2.91/TITLEBAR.BMP",
"shade": {
Width: 275,
Height: 14,
X: 27,
Y: 42,
"selected": {
X: 27,
Y: 29
},
"position": {
"background": {
Width: 17,
Height: 7,
X: 0,
Y: 36
},
"thumb": {
Width: 3,
Height: 7,
"middle": {
X: 20,
Y: 36
},
"left": {
X: 17,
Y: 36
},
"right": {
X: 23,
Y: 36
}
}
}
},
"button": {
Width: 9,
Height: 9,
"option": { //winamp menu
X: 0,
Y: 0,
"active": {
X: 0,
Y: 9
}
},
"minimize": {
X: 9,
Y: 0,
"active": {
X: 9,
Y: 9
}
},
"shade": {
X: 0,
Y: 18,
"active": {
X: 9,
Y: 18
}
},
"close": {
X: 18,
Y: 0,
"active": {
X: 18,
Y: 9
}
},
"unshade": {
X: 0,
Y: 27,
"active": {
X: 9,
Y: 27
}
}
},
"titlebar": {
Width: 275,
Height: 116,
X: 27,
Y: 14,
"selected": {
X: 27,
Y: 0
},
"llama": {
X: 27,
Y: 61,
"selected": {
X: 27,
Y: 57
}
}
},
"clutterbar": {
Width: 8,
Height: 43,
X: 304,
Y: 0,
"disabled": {
X: 312,
Y: 0
},
"o": {
X: 304,
Y: 44
},
"p": {
X: 312,
Y: 44
},
"i": {
X: 320,
Y: 44
},
"d": {
X: 328,
Y: 44
},
"v": {
X: 336,
Y: 44
}
}
},
"PLAYPAUS.BMP": { // play/work indicators
URL:"https://cdn.rawgit.com/captbaritone/winamp-skins/master/v2/base-2.91/PLAYPAUS.BMP",
"play": {
Width: 9,
Height: 9,
X: 0,
Y: 0,
"background": {
// Width:9, // or 2, or what ever
X: 27,
Y: 0
},
"play": {
X: 0,
Y: 0
},
"pause": {
X: 9,
Y: 0
},
"stop": {
X: 18,
Y: 0
},
},
"work": {
Width: 3,
Height: 9,
"on": {
X: 36,
Y: 0
},
"off": {
X: 39,
Y: 0
}
}
},
"monoster.bmp": {
URL:"https://cdn.rawgit.com/captbaritone/winamp-skins/master/v2/base-2.91/MONOSTER.BMP",
"stereo": {
Width: 29,
Height: 12,
"on": {
X: 0,
Y: 0
},
"off": {
X: 0,
Y: 12
}
},
"mono": {
Width: 29,
Height: 12,
"on": {
X: 29,
Y: 0
},
"off": {
X: 29,
Y: 12
}
}
},
"posbar.bmp": {
URL:"https://cdn.rawgit.com/captbaritone/winamp-skins/master/v2/base-2.91/POSBAR.BMP",
"background": {
Width: 248,
Height: 10,
X: 0,
Y: 0
},
"thumb": {
Width: 29,
Height: 10,
X: 248,
Y: 0,
"active": {
X: 278,
Y: 0
}
}
},
"volume.bmp": {
URL:"https://cdn.rawgit.com/captbaritone/winamp-skins/master/v2/base-2.91/VOLUME.BMP",
Width: 68,
Height: 13,
"0": {
X: 0,
Y: 0
},
"1": {
X: 0,
Y: 15
},
"2": {
X: 0,
Y: 30
},
"3": {
X: 0,
Y: 45
},
"4": {
X: 0,
Y: 60
},
"5": {
X: 0,
Y: 75
},
"6": {
X: 0,
Y: 90
},
"7": {
X: 0,
Y: 105
},
"8": {
X: 0,
Y: 120
},
"9": {
X: 0,
Y: 135
},
"10": {
X: 0,
Y: 150
},
"11": {
X: 0,
Y: 165
},
"12": {
X: 0,
Y: 180
},
"13": {
X: 0,
Y: 195
},
"14": {
X: 0,
Y: 210
},
"15": {
X: 0,
Y: 225
},
"16": {
X: 0,
Y: 240
},
"17": {
X: 0,
Y: 255
},
"18": {
X: 0,
Y: 270
},
"19": {
X: 0,
Y: 285
},
"20": {
X: 0,
Y: 300
},
"21": {
X: 0,
Y: 315
},
"22": {
X: 0,
Y: 330
},
"23": {
X: 0,
Y: 345
},
"24": {
X: 0,
Y: 360
},
"25": {
X: 0,
Y: 375
},
"26": {
X: 0,
Y: 390
},
"27": {
X: 0,
Y: 405
},
"thumb": {
Width: 14,
Height: 11,
X: 15,
Y: 422,
"active": {
X: 0,
Y: 422
}
}
},
"balance.bmp": {
URL:"http://jordaneldredge.com/projects/winamp2-js/skins/default/BALANCE.BMP",
Width: 38,
Height: 13,
"0": {
X: 9,
Y: 0
},
"1": {
X: 9,
Y: 15
},
"2": {
X: 9,
Y: 30
},
"3": {
X: 9,
Y: 45
},
"4": {
X: 9,
Y: 60
},
"5": {
X: 9,
Y: 75
},
"6": {
X: 9,
Y: 90
},
"7": {
X: 9,
Y: 105
},
"8": {
X: 9,
Y: 120
},
"9": {
X: 9,
Y: 135
},
"10": {
X: 9,
Y: 150
},
"11": {
X: 9,
Y: 165
},
"12": {
X: 9,
Y: 180
},
"13": {
X: 9,
Y: 195
},
"14": {
X: 9,
Y: 210
},
"15": {
X: 9,
Y: 225
},
"16": {
X: 9,
Y: 240
},
"17": {
X: 9,
Y: 255
},
"18": {
X: 9,
Y: 270
},
"19": {
X: 9,
Y: 285
},
"20": {
X: 9,
Y: 300
},
"21": {
X: 9,
Y: 315
},
"22": {
X: 9,
Y: 330
},
"23": {
X: 9,
Y: 345
},
"24": {
X: 9,
Y: 360
},
"25": {
X: 9,
Y: 375
},
"26": {
X: 9,
Y: 390
},
"27": {
X: 9,
Y: 405
},
"thumb": {
Width: 14,
Height: 11,
X: 15,
Y: 422,
"active": {
X: 0,
Y: 422
}
}
}
}
function decorate(node, props, parent) {
Object.keys(props).forEach(function(last) {
if ((node.X !== undefined || node.Y !== undefined) && props[last] !== null && node[last] === undefined) node[last] = props[last];
if (node[last] !== undefined) props[last] = node[last];
});
Object.keys(node).forEach(function(key) {
var prop = node[key];
if (typeof prop == 'object') decorate(prop, props, node);
});
// if (parent) node.Parent = parent;
};
Object.keys(spritesheet).forEach(function(key) {
decorate(spritesheet[key], {
Width: null,
Height: null,
X: null,
Y: null,
Image: key
});
});
var a;
function createStyles(spritesheets) {
function iterate(node, imageID, path) {
if (node.X !== undefined) {
console.debug(imageID + ' ' + path + ' _size');
var rule = '.' + imageID + '.' + path + '{background-position: -' + node.X + 'px -' + node.Y + 'px;}';
// Insert CSS Rule
styleSheet.insertRule(rule, styleSheet.cssRules.length);
rule = '.' + imageID + '.' + path + '._size{width: ' + node.Width + 'px; height:' + node.Height + 'px;}';
// Insert CSS Rule
styleSheet.insertRule(rule, styleSheet.cssRules.length);
}
Object.keys(node).forEach(function(key) {
if (typeof node[key] == 'object') iterate(node[key], imageID, path + '_' + key);
});
}
var styleEl = document.createElement('style'),
styleSheet;
// Apparently some version of Safari needs the following line? I dunno.
styleEl.appendChild(document.createTextNode(''));
// Append style element to head
document.head.appendChild(styleEl);
// Grab style sheet
styleSheet = styleEl.sheet;
Object.keys(spritesheets).forEach(function(key) {
var sheet = spritesheets[key];
var image = key;
var imageID = image.replace('.', '_');
styleSheet.insertRule('.' + imageID + ' { background-image:url(\'' + sheet.URL + '\');}', styleSheet.cssRules.length);
iterate(sheet, imageID, '');
})
a = styleSheet;
}
createStyles(spritesheet);
I think we should have some sort of very minimal colored background. Here are the goals I have:
Additionally, the credits at the bottom of the page the link to my Twitter and this repository, should be styled/positioned to look classy against this new background.
Since this is highly subjective, I reserve the right to reject submissions simply because I don't like them. Sorry!
@sethiroth66 Any ideas?
Now that we support loading local skins, we are going to notice a lot more edge cases with how skins are handled.
It looks like at some point they changed to skin file to have an optional different number image format. If numbs_ex.bmp
is present, we should use it's alternate format. I believe it just gives you an extra character at the end for the -
sign.
Steps to reproduce :
When you change the volume or balance for the first time, it hides the track title, but there is no volume or balance info populated yet, so the title field is empty until you start sliding. Looks bad.
Looks like it could be built using this: https://developer.mozilla.org/en-US/docs/Web/API/AnalyserNode
In shade mode we have different assets for if the slider is on the left, right or center. Use them.
Can we get any of the following via the Web Audio API?
The native app has a large, deep context menu when you click in the upper right hand corner. After some careful looking, I think the only options we will be using are: open file from url, and select a skin.
I'd rather not redesign the context menu in CSS if we can help it, but I don't see any other solutions.
Maybe we could do a very simple version of the menu that just offers those two options?
- Play Location...
- Skins
- <Base Skin>
- TopazAmp
- Fony
Maybe there is some other option I'm overlooking?
Nice script you got there, bringing back some memories :).
You might want to take a look at https://github.com/audiocogs/aurora.js to support FLAC, OGG, mp3 etc. in all navigators!
The little green box next to the play button has a red version for when we are loading a file.
Code seem to expect a string, but when pressing cancel button it returns null and causes a JS error and breaks playback of the current file.
Splitting up the js files has made development a lot easier, but it adds a bunch of additional requests. In production, we should merge them all into one file and perhaps minify. Perhaps this a is a job for Gulp.
See these skins as an example: http://customize.org/winamp2/skins/54312
This should enable crossfades, panning, and detailed info about the track
In my zeal to support custom skins as well as shield my server from traffic, the new approach to skins always gets its files from rawgit.com. This means that you can't currently develop without an internet connection.
I think the solution is to have a variable like var production = false;
which I will override on my server. It could default to the local skin files, as well as, perhaps, a local version of the demo mp3.
At present the only difference between this code a production is that I have Google Analytics injected into my version. I don't intend to include that in this repository.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.