soundcloud-custom-player-rails 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +20 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +35 -0
- data/Rakefile +1 -0
- data/lib/soundcloud-custom-player-rails.rb +12 -0
- data/lib/soundcloud-custom-player-rails/engine.rb +6 -0
- data/lib/soundcloud-custom-player-rails/railtie.rb +6 -0
- data/lib/soundcloud-custom-player-rails/version.rb +3 -0
- data/soundcloud-custom-player-rails.gemspec +17 -0
- data/vendor/assets/images/sc-player-artwork/pause-hover.png +0 -0
- data/vendor/assets/images/sc-player-artwork/pause.png +0 -0
- data/vendor/assets/images/sc-player-artwork/play-hover.png +0 -0
- data/vendor/assets/images/sc-player-artwork/play.png +0 -0
- data/vendor/assets/images/sc-player-minimal/pause-hover.png +0 -0
- data/vendor/assets/images/sc-player-minimal/pause.png +0 -0
- data/vendor/assets/images/sc-player-minimal/play-hover.png +0 -0
- data/vendor/assets/images/sc-player-minimal/play.png +0 -0
- data/vendor/assets/images/sc-player-red/pause-hover.png +0 -0
- data/vendor/assets/images/sc-player-red/pause.png +0 -0
- data/vendor/assets/images/sc-player-red/play-hover.png +0 -0
- data/vendor/assets/images/sc-player-red/play.png +0 -0
- data/vendor/assets/images/sc-player-standard/pause-blue-hover.png +0 -0
- data/vendor/assets/images/sc-player-standard/pause-blue.png +0 -0
- data/vendor/assets/images/sc-player-standard/pause-green-hover.png +0 -0
- data/vendor/assets/images/sc-player-standard/pause-green.png +0 -0
- data/vendor/assets/images/sc-player-standard/pause-orange-hover.png +0 -0
- data/vendor/assets/images/sc-player-standard/pause-orange.png +0 -0
- data/vendor/assets/images/sc-player-standard/play-blue-hover.png +0 -0
- data/vendor/assets/images/sc-player-standard/play-blue.png +0 -0
- data/vendor/assets/images/sc-player-standard/play-green-hover.png +0 -0
- data/vendor/assets/images/sc-player-standard/play-green.png +0 -0
- data/vendor/assets/images/sc-player-standard/play-orange-hover.png +0 -0
- data/vendor/assets/images/sc-player-standard/play-orange.png +0 -0
- data/vendor/assets/javascripts/sc-player.js +725 -0
- data/vendor/assets/javascripts/soundcloud.player.api.js +140 -0
- data/vendor/assets/stylesheets/sc-player-artwork/colors.css +130 -0
- data/vendor/assets/stylesheets/sc-player-artwork/standards.css +18 -0
- data/vendor/assets/stylesheets/sc-player-artwork/structure.css +173 -0
- data/vendor/assets/stylesheets/sc-player-minimal/colors.css +138 -0
- data/vendor/assets/stylesheets/sc-player-minimal/standards.css +17 -0
- data/vendor/assets/stylesheets/sc-player-minimal/structure.css +174 -0
- data/vendor/assets/stylesheets/sc-player-red/colors.css +141 -0
- data/vendor/assets/stylesheets/sc-player-red/standards.css +32 -0
- data/vendor/assets/stylesheets/sc-player-red/structure.css +171 -0
- data/vendor/assets/stylesheets/sc-player-standard/colors-blue.css +299 -0
- data/vendor/assets/stylesheets/sc-player-standard/colors-green.css +167 -0
- data/vendor/assets/stylesheets/sc-player-standard/colors-orange.css +165 -0
- data/vendor/assets/stylesheets/sc-player-standard/standards.css +33 -0
- data/vendor/assets/stylesheets/sc-player-standard/structure-horizontal.css +209 -0
- data/vendor/assets/stylesheets/sc-player-standard/structure-vertical.css +190 -0
- metadata +96 -0
@@ -0,0 +1,140 @@
|
|
1
|
+
/*
|
2
|
+
* JavaScript interface for the SoundCloud Player widget
|
3
|
+
* Author: Matas Petrikas, matas@soundcloud.com
|
4
|
+
* Copyright (c) 2009 SoundCloud Ltd.
|
5
|
+
* Licensed under the MIT license:
|
6
|
+
* http://www.opensource.org/licenses/mit-license.php
|
7
|
+
*/
|
8
|
+
(function(){
|
9
|
+
var isIE = (/msie/i).test(navigator.userAgent) && !(/opera/i).test(navigator.userAgent);
|
10
|
+
|
11
|
+
var soundcloud = window.soundcloud = {
|
12
|
+
version: "0.1",
|
13
|
+
debug: false,
|
14
|
+
_listeners: [],
|
15
|
+
// re-dispatches widget events in the DOM, using JS library support, the events also should bubble up the DOM
|
16
|
+
_redispatch: function(eventType, flashId, data) {
|
17
|
+
var playerNode,
|
18
|
+
lsnrs = this._listeners[eventType] || [],
|
19
|
+
// construct the custom eventType e.g. 'soundcloud:onPlayerReady'
|
20
|
+
customEventType = 'soundcloud:' + eventType;
|
21
|
+
|
22
|
+
try{
|
23
|
+
// find the flash player, might throw an exception
|
24
|
+
playerNode = this.getPlayer(flashId);
|
25
|
+
}catch(e){
|
26
|
+
if(this.debug && window.console){
|
27
|
+
console.error('unable to dispatch widget event ' + eventType + ' for the widget id ' + flashId, data, e);
|
28
|
+
}
|
29
|
+
return;
|
30
|
+
}
|
31
|
+
// re-dispatch SoundCloud events up in the DOM
|
32
|
+
if(window.jQuery){
|
33
|
+
// if jQuery is available, trigger the custom event
|
34
|
+
jQuery(playerNode).trigger(customEventType, [data]);
|
35
|
+
}else if(window.Prototype){
|
36
|
+
// if Prototype.js is available, fire the custom event
|
37
|
+
$(playerNode).fire(customEventType, data);
|
38
|
+
}else{
|
39
|
+
// TODO add more JS libraries that support custom DOM events
|
40
|
+
}
|
41
|
+
// if there are any listeners registered to this event, trigger them all
|
42
|
+
for(var i = 0, l = lsnrs.length; i < l; i += 1) {
|
43
|
+
lsnrs[i].apply(playerNode, [playerNode, data]);
|
44
|
+
}
|
45
|
+
// log the events in debug mode
|
46
|
+
if(this.debug && window.console){
|
47
|
+
console.log(customEventType, eventType, flashId, data);
|
48
|
+
}
|
49
|
+
|
50
|
+
},
|
51
|
+
// you can add multiple listeners to a certain event
|
52
|
+
// e.g. soundcloud.addEventListener('onPlayerReady', myFunctionOne);
|
53
|
+
// soundcloud.addEventListener('onPlayerReady', myFunctionTwo);
|
54
|
+
addEventListener: function(eventType, callback) {
|
55
|
+
if(!this._listeners[eventType]){
|
56
|
+
this._listeners[eventType] = [];
|
57
|
+
}
|
58
|
+
this._listeners[eventType].push(callback);
|
59
|
+
},
|
60
|
+
// you can also remove the function listener if e.g you want to trigger it only once
|
61
|
+
// soundcloud.removeEventListener('onMediaPlay', myFunctionOne);
|
62
|
+
removeEventListener: function(eventType, callback) {
|
63
|
+
var lsnrs = this._listeners[eventType] || [];
|
64
|
+
for(var i = 0, l = lsnrs.length; i < l; i += 1) {
|
65
|
+
if(lsnrs[i] === callback){
|
66
|
+
lsnrs.splice(i, 1);
|
67
|
+
}
|
68
|
+
}
|
69
|
+
},
|
70
|
+
// get widget node based on its id (if object tag) or name (if embed tag)
|
71
|
+
// if you're using SWFObject or other dynamic Flash generators, please make sure that you set the id parameter
|
72
|
+
// only if the DOM has an id/name it's possible to call player's methods.
|
73
|
+
// Important!: because of the bug in Opera browser, the Flash can't get its own id
|
74
|
+
// so the generator should set it additionally through flashvars parameter 'object_id'
|
75
|
+
getPlayer: function(id){
|
76
|
+
var flash;
|
77
|
+
try{
|
78
|
+
if(!id){
|
79
|
+
throw "The SoundCloud Widget DOM object needs an id atribute, please refer to SoundCloud Widget API documentation.";
|
80
|
+
}
|
81
|
+
flash = isIE ? window[id] : document[id];
|
82
|
+
if(flash){
|
83
|
+
if(flash.api_getFlashId){
|
84
|
+
return flash;
|
85
|
+
}else{
|
86
|
+
throw "The SoundCloud Widget External Interface is not accessible. Check that allowscriptaccess is set to 'always' in embed code";
|
87
|
+
}
|
88
|
+
}else{
|
89
|
+
throw "The SoundCloud Widget with an id " + id + " couldn't be found";
|
90
|
+
}
|
91
|
+
}catch(e){
|
92
|
+
if (console && console.error) {
|
93
|
+
console.error(e);
|
94
|
+
}
|
95
|
+
throw e;
|
96
|
+
}
|
97
|
+
},
|
98
|
+
// fired when widget has loaded its data and is ready to accept calls from outside
|
99
|
+
// the widget will call these functions only if in it's flashvars there's a parameter enable_api=true
|
100
|
+
// @flashId: the widget id, basically the Flash node should be accessible to JS with soundcloud.getPlayer(flashId)
|
101
|
+
// @data: an object containing .mediaUri (eg. 'http://api.soundcloud.com/tracks/49931') .mediaId (e.g. '4532')
|
102
|
+
// in buffering events data contains also .percent = (e.g. '99')
|
103
|
+
onPlayerReady: function(flashId, data) {
|
104
|
+
this._redispatch('onPlayerReady', flashId, data);
|
105
|
+
},
|
106
|
+
// fired when widget starts playing current track (fired only once per track)
|
107
|
+
onMediaStart : function(flashId, data) {
|
108
|
+
this._redispatch('onMediaStart', flashId, data);
|
109
|
+
},
|
110
|
+
// fired when the track/playlist has finished playing
|
111
|
+
onMediaEnd : function(flashId, data) {
|
112
|
+
this._redispatch('onMediaEnd', flashId, data);
|
113
|
+
},
|
114
|
+
// fired when widget starts playing current track (fired on every play, seek)
|
115
|
+
onMediaPlay : function(flashId, data) {
|
116
|
+
this._redispatch('onMediaPlay', flashId, data);
|
117
|
+
},
|
118
|
+
// fired when track was paused
|
119
|
+
onMediaPause : function(flashId, data) {
|
120
|
+
this._redispatch('onMediaPause', flashId, data);
|
121
|
+
},
|
122
|
+
// fired when the widget is still buffering, means you can't seek in the track fully yet
|
123
|
+
onMediaBuffering : function(flashId, data) {
|
124
|
+
this._redispatch('onMediaBuffering', flashId, data);
|
125
|
+
},
|
126
|
+
// fired when the user seeks in the track
|
127
|
+
onMediaSeek : function(flashId, data) {
|
128
|
+
this._redispatch('onMediaSeek', flashId, data);
|
129
|
+
},
|
130
|
+
// fired when the widget is done buffering and the whole track length is seekable
|
131
|
+
onMediaDoneBuffering : function(flashId, data) {
|
132
|
+
this._redispatch('onMediaDoneBuffering', flashId, data);
|
133
|
+
},
|
134
|
+
// fired when the widget can't get the requested data from the server (the resource is removed, hidden, etc.)
|
135
|
+
onPlayerError : function(flashId, data) {
|
136
|
+
this._redispatch('onPlayerError', flashId, data);
|
137
|
+
}
|
138
|
+
};
|
139
|
+
|
140
|
+
})();
|
@@ -0,0 +1,130 @@
|
|
1
|
+
.sc-player {
|
2
|
+
font: 12px Arial, sans-serif;
|
3
|
+
color: #000;
|
4
|
+
font-size: 0.8em;
|
5
|
+
font-weight: bold;
|
6
|
+
line-height: 1.6em;
|
7
|
+
}
|
8
|
+
|
9
|
+
.sc-player a {
|
10
|
+
text-decoration: none;
|
11
|
+
color: #000;
|
12
|
+
}
|
13
|
+
|
14
|
+
/* scrubber */
|
15
|
+
|
16
|
+
.sc-scrubber {
|
17
|
+
background-color: #e5e5e5;
|
18
|
+
border-top: 2px solid #000;
|
19
|
+
border-bottom: 2px solid #000;
|
20
|
+
}
|
21
|
+
|
22
|
+
.sc-scrubber .sc-time-span {
|
23
|
+
background-color: #fff;
|
24
|
+
}
|
25
|
+
|
26
|
+
.sc-scrubber .sc-time-span img {
|
27
|
+
background-color: #59C5C7;
|
28
|
+
background: -moz-linear-gradient(top, black, #96d8d9 0px, #59C5C7 90%);
|
29
|
+
background: -webkit-gradient(linear, left top, left 90%, from(black), color-stop(0%, #59C5C7), to(#96d8d9));
|
30
|
+
}
|
31
|
+
|
32
|
+
.sc-scrubber .sc-buffer, .sc-scrubber .sc-played {
|
33
|
+
background-color: #fff;
|
34
|
+
opacity: 0.4;
|
35
|
+
}
|
36
|
+
|
37
|
+
.sc-scrubber .sc-played {
|
38
|
+
background-color: #000;
|
39
|
+
opacity: 0.4;
|
40
|
+
}
|
41
|
+
|
42
|
+
/* controls */
|
43
|
+
|
44
|
+
.sc-player .sc-controls a {
|
45
|
+
color: transparent;
|
46
|
+
background: url('sc-player-artwork/play.png');
|
47
|
+
}
|
48
|
+
|
49
|
+
.sc-player .sc-controls a:hover {
|
50
|
+
background: url('sc-player-artwork/play-hover.png');
|
51
|
+
}
|
52
|
+
|
53
|
+
.sc-player .sc-controls a.sc-pause {
|
54
|
+
background: url('sc-player-artwork/play.png');
|
55
|
+
}
|
56
|
+
|
57
|
+
.sc-player .sc-controls a.sc-pause:hover{
|
58
|
+
background: url('sc-player-artwork/play-hover.png');
|
59
|
+
}
|
60
|
+
|
61
|
+
.sc-player.playing .sc-controls a.sc-pause{
|
62
|
+
background: url('sc-player-artwork/pause.png');
|
63
|
+
}
|
64
|
+
|
65
|
+
.sc-player.playing .sc-controls a.sc-pause:hover{
|
66
|
+
background: url('sc-player-artwork/pause-hover.png');
|
67
|
+
}
|
68
|
+
|
69
|
+
.sc-scrubber .sc-time-indicators{
|
70
|
+
color: #000;
|
71
|
+
font-size: 0.8em;
|
72
|
+
}
|
73
|
+
|
74
|
+
/* Track listings*/
|
75
|
+
|
76
|
+
.sc-player ol.sc-trackslist li, .sc-player ol.sc-trackslist a {
|
77
|
+
color: transparent;
|
78
|
+
}
|
79
|
+
|
80
|
+
.sc-player ol.sc-trackslist li.active, .sc-player ol.sc-trackslist li:hover {
|
81
|
+
background-color: #59C5C7;
|
82
|
+
color: #000;
|
83
|
+
background: -moz-linear-gradient(top, black, #96d8d9 0px, #59C5C7 90%);
|
84
|
+
background: -webkit-gradient(linear, left top, left 90%, from(black), color-stop(0%, #59C5C7), to(#96d8d9));
|
85
|
+
-moz-box-shadow: 1px 1px 4px #333;
|
86
|
+
-webkit-box-shadow: 1px 1px 4px #333;
|
87
|
+
opacity: 0.8;
|
88
|
+
}
|
89
|
+
|
90
|
+
.sc-player ol.sc-trackslist li.active a, .sc-player ol.sc-trackslist li:hover a {
|
91
|
+
color: #000;
|
92
|
+
}
|
93
|
+
|
94
|
+
.sc-track-duration {
|
95
|
+
text-align: right;
|
96
|
+
float: right;
|
97
|
+
padding: 0 5px;
|
98
|
+
margin-left: 5px;
|
99
|
+
}
|
100
|
+
|
101
|
+
/* Track info*/
|
102
|
+
|
103
|
+
.sc-player .sc-info{
|
104
|
+
background: #fff;
|
105
|
+
opacity: 0.9;
|
106
|
+
}
|
107
|
+
|
108
|
+
.sc-player .sc-info-toggle{
|
109
|
+
background: #fff;
|
110
|
+
color: #003399;
|
111
|
+
-moz-border-radius: 4px;
|
112
|
+
-webkit-border-radius: 4px;
|
113
|
+
-moz-box-shadow: 1px 1px 4px #ccc;
|
114
|
+
-webkit-box-shadow: 1px 1px 4px #ccc;
|
115
|
+
padding: 4px;
|
116
|
+
}
|
117
|
+
|
118
|
+
.sc-player .sc-info-toggle:hover{
|
119
|
+
background: #003399;
|
120
|
+
color: #eee;
|
121
|
+
}
|
122
|
+
|
123
|
+
.sc-player .sc-info-close{
|
124
|
+
background: #003399;
|
125
|
+
color: #fff;
|
126
|
+
-moz-border-radius: 4px;
|
127
|
+
-webkit-border-radius: 4px;
|
128
|
+
padding: 2px 4px;
|
129
|
+
font-weight: bold;
|
130
|
+
}
|
@@ -0,0 +1,18 @@
|
|
1
|
+
body {
|
2
|
+
font-family: 'arial', helvetica, sans serif;
|
3
|
+
width: 1000px;
|
4
|
+
margin: 0 auto;
|
5
|
+
background: #fff;
|
6
|
+
color: #000;
|
7
|
+
}
|
8
|
+
|
9
|
+
h1 {
|
10
|
+
border-bottom: 5px solid #000;
|
11
|
+
padding: 20px 0;
|
12
|
+
}
|
13
|
+
|
14
|
+
.footer {
|
15
|
+
border-top: 5px solid #000;
|
16
|
+
padding: 10px 0;
|
17
|
+
text-align: right;
|
18
|
+
}
|
@@ -0,0 +1,173 @@
|
|
1
|
+
.sc-player{
|
2
|
+
width: 1000px;
|
3
|
+
height: 300px;
|
4
|
+
position: relative;
|
5
|
+
margin-bottom: 20px;
|
6
|
+
}
|
7
|
+
|
8
|
+
.sc-player ol, .sc-player li{
|
9
|
+
margin: 0;
|
10
|
+
padding: 0;
|
11
|
+
list-style-position: inside;
|
12
|
+
}
|
13
|
+
|
14
|
+
/* Artworks */
|
15
|
+
|
16
|
+
.sc-player .sc-artwork-list{
|
17
|
+
width: 100%;
|
18
|
+
height: 50%;
|
19
|
+
background-color: transparent;
|
20
|
+
list-style-type: none;
|
21
|
+
position: relative;
|
22
|
+
}
|
23
|
+
|
24
|
+
.sc-player .sc-artwork-list li{
|
25
|
+
list-style-type: none;
|
26
|
+
float: left;
|
27
|
+
width: 200px;
|
28
|
+
}
|
29
|
+
|
30
|
+
.sc-player .sc-artwork-list li.active{
|
31
|
+
list-style-type: none;
|
32
|
+
display: block;
|
33
|
+
}
|
34
|
+
|
35
|
+
.sc-player .sc-artwork-list li img, .sc-player .sc-artwork-list li div{
|
36
|
+
list-style-type: none;
|
37
|
+
width: 200px;
|
38
|
+
height: 200px;
|
39
|
+
}
|
40
|
+
|
41
|
+
/* controls */
|
42
|
+
|
43
|
+
.sc-player .sc-controls{
|
44
|
+
position: absolute;
|
45
|
+
width: 40px;
|
46
|
+
height: 40px;
|
47
|
+
top: 242px;
|
48
|
+
left: 0;
|
49
|
+
|
50
|
+
}
|
51
|
+
|
52
|
+
.sc-player .sc-controls a{
|
53
|
+
display: block;
|
54
|
+
width: 40px;
|
55
|
+
height: 40px;
|
56
|
+
}
|
57
|
+
|
58
|
+
.sc-player .sc-controls a.sc-pause{
|
59
|
+
display: none;
|
60
|
+
}
|
61
|
+
|
62
|
+
.sc-player.playing .sc-controls a.sc-play{
|
63
|
+
display: none;
|
64
|
+
}
|
65
|
+
|
66
|
+
.sc-player.playing .sc-controls a.sc-pause{
|
67
|
+
display: block;
|
68
|
+
}
|
69
|
+
|
70
|
+
/* scrubber */
|
71
|
+
|
72
|
+
.sc-scrubber {
|
73
|
+
position: absolute;
|
74
|
+
left: 50px;
|
75
|
+
top: 240px;
|
76
|
+
height: 40px;
|
77
|
+
width: 950px;
|
78
|
+
display: block;
|
79
|
+
}
|
80
|
+
|
81
|
+
.sc-scrubber .sc-time-span{
|
82
|
+
height: 30px;
|
83
|
+
margin: 5px;
|
84
|
+
position: relative;
|
85
|
+
}
|
86
|
+
|
87
|
+
.sc-scrubber .sc-time-span img {
|
88
|
+
height: 30px;
|
89
|
+
width: 940px;
|
90
|
+
}
|
91
|
+
|
92
|
+
.sc-scrubber .sc-buffer, .sc-scrubber .sc-played{
|
93
|
+
height: 30px;
|
94
|
+
position: absolute;
|
95
|
+
top: 0;
|
96
|
+
}
|
97
|
+
|
98
|
+
.sc-scrubber .sc-time-indicators{
|
99
|
+
position: absolute;
|
100
|
+
right: 0;
|
101
|
+
top: -30px;
|
102
|
+
}
|
103
|
+
|
104
|
+
/* tracks */
|
105
|
+
|
106
|
+
/* Track listings*/
|
107
|
+
|
108
|
+
.sc-player ol.sc-trackslist{
|
109
|
+
position: absolute;
|
110
|
+
float: left;
|
111
|
+
width: 100%;
|
112
|
+
top: 0;
|
113
|
+
}
|
114
|
+
|
115
|
+
.sc-player ol.sc-trackslist li{
|
116
|
+
float: left;
|
117
|
+
width: 190px;
|
118
|
+
height: 60px;
|
119
|
+
cursor: pointer;
|
120
|
+
margin: 0px;
|
121
|
+
padding: 150px 5px 5px 5px;
|
122
|
+
list-style: none;
|
123
|
+
}
|
124
|
+
|
125
|
+
/* Track info*/
|
126
|
+
|
127
|
+
.sc-player .sc-info{
|
128
|
+
position: absolute;
|
129
|
+
top: 10px;
|
130
|
+
left: -5000px;
|
131
|
+
width : 400px;
|
132
|
+
padding: 5px;
|
133
|
+
height: 200px;
|
134
|
+
z-index: 500;
|
135
|
+
margin-left: -200px;
|
136
|
+
}
|
137
|
+
|
138
|
+
.sc-player .sc-info.active{
|
139
|
+
left: 50%;
|
140
|
+
top: 12%;
|
141
|
+
}
|
142
|
+
|
143
|
+
|
144
|
+
.sc-player .sc-info-toggle{
|
145
|
+
position: absolute;
|
146
|
+
top: 10px;
|
147
|
+
left: 10px;
|
148
|
+
display: none;
|
149
|
+
}
|
150
|
+
|
151
|
+
.sc-player .sc-info-toggle.active{
|
152
|
+
left: -5000px;
|
153
|
+
}
|
154
|
+
|
155
|
+
.sc-player .sc-info-close{
|
156
|
+
position: absolute;
|
157
|
+
top: 10px;
|
158
|
+
right: 20px;
|
159
|
+
}
|
160
|
+
|
161
|
+
/* utilities */
|
162
|
+
|
163
|
+
.sc-player .hidden {
|
164
|
+
display: none;
|
165
|
+
}
|
166
|
+
|
167
|
+
.sc-player-engine-container{
|
168
|
+
width: 1px;
|
169
|
+
height: 1px;
|
170
|
+
position: fixed;
|
171
|
+
top: 2px;
|
172
|
+
left: 2px;
|
173
|
+
}
|