summaryrefslogtreecommitdiff
path: root/docs/dymaxion/soundmanagerv297a-20101010/demo/page-player
diff options
context:
space:
mode:
Diffstat (limited to 'docs/dymaxion/soundmanagerv297a-20101010/demo/page-player')
-rwxr-xr-xdocs/dymaxion/soundmanagerv297a-20101010/demo/page-player/basic.html103
-rwxr-xr-xdocs/dymaxion/soundmanagerv297a-20101010/demo/page-player/css/demo.css124
-rwxr-xr-xdocs/dymaxion/soundmanagerv297a-20101010/demo/page-player/css/optional-annotations.css168
-rwxr-xr-xdocs/dymaxion/soundmanagerv297a-20101010/demo/page-player/css/optional-themes.css206
-rwxr-xr-xdocs/dymaxion/soundmanagerv297a-20101010/demo/page-player/css/page-player.css320
-rwxr-xr-xdocs/dymaxion/soundmanagerv297a-20101010/demo/page-player/image/divot-bottom.pngbin0 -> 202 bytes
-rwxr-xr-xdocs/dymaxion/soundmanagerv297a-20101010/demo/page-player/image/divot.pngbin0 -> 233 bytes
-rwxr-xr-xdocs/dymaxion/soundmanagerv297a-20101010/demo/page-player/image/top-highlight.pngbin0 -> 165 bytes
-rwxr-xr-xdocs/dymaxion/soundmanagerv297a-20101010/demo/page-player/index.html367
-rwxr-xr-xdocs/dymaxion/soundmanagerv297a-20101010/demo/page-player/script/page-player.js936
10 files changed, 2224 insertions, 0 deletions
diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/page-player/basic.html b/docs/dymaxion/soundmanagerv297a-20101010/demo/page-player/basic.html
new file mode 100755
index 0000000..851be17
--- /dev/null
+++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/page-player/basic.html
@@ -0,0 +1,103 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
+<head>
+<title>SoundManager 2 Demo: Play MP3 links on a page, "page as playlist" style</title>
+<style type="text/css">
+
+/*
+
+ -------------------------------------------------------------
+
+ In-page demo CSS - see external CSS for actual relevant stuff.
+
+ --------------------------------------------------------------
+
+ */
+
+#soundmanager-debug {
+ /* SM2 debug container (optional, makes debug more useable) */
+ position:absolute;position:fixed;*position:absolute;bottom:10px;right:10px;width:50em;height:18em;overflow:auto;background:#fff;margin:1em;padding:1em;border:1px solid #999;font-family:"lucida console",verdana,tahoma,"sans serif";font-size:x-small;line-height:1.5em;opacity:0.9;filter:alpha(opacity=90);z-index:99;
+}
+
+body {
+ font:75% normal verdana,arial,tahoma,"sans serif";
+}
+</style>
+<link rel="stylesheet" type="text/css" href="css/page-player.css" />
+<!-- soundManager.useFlashBlock: related CSS -->
+<link rel="stylesheet" type="text/css" href="../flashblock/flashblock.css" />
+<script type="text/javascript" src="../../script/soundmanager2.js"></script>
+<script type="text/javascript" src="script/page-player.js"></script>
+<script type="text/javascript">
+
+soundManager.url = '../../swf/';
+
+// demo only..
+function setTheme(sTheme) {
+ var o = document.getElementsByTagName('ul')[0];
+ o.className = 'playlist'+(sTheme?' '+sTheme:'');
+ return false;
+}
+</script>
+</head>
+
+<body>
+
+<div>
+
+ <h1><a href="http://www.schillmania.com/projects/soundmanager2/" title="Play a page of mp3s with javascript via SoundManager 2">SoundManager 2</a> / page as a playlist, basic template (flash 8)</h1>
+
+ <div id="sm2-container">
+ <!-- SM2 flash movie goes here -->
+ </div>
+
+ <ul class="playlist">
+
+ <li><a href="../jsAMP-preview/audio/rain.mp3">Rain</a></li>
+ <li><a href="../jsAMP-preview/audio/going_outside.mp3">Going Outside</a></li>
+ <li><a href="../jsAMP-preview/audio/office_lobby.mp3">Office Lobby</a></li>
+ <li><a href="../jsAMP-preview/audio/walking.mp3">Walking</a></li>
+ <li><a href="http://freshly-ground.com/data/audio/mpc/20060812%20-%20Groove.mp3" title="Dr. John Groove">Schill - Dr. John Groove</a></li>
+ <!-- files from the web (note that ID3 and waveformData information will *not* load from remote domains without permission, due to Flash security restrictions) -->
+ <li><a href="http://www.freshly-ground.com/misc/music/carl-3-barlp.mp3">Barrlping with Carl (featureblend.com)</a></li>
+ <li><a href="http://www.freshly-ground.com/data/audio/binaural/Mak.mp3">Angry cow sound?</a></li>
+ <li><a href="http://www.freshly-ground.com/data/audio/binaural/Things that open, close and roll.mp3">Things that open, close and roll</a></li>
+ <li><a href="http://www.freshly-ground.com/data/audio/binaural/A%20Trip%20to%20the%20Basement%20Garage.mp3">A Trip To The Basement Garage</a></li>
+
+ </ul>
+
+ <div id="control-template">
+ <!-- control markup inserted dynamically after each link -->
+ <div class="controls">
+ <div class="statusbar">
+ <div class="loading"></div>
+ <div class="position"></div>
+ </div>
+ </div>
+ <div class="timing">
+ <div id="sm2_timing" class="timing-data">
+ <span class="sm2_position">%s1</span> / <span class="sm2_total">%s2</span></div>
+ </div>
+ <div class="peak">
+ <div class="peak-box"><span class="l"></span><span class="r"></span>
+ </div>
+ </div>
+ </div>
+
+ <div id="spectrum-container" class="spectrum-container">
+ <div class="spectrum-box">
+ <div class="spectrum"></div>
+ </div>
+ </div>
+
+ <p>For alternate themes, add the class to the playlist UL - eg. <a href="#" onclick="return setTheme('dark')">&lt;ul class="playlist dark"&gt;</a> or <a href="#" onclick="return setTheme('bubblegum')">&lt;ul class="playlist bubblegum"&gt;</a>; the base default is <a href="#" onclick="return setTheme()">&lt;ul class="playlist"&gt;</a>.</p>
+
+ <p>A reminder that if loading from the local filesystem, Flash will deny access to remote (network/internet) URLs by default unless whitelisted via the <a href="http://www.macromedia.com/support/documentation/en/flashplayer/help/settings_manager04.html">Flash Player Global Security Settings Page</a>. Some URLs in this example are remote to demonstrate this.</p>
+
+ <p>Note that by default, the Flash 8 version is used and therefore Flash 9-only features such as the VU meter, waveform etc. are not available. Refer to the main "page player" demo for configuration examples, or view the source of page-player.js for the configuration object (similar to that used in SoundManager 2 itself.)</p>
+
+ <p><a href="http://www.schillmania.com/projects/soundmanager2/" title="Javascript MP3 sound player API">SoundManager 2 project</a></p>
+
+</body>
+</html>
diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/page-player/css/demo.css b/docs/dymaxion/soundmanagerv297a-20101010/demo/page-player/css/demo.css
new file mode 100755
index 0000000..f11964e
--- /dev/null
+++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/page-player/css/demo.css
@@ -0,0 +1,124 @@
+/*
+ -----------------------------------------------------------------
+ In-page demo CSS for code, documentation etc.
+ See page-player.css for actual playlist-relevant stuff.
+ -----------------------------------------------------------------
+ */
+
+#soundmanager-debug {
+ /* SM2 debug container (optional, makes debug more useable) */
+ position:absolute;position:fixed;*position:absolute;bottom:10px;right:10px;width:50em;height:18em;overflow:auto;background:#fff;margin:1em;padding:1em;border:1px solid #999;font-family:"lucida console",verdana,tahoma,"sans serif";font-size:x-small;line-height:1.5em;opacity:0.9;filter:alpha(opacity=90);z-index:99;
+}
+
+body {
+ font:75% normal verdana,arial,tahoma,"sans serif";
+}
+
+h1, h2, h3 {
+ font:lighter 3em "Helvetica Neue Light","Helvetica Neue",georgia,"times new roman","Arial Rounded MT Bold",helvetica,verdana,tahoma,arial,"sans serif";
+ margin-bottom:0px;
+}
+
+h1, h2 {
+ letter-spacing:-1px; /* zomg web x.0! ;) */
+}
+
+h1, h2, h3 {
+ float:left;
+ clear:both;
+ border-bottom:1px solid #999;
+ padding-bottom:1px;
+ margin-bottom:0.25em;
+}
+
+h1 {
+ margin-top:0px;
+ margin-bottom:0px;
+ background-color:#666;
+ color:#ccc;
+ margin-left:-5px;
+ padding-left:5px;
+ padding-right:5px;
+}
+
+h1,
+h1 a {
+ color:#fff;
+ text-decoration:none;
+}
+
+h1 a:hover {
+ text-decoration:underline;
+}
+
+h2 {
+ font-size:2em;
+ margin-top:1em;
+ background-color:#aaa;
+ color:#fff;
+ padding:5px;
+ margin-left:-5px;
+ min-width:23em;
+}
+
+h3 {
+ font-size:1.65em;
+ margin-top:0.5em;
+ margin-bottom:0.25em;
+ color:#333;
+ min-width:28em;
+}
+
+h3 a {
+ font-size:small;
+}
+
+h4 {
+ color:#444;
+}
+
+ul.notes {
+ margin-left:0px;
+ padding-left:1.5em;
+}
+
+.note {
+ margin-top:0px;
+ font-style:italic;
+ color:#999;
+}
+
+pre {
+ font-size:1.2em;
+ _font-size:1em;
+}
+
+code {
+ font-family:"lucida console",monaco,courier,terminal,system;
+ font-size:1em;
+ color:#003366;
+}
+
+code span {
+ color:#666;
+}
+
+ul,
+p,
+pre {
+ clear:left;
+ max-width:46em;
+}
+
+ul.tight li {
+ max-width:44.5em;
+}
+
+ul.playlist {
+ /* undo the above nonsense */
+ max-width:none;
+}
+
+ul.tight {
+ padding-left:1.5em;
+}
diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/page-player/css/optional-annotations.css b/docs/dymaxion/soundmanagerv297a-20101010/demo/page-player/css/optional-annotations.css
new file mode 100755
index 0000000..123457f
--- /dev/null
+++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/page-player/css/optional-annotations.css
@@ -0,0 +1,168 @@
+/*
+ ------------------------------------------
+ -- annotations (sub-tracks, notes etc.) --
+ ------------------------------------------
+*/
+
+ul.playlist li a.sm2_link .metadata {
+ display:none; /* hide by default */
+}
+
+ul.playlist li.sm2_paused a.sm2_link .metadata,
+ul.playlist li.sm2_playing a.sm2_link .metadata {
+ display:inline;
+}
+
+ul.playlist li ul {
+ list-style-type:none;
+ margin:0px;
+ padding:0px;
+ position:relative;
+ font-size:small;
+ display:none;
+}
+
+ul.playlist li ul li {
+ position:relative;
+ margin:0px;
+ padding:2px 3px;
+ border:1px solid transparent;
+ -moz-border-radius:6px;
+ -khtml-border-radius:6px;
+ border-radius:6px;
+ margin-right:1em;
+ font-family:helvetica,verdana,tahoma,arial,"sans serif";
+ font-size:x-small;
+ font-weight:lighter;
+ letter-spacing:0px;
+ background-color:transparent;
+ opacity:0.66;
+}
+
+ul.playlist li ul li:hover {
+ opacity:1;
+ background-color:#fff;
+ border-color:#ccc;
+ color:#666;
+}
+
+ul.playlist li.sm2_playing ul li,
+ul.playlist li.sm2_paused ul li {
+ color:#fff;
+}
+
+ul.playlist li.sm2_playing ul li:hover {
+ background-color:#fff;
+ color:#5588bb;
+ border-color:#336699;
+ opacity:0.9;
+}
+
+ul.playlist li.sm2_paused ul li:hover {
+ background-color:#888;
+}
+
+/* metadata */
+
+ul.playlist li .metadata .duration {
+ /* optional timing data */
+ display:none;
+}
+
+ul.playlist li .metadata ul li p {
+ margin:0px;
+ padding:0px;
+}
+
+ul.playlist li .metadata ul li span {
+ display:none;
+}
+
+ul.playlist li .controls .statusbar .annotation {
+ position:absolute;
+ background-color:transparent;
+ top:0px;
+ color:#666;
+ text-align:right;
+ margin-left:10px;
+ height:0.5em;
+}
+
+ul.playlist li .controls .statusbar .annotation:hover {
+ z-index:12; /* sit on top of note */
+}
+
+ul.playlist li .controls .statusbar .annotation span.bubble {
+ /* using &middot; */
+ display:inline-block;
+ background-color:#fff;
+ border:1px solid #666;
+ border-radius:6px;
+ -moz-border-radius:6px;
+ -webkit-border-radius:6px;
+}
+
+ul.playlist li .controls .statusbar .annotation span {
+ display:block;
+ background:transparent url(../image/divot.png) no-repeat 50% 0px;
+ width:15px;
+ margin-left:-15px;
+ height:12px;
+ text-align:center;
+}
+
+ul.playlist li .controls .statusbar .annotation.alt {
+ top:auto;
+ bottom:0px;
+}
+
+ul.playlist li .controls .statusbar .annotation span:hover {
+ cursor:none; /* Fx3 rules. */
+ margin-top:0.1em;
+}
+
+ul.playlist li .controls .statusbar .annotation.alt span:hover {
+ margin-top:-0.1em;
+}
+
+ul.playlist li .controls .statusbar .annotation.alt span {
+ background:transparent url(../image/divot-bottom.png) no-repeat 50% bottom;
+}
+
+ul.playlist li .note {
+ position:absolute;
+ display:none;
+ left:0px;
+ top:0px;
+ z-index:10;
+ font-size:x-small;
+ padding:2px 4px 2px 4px;
+ width:auto;
+ color:#666;
+ background-color:#fff;
+ border:1px solid #ccc;
+ border-radius:6px;
+ -moz-border-radius:6px;
+ -webkit-border-radius:6px;
+ font-style:normal;
+ font-weight:bold;
+ font-family:arial,tahoma,verdana,"sans serif";
+ letter-spacing:0px;
+ margin-top:1.1em;
+}
+
+ul.playlist li .note.alt {
+ margin-top:-1.32em;
+}
+
+ul.playlist li .note:hover {
+ display:block !important;
+}
+
+ul.playlist li .sm2_divider {
+ font-size:0.75em;
+}
+
+ul.playlist li .sm2_metadata {
+ font-size:0.65em;
+}
diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/page-player/css/optional-themes.css b/docs/dymaxion/soundmanagerv297a-20101010/demo/page-player/css/optional-themes.css
new file mode 100755
index 0000000..62a8146
--- /dev/null
+++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/page-player/css/optional-themes.css
@@ -0,0 +1,206 @@
+/*
+ ---------------------------------
+ -- alternate (optional) themes --
+ ---------------------------------
+*/
+
+ul.playlist.dark li.sm2_playing a {
+ color:#fff;
+}
+
+ul.playlist.dark li.sm2_playing .timing,
+ul.playlist.use-peak.dark li.sm2_playing .peak {
+ color:#999;
+}
+
+ul.playlist.use-spectrum.dark li.sm2_playing .spectrum-container {
+ background-color:#222;
+ border-color:#444;
+}
+
+ul.playlist.use-spectrum.dark li.sm2_playing .spectrum-container .spectrum {
+ background-color:#999;
+}
+
+ul.playlist.dark li.sm2_paused {
+ background-color:#333;
+}
+
+ul.playlist.dark li.sm2_paused a {
+ color:#999;
+}
+
+ul.playlist.dark li.sm2_playing,
+ul.playlist.dark li.sm2_playing:hover {
+ background-color:#333;
+}
+
+ul.playlist.dark li:hover .controls .statusbar {
+ background-color:#666;
+}
+
+ul.playlist.dark li .controls {
+ background-color:#333;
+}
+
+ul.playlist.dark li .controls .statusbar {
+ background-color:#666;
+ border-color:#444;
+}
+
+ul.playlist.dark li .controls .statusbar .position {
+ background-color:#111;
+ border-right:3px solid #111;
+ border-radius:3px;
+ -moz-border-radius:3px;
+ -webkit-border-radius:3px;
+}
+
+ul.playlist.dark li .controls .statusbar .loading {
+ background-color:#444;
+}
+
+ul.playlist.dark li .timing,
+ul.playlist.use-peak.dark li .peak {
+ background-color:#222;
+ border-color:#444;
+}
+
+ul.playlist.dark.use-peak li .peak .l,
+ul.playlist.dark.use-peak li .peak .r {
+ border-color:#444;
+ background-color:#999;
+}
+
+
+/* gold theme */
+
+ul.playlist.gold li.sm2_paused {
+ background-color:#996600;
+}
+
+ul.playlist.gold li.sm2_playing,
+ul.playlist.gold li.sm2_playing:hover {
+ background-color:#cc9900;
+}
+
+ul.playlist.gold li .controls {
+ background-color:transparent;
+}
+
+ul.playlist.gold li .controls .statusbar {
+ background-color:#fff;
+ border-color:#fff;
+}
+
+ul.playlist.gold li .controls .statusbar .position {
+ background-color:#996600;
+ border-right:3px solid #996600;
+ border-radius:3px;
+ -moz-border-radius:3px;
+ -webkit-border-radius:3px;
+}
+
+ul.playlist.gold li .controls .statusbar .loading {
+ background-color:#ffeedd;
+}
+
+ul.playlist.gold li .timing,
+ul.playlist.use-peak.gold li .peak {
+ background-color:#CC9900;
+ border-color:#ffcc33;
+}
+
+ul.playlist.use-spectrum.gold li.sm2_playing .spectrum-container {
+ background-color:#cc9900;
+ border-color:#ffcc33;
+}
+
+ul.playlist.use-spectrum.gold li.sm2_playing .spectrum-container .spectrum {
+ background-color:#fff;
+}
+
+ul.playlist.gold.use-peak li .peak .l,
+ul.playlist.gold.use-peak li .peak .r {
+ border-color:#fff;
+ background-color:#fff;
+}
+
+
+/* ZOMG PONIES!!!ONEONEONE */
+
+ul.playlist.bubblegum li a {
+ font-family:"comic sans ms",verdana,arial,tahoma,"sans serif"; /* heh */
+}
+
+ul.playlist.bubblegum li.sm2_paused,
+ul.playlist.bubblegum li.sm2_paused:hover {
+ background-color:#ffccee;
+}
+
+ul.playlist.bubblegum li.sm2_paused a,
+ul.playlist.bubblegum li.sm2_paused:hover a,
+ul.playlist.bubblegum li.sm2_paused .timing,
+ul.playlist.use-peak.bubblegum li.sm2_paused .peak {
+ color:#ff6699;
+}
+
+ul.playlist.bubblegum li:hover {
+ background-color:#ffddee;
+}
+
+ul.playlist.bubblegum li.sm2_playing,
+ul.playlist.bubblegum li.sm2_playing:hover {
+ background-color:#ff7799;
+}
+
+ul.playlist.bubblegum li .controls {
+ background-color:transparent;
+}
+
+ul.playlist.bubblegum li .controls .statusbar {
+ background-color:#fff;
+ border-color:#fff;
+}
+
+ul.playlist.bubblegum li .controls .statusbar .position {
+ background-color:#ffaacc;
+ border-right:3px solid #ffaacc;
+ border-radius:3px;
+ -moz-border-radius:3px;
+ -webkit-border-radius:3px;
+}
+
+ul.playlist.bubblegum li .controls .statusbar .loading {
+ background-color:#ffeedd;
+}
+
+ul.playlist.bubblegum li .timing,
+ul.playlist.use-peak.bubblegum li .peak {
+ background-color:#ffaacc;
+ border-color:#ffccee;
+}
+
+ul.playlist.use-spectrum.bubblegum li.sm2_playing .spectrum-container {
+ background-color:#ffaacc;
+ border-color:#ffccee;
+}
+
+ul.playlist.use-spectrum.bubblegum li.sm2_playing .spectrum-container .spectrum {
+ background-color:#fff;
+}
+
+ul.playlist.bubblegum.use-peak li .peak .l,
+ul.playlist.bubblegum.use-peak li .peak .r {
+ border-color:#fff;
+ background-color:#fff;
+}
+
+
+ul.playlist.shiny li.sm2_paused,
+ul.playlist.shiny li.sm2_playing {
+ background-image:url(../image/top-highlight.png);
+ background-repeat:repeat-x;
+ background-position:0px -1px;
+ _background-image:none; /* can't be bothered with IE 6. */
+} \ No newline at end of file
diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/page-player/css/page-player.css b/docs/dymaxion/soundmanagerv297a-20101010/demo/page-player/css/page-player.css
new file mode 100755
index 0000000..2c0ca3b
--- /dev/null
+++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/page-player/css/page-player.css
@@ -0,0 +1,320 @@
+/*
+
+ SoundManager 2: "page as playlist" example
+ ------------------------------------------
+ http://schillmania.com/projects/soundmanager2/
+
+*/
+
+.spectrum-container {
+ display:none;
+}
+
+ul.use-spectrum li.sm2_playing .spectrum-container {
+ position:absolute;
+ left:0px;
+ top:0px;
+ margin-left:-266px;
+ margin-top:-1px;
+ display:block;
+ background-color:#5588bb;
+ border:1px solid #99ccff;
+ -moz-border-radius:4px;
+ -webkit-border-radius:4px;
+ border-radius:4px;
+}
+
+ul.use-spectrum .spectrum-box {
+ position:relative;
+ width:255px;
+ font-size:1em;
+ padding:2px 0px;
+ height:1.2em;
+ overflow:hidden;
+}
+
+ul.use-spectrum .spectrum-box .spectrum {
+ position:absolute;
+ left:0px;
+ top:-2px;
+ margin-top:20px;
+ display:block;
+ font-size:1px;
+ width:1px;
+ height:1px; /* set to 50px for a thick line, 1px for a thin line, etc. */
+ overflow:hidden;
+ background-color:#fff;
+}
+
+ul.playlist {
+ list-style-type:none;
+ margin:0px;
+ padding:0px;
+
+}
+
+ul.playlist li {
+ /* assume all items will be sounds rather than wait for onload etc. in this example.. may differ for your uses. */
+ position:relative;
+ display:block;
+ width:auto;
+ font-size:2em;
+ color:#666;
+ padding:0.25em 0.5em 0.25em 0.5em;
+ border:none;
+ letter-spacing:-1px; /* ZOMG WEB X.0. ;) */
+ background-color:#f9f9f9;
+ -webkit-transition-property: hover;
+ -webkit-transition: background-color 0.15s ease-in-out;
+ -moz-transition: background-color 0.15s linear 0s; /* firefox 4 */
+ -o-transition-property: background-color; /* opera 10.5 */
+ -o-transition-duration: 0.15s;
+
+}
+
+ul.playlist li a {
+ display:block;
+ text-decoration:none;
+ font-weight:normal;
+ color:#000;
+ font-size:120%;
+ outline:none;
+ position:relative;
+ z-index:2;
+}
+
+ul.playlist li.sm2_playing,
+ul.playlist li.sm2_paused,
+ul.playlist li.sm2_playing a {
+ color:#fff;
+ border-radius:3px;
+ -webkit-border-radius:3px;
+ -moz-border-radius:3px;
+}
+
+ul.playlist li:hover {
+ background-color:#eee;
+}
+
+ul.playlist li:hover a {
+ color:#333;
+}
+
+ul.playlist li.sm2_playing,
+ul.playlist li.sm2_playing:hover {
+ background-color:#6699cc;
+}
+
+ul.playlist li.sm2_paused {
+ background-color:#999;
+}
+
+ul.playlist li.sm2_playing:hover a,
+ul.playlist li.sm2_paused a {
+ color:#fff;
+}
+
+ul.playlist li .controls {
+ display:none;
+}
+
+ul.playlist li .peak,
+ul.playlist.use-peak li .peak {
+ display:none;
+ position:absolute;
+ top:0.55em;
+ right:0.5em;
+}
+
+ul.playlist li.sm2_playing .controls,
+ul.playlist li.sm2_paused .controls {
+ position:relative;
+ display:block;
+}
+
+ul.playlist.use-peak li.sm2_playing .peak,
+ul.playlist.use-peak li.sm2_paused .peak {
+ display:inline;
+ display:inline-block;
+}
+
+ul.playlist.use-peak li .peak {
+ display:none; /* IE 7 */
+}
+
+ul.playlist li.sm2_paused .controls {
+ background-color:#666;
+}
+
+ul.playlist li:hover .controls .statusbar {
+ position:relative;
+ cursor:ew-resize;
+ cursor:-moz-grab;
+ cursor:grab;
+}
+
+ul.playlist li.sm2_paused .controls .statusbar {
+ background-color:#ccc;
+}
+
+ul.playlist li .controls {
+ position:relative;
+ margin-top:0.25em;
+ margin-bottom:0.25em;
+ background-color:#99ccff;
+}
+
+ul.playlist li .controls .statusbar {
+ position:relative;
+ height:0.5em;
+ background-color:#ccddff;
+ border:2px solid #fff;
+ border-radius:2px;
+ -moz-border-radius:2px;
+ -webkit-border-radius:2px;
+ overflow:hidden;
+ cursor:-moz-grab;
+ cursor:grab;
+}
+
+ul.playlist li .controls.dragging .statusbar {
+ cursor:-moz-grabbing;
+ cursor:grabbing;
+}
+
+ul.playlist li .controls .statusbar .position,
+ul.playlist li .controls .statusbar .loading,
+ul.playlist li .controls .statusbar .annotation {
+ position:absolute;
+ left:0px;
+ top:0px;
+ height:0.5em;
+}
+
+ul.playlist li .controls .statusbar .position {
+ background-color:#336699;
+ border-right:3px solid #336699;
+ border-radius:3px;
+ -moz-border-radius:3px;
+ -webkit-border-radius:3px;
+}
+
+ul.playlist li.sm2_paused .controls .statusbar .position {
+ background-color:#666;
+ border-color:#666;
+}
+
+ul.playlist li .controls .statusbar .loading {
+ background-color:#eee;
+}
+
+ul.playlist li .controls .statusbar .position,
+ul.playlist li .controls .statusbar .loading {
+ width:0px;
+}
+
+ul.playlist li.sm2_playing a.sm2_link,
+ul.playlist li.sm2_paused a.sm2_link {
+ margin-right:4.5em; /* room for timing stuff */
+}
+
+ul.playlist li .timing {
+ position:absolute;
+ display:none;
+ text-align:right;
+ right:1em;
+ top:1em;
+ width:auto;
+ height:1em;
+ padding:3px 5px;
+ background-color:#5588bb;
+ border:1px solid #99ccff;
+ -moz-border-radius:4px;
+ -khtml-border-radius:4px;
+ border-radius:4px;
+ letter-spacing:0px;
+ font:44% monaco,"VT-100",terminal,"lucida console",courier,system;
+ line-height:1em;
+ vertical-align:middle;
+}
+
+ul.playlist.use-peak li .timing {
+ right:4.25em;
+}
+
+ul.playlist li:hover .timing {
+ z-index:2;
+}
+
+ul.playlist li .timing div.sm2_timing {
+ margin:0px;
+ padding:0px;
+ margin-top:-1em;
+}
+
+ul.playlist li.sm2_playing .timing,
+ul.playlist li.sm2_paused .timing {
+ display:block;
+}
+
+ul.playlist li.sm2_paused .timing .sm2_position {
+ text-decoration:blink; /* hee hee. first actual appropriate use? :D */
+}
+
+ul.playlist li.sm2_paused .timing,
+ul.playlist.use-peak li.sm2_paused .peak {
+ background-color:#888;
+ border-color:#ccc;
+}
+
+/* peak data */
+
+/* ul.playlist ... */
+
+ul.playlist.use-peak li .peak {
+ display:none;
+ zoom:1;
+ border:1px solid #99ccff;
+ padding:2px;
+ height:0.55em;
+ -moz-border-radius:4px;
+ -khtml-border-radius:4px;
+ border-radius:4px;
+ background-color:#5588bb;
+ width:0.8em;
+ height:0.55em;
+ margin-top:-3px;
+}
+
+ul.playlist.use-peak li .peak-box {
+ position:relative;
+ width:100%;
+ height:0.55em;
+ overflow:hidden;
+}
+
+ul.playlist li .peak .l,
+ul.playlist li .peak .r {
+ position:absolute;
+ left:0px;
+ top:0px;
+ width:7px;
+ height:50px;
+ background:#fff;
+ border:1px solid #fff;
+ -moz-border-radius:1px;
+ -khtml-border-radius:1px;
+ margin-top:1em;
+}
+
+ul.playlist li .peak .l {
+ margin-right:1px;
+}
+
+ul.playlist li .peak .r {
+ left:10px;
+}
+
+#control-template {
+ display:none;
+} \ No newline at end of file
diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/page-player/image/divot-bottom.png b/docs/dymaxion/soundmanagerv297a-20101010/demo/page-player/image/divot-bottom.png
new file mode 100755
index 0000000..05b1dff
--- /dev/null
+++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/page-player/image/divot-bottom.png
Binary files differ
diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/page-player/image/divot.png b/docs/dymaxion/soundmanagerv297a-20101010/demo/page-player/image/divot.png
new file mode 100755
index 0000000..fbcf930
--- /dev/null
+++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/page-player/image/divot.png
Binary files differ
diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/page-player/image/top-highlight.png b/docs/dymaxion/soundmanagerv297a-20101010/demo/page-player/image/top-highlight.png
new file mode 100755
index 0000000..f88668d
--- /dev/null
+++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/page-player/image/top-highlight.png
Binary files differ
diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/page-player/index.html b/docs/dymaxion/soundmanagerv297a-20101010/demo/page-player/index.html
new file mode 100755
index 0000000..ee5bf79
--- /dev/null
+++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/page-player/index.html
@@ -0,0 +1,367 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
+<head>
+<title>SoundManager 2 Demo: Play MP3 links on a page, "page as playlist" style</title>
+<meta name="robots" content="noindex" />
+
+<!-- for this page only, make things pretty -->
+<link rel="stylesheet" type="text/css" href="css/demo.css" />
+
+<!-- player core CSS -->
+<link rel="stylesheet" type="text/css" href="css/page-player.css" />
+
+<!-- soundManager.useFlashBlock: related CSS -->
+<link rel="stylesheet" type="text/css" href="../flashblock/flashblock.css" />
+
+<!-- optional: annotations/sub-tracks/notes, and alternate themes -->
+<link rel="stylesheet" type="text/css" href="css/optional-annotations.css" />
+<link rel="stylesheet" type="text/css" href="css/optional-themes.css" />
+
+<style type="text/css">
+ul.playlist li .comment {font-size:0.65em;opacity:0.5}
+</style>
+<script type="text/javascript" src="../../script/soundmanager2.js"></script>
+<script type="text/javascript">
+
+/* --------
+
+ Config override: This demo uses shiny flash 9 stuff, overwriting Flash 8-based defaults
+ Alternate PP_CONFIG object must be defined before page-player JS is included/executed.
+ Alternately, edit the config in page-player.js to simply use the values below by default
+
+-------- */
+
+// demo only..
+soundManager.useHighPerformance = true; // keep flash on screen, boost performance
+soundManager.wmode = 'transparent'; // transparent SWF, if possible
+soundManager.useFastPolling = true; // increased JS callback frequency
+soundManager.url = '../../swf/';
+
+var PP_CONFIG = {
+ flashVersion: 9, // version of Flash to tell SoundManager to use - either 8 or 9. Flash 9 required for peak / spectrum data.
+ usePeakData: true, // [Flash 9 only] whether or not to show peak data (left/right channel values) - nor noticable on CPU
+ useWaveformData: true, // [Flash 9 only] show raw waveform data - WARNING: LIKELY VERY CPU-HEAVY
+ useEQData: false, // [Flash 9 only] show EQ (frequency spectrum) data
+ useFavIcon: false, // try to apply peakData to address bar (Firefox + Opera) - performance note: appears to make Firefox 3 do some temporary, heavy disk access/swapping/garbage collection at first(?) - may be too heavy on CPU
+ useMovieStar: true // Flash 9.0r115+ only: Support for a subset of MPEG4 formats.
+}
+
+</script>
+<script type="text/javascript" src="script/page-player.js"></script>
+<script type="text/javascript">
+var is_shiny = false;
+function setTheme(sTheme) {
+ var o = pagePlayer.getElementsByClassName('playlist','ul');
+ for (var i=o.length; i--;) {
+ o[i].className = 'playlist'+(pagePlayer.cssBase?' '+pagePlayer.cssBase:'')+(sTheme?' '+sTheme:'')+(is_shiny?' shiny':'');
+ }
+ return false;
+}
+function setShiny(bShiny) {
+ is_shiny = bShiny;
+ var o = pagePlayer.getElementsByClassName('playlist','ul');
+ var sClass = 'shiny';
+ for (var i=o.length; i--;) {
+ if (!bShiny) {
+ pagePlayer.removeClass(o[i],sClass);
+ } else {
+ pagePlayer.addClass(o[i],sClass);
+ }
+ }
+}
+</script>
+</head>
+
+<body>
+
+<div id="left">
+
+ <h1><a href="http://www.schillmania.com/projects/soundmanager2/" title="Play a page of mp3s with javascript via SoundManager 2">SoundManager 2</a> / "Page as a playlist"</h1>
+
+ <h2 style="margin-top:0px;border:none">Muxtape.com-style UI, MP3/AAC Player Example</h2>
+ <p class="note">*CSS 3 border-radius supported by Firefox 2.x+, Safari (2.x?) and IE 9.</p>
+
+ <p style="margin-top:1.5em;color:#333">This page uses shiny features which require Flash 9. The <a href="basic.html" title="Basic page player demo">default config</a> uses Flash 8.</p>
+
+ <div id="sm2-container">
+ <!-- SM2 flash goes here -->
+ </div>
+
+ <ul class="playlist">
+ <li><a href="../mpc/audio/CRASH_1.mp3">Crash cymbal</a></li>
+ <li><a href="../_mp3/bass.mp3">Bass</a></li>
+ <li><a href="../_mp3/sine,%20square,%20sawtooth,%20rando.mp3">440 Hz sine, square, sawtooth, pink noise, random</a></li>
+ <li><a href="../_mp3/1hz-10khz-sweep.mp3">1Hz - 10KHz sweep</a></li>
+ <!-- files from the web (note that ID3 and waveformData information will *not* load from remote domains without permission, due to Flash security restrictions) -->
+ <li><a href="http://freshly-ground.com/misc/music/20060826%20-%20Armstrong.mp3">20060826 - Armstrong</a></li>
+ <li><a href="http://freshly-ground.com/misc/music/carl-3-barlp.mp3">Barrlping with Carl <span class="comment">(featureblend.com)</span></a></li>
+ <li><a href="http://freshly-ground.com/data/audio/binaural/Mak.mp3" class="exclude">Angry cow sound with "exclude" CSS class <span class="comment">(Browser follows link normally)</span></a></li>
+ </ul>
+
+ <h2>MPEG4 / H.264 + HE-AAC (Flash "MovieStar" 9.0r115+) format support - audio-only example</h2>
+ <h3>A subset of MPEG4 <a href="http://www.adobe.com/support/documentation/en/flashplayer/9/releasenotes.html#fixes_90115">is supported</a> including AAC, FLV, MP4, M4A, MOV, MP4V, 3GP and 3G2 files.</h3>
+
+ <ul class="playlist">
+ <li><a href="http://freshly-ground.com/data/video/Rain%20on%20Car%20Roof.aac">Rain on Car Roof <span class="comment">(MPEG4 .AAC audio, 128 kbps AAC-LC exported from QuickTime)</span></a></li>
+ <li><a href="http://freshly-ground.com/data/video/Jellyfish.mov">Jellyfish <span class="comment">(848x480 H.264 video, playing audio portion only)</span></a></li>
+ </ul>
+
+ <div id="control-template">
+ <!-- control markup inserted dynamically after each link -->
+ <div class="controls">
+ <div class="statusbar">
+ <div class="loading"></div>
+ <div class="position"></div>
+ </div>
+ </div>
+ <div class="timing">
+ <div id="sm2_timing" class="timing-data">
+ <span class="sm2_position">%s1</span> / <span class="sm2_total">%s2</span>
+ </div>
+ </div>
+ <div class="peak">
+ <div class="peak-box"><span class="l"></span><span class="r"></span></div>
+ </div>
+ </div>
+
+ <div id="spectrum-container" class="spectrum-container">
+ <div class="spectrum-box">
+ <div class="spectrum"></div>
+ </div>
+ </div>
+
+ <h3 style="margin-top:1em">Basics</h3>
+
+ <p class="note">Don't want a Flash 9 requirement, EQ/waveform, perhaps less CPU? See Flash 8-based <a href="basic.html" title="Page as playlist demo">basic demo</a>.</p>
+
+ <p>Clicking a title will start loading + playing, or pause, a sound.</p>
+ <p>Once loading, click (or click and drag) on the loading/position bar to seek within the sound.</p>
+ <p>The document title reflects the currently-playing sound, and by default the list will play sequentially if left alone. (This is configurable.)</p>
+
+ <h3>Themes</h3>
+ <p>Just for fun, a few color schemes (visible when playing/paused):</p>
+ <ul class="themes">
+ <li><a href="#" onclick="return setTheme('dark')">&lt;ul class="playlist dark"&gt;</a> - #333 and #666, mostly</li>
+ <li><a href="#" onclick="return setTheme('gold')">&lt;ul class="playlist gold"&gt;</a> - Frontin' the bling</li>
+ <li><a href="#" onclick="return setTheme('bubblegum')">&lt;ul class="playlist bubblegum"&gt;</a> - ZOMG PONIES!!!ONEONEONE</li>
+ <li><a href="#" onclick="return setTheme('')">&lt;ul class="playlist"&gt;</a> (default)</li>
+ </ul>
+
+ <form style="margin:0px;padding:0px" action="#" onsubmit="return false">
+ <div>
+ <input id="makeShiny" name="makeShiny" type="checkbox" onchange="setShiny(this.checked)" value="Shiny" /> <label for="makeShiny">Also add "shiny", eg. &lt;ul class="shiny playlist"&gt;...</label>
+ </div>
+ </form>
+ <script type="text/javascript">document.getElementById('makeShiny').checked=false;</script>
+
+ <h2 id="metadata">Experimental (Alpha) Variant: MP3 "Metadata": Annotations / notes / sub-tracks</h2>
+ <p>A potential approach to noting interesting moments in sounds, scene changes, new tracks in seamless DJ mixes etc. Keep in mind this is a single MP3 being loaded, but annotations are placed along the timeline as shown.</p>
+ <p>A "metadata" element contains a nested list of data (UL/LI combination) - in this case, a summary of each scene - and the time at which this item occurs/begins. In order to help with positioning, the total length of the sound is also specified up-front. View the source code of this page for the details.</p>
+
+ <ul class="playlist">
+
+ <li>
+ <a href="http://freshly-ground.com/data/audio/binaural/A%20Virtual%20Haircut%20in%20San%20Francisco%20%283%20Scenes%29.mp3">A Virtual Haircut (3 scenes)</a>
+ <div class="metadata">
+ <div class="duration">4:43</div> <!-- total track time (for positioning while loading, until determined -->
+ <ul>
+ <li><p>Electric razor</p><span>0:00</span></li> <!-- first scene -->
+ <li><p>Water, scissors</p><span>2:41</span></li> <!-- start time of second scene -->
+ <li><p>More razor work</p><span>4:00</span></li>
+ </ul>
+ </div>
+ </li>
+
+ <li>
+ <a href="http://freshly-ground.com/data/audio/binaural/Rubber%20Chicken%20Launch%20%28office%29.mp3">Rubber Chicken Launch (Office)</a>
+ <div class="metadata">
+ <div class="duration">0:47</div>
+ <ul>
+ <li><p>First attempt</p><span>0:00</span></li>
+ <li><p>Fire!</p><span>0:02</span></li>
+ <li><p>"Too much angle"</p><span>0:05</span></li>
+ <li><p>Random chicken noise</p><span>0:18</span></li>
+ <li><p>"Wait a second"</p><span>0:31</span></li>
+ <li><p>Derrr..</p><span>0:34</span></li>
+ <li><p>Launch attempt #2</p><span>0:36</span></li>
+ <li><p>"Wrong angle"</p><span>0:39</span></li>
+ <li><p>"Fail"</p><span>0:42</span></li>
+ </ul>
+ </div>
+ </li>
+
+ </ul>
+
+ <h2>How It Works</h2>
+
+ <p>This example uses <a href="http://www.schillmania.com/projects/soundmanager2/" title="SoundManager 2 Javascript Sound API">SoundManager 2</a> to find links to MP3 files within an unordered list, and makes them playable "in-place" on a page. The script assigns CSS classes to links' parent LI nodes to indicate their state (playing/paused, etc.)</p>
+
+ <h3>Progressive Enhancement</h3>
+
+ <p>This provides a nice HTML base for all browsers and user agents, and enhances progressively for those with Javascript and Flash. Links pointing to MP3s are assigned an onclick handler which intercepts the click (preventing the browser from following the link and unloading the page. SM2 will then create sound objects as needed to play the MP3s. In the event there is an error at runtime or a lack of support (no JS/Flash etc.), the browser will simply load the MP3s directly as it normally would. This includes iPhones, etc.</p>
+
+ <h3>HTML Fragments (UI Element Templates)</h3>
+ <p>Each item in the playlist has its own set of controls and progress indicators, etc. This content is defined once as a hidden template of HTML in-page separate from the playlist markup and is cloned for each item as needed. This can be easily styled with CSS as well, of course.</p>
+
+<h2>I'd like to use this.</h2>
+<p>See this <a href="basic.html" title="Page as playlist demo">basic demo</a> for reference.</p>
+<p>The basic demo uses the default Flash 8 configuration, but you can easily change this to use Flash 9 features. The only difference in code is the configuration.</p>
+
+<p>A reminder that if loading from the local filesystem, Flash will deny access to remote (network/internet) URLs by default unless whitelisted via the <a href="http://www.macromedia.com/support/documentation/en/flashplayer/help/settings_manager04.html">Flash Player Global Security Settings Page</a>. Some URLs in this example are remote to demonstrate this.</p>
+
+<h2>Configuration + Options</h2>
+
+<h3>Default configuration</h3>
+
+<p>Behaviours such as auto-start and UI elements like VU meters and spectrum graphs are easy configurable, using an object literal format as shown below.</p>
+<p>The page player config (see related page-player.js file) as below.</p>
+<p>The custom parameters used to make this demo page are highlighted in red.</p>
+<pre class="block"><code> <span>// ( within page-player.js )</span>
+
+ this.config = {
+ flashVersion: <span style="color:red">9</span>, <span>// version of Flash to tell SoundManager to use - either 8 or 9.</span>
+ usePeakData: <span style="color:red">true</span>, <span>// [Flash 9 only] show peak (VU-meter) data</span>
+ useFavIcon: <span style="color:red">true</span>, <span>// try to show peakData in address bar (Firefox + Opera) - requires usePeakData = true too, of course.</span>
+ useWaveformData: <span style="color:red">true</span>, <span>// [Flash 9 only] true: show raw waveform data - WARNING: CPU-intensive</span>
+ useEQData: false, <span>// [Flash 9 only] show EQ (frequency spectrum) data - WARNING: CPU-intensive</span>
+ fillGraph: false, <span>// [Flash 9 only] draw full lines instead of only top (peak) spectrum points</span>
+ allowRightClick:true, <span>// let users right-click MP3 links ("save as...", etc.) or discourage (can't prevent.)</span>
+ useThrottling: false, <span>// try to rate-limit potentially-expensive calls (eg. dragging position around)</span>
+ autoStart: false, <span>// begin playing first sound when page loads</span>
+ playNext: true, <span>// stop after one sound, or play through list until end</span>
+ updatePageTitle: true, <span>// change the page title while playing sounds</span>
+ emptyTime: '-:--' <span>// null/undefined timer values (before data is available)</span>
+ }
+</code></pre>
+
+<h3>Per-page configuration override</h3>
+
+<p>Alternately, you may override the defaults on a per-page basis by defining an "alternate configuration" object <b>before</b> the page-player.js file has been included in your source code:</p>
+
+<pre class="block"><code> <span>// ( before page-player.js )</span>
+
+ var PP_CONFIG = {
+ flashVersion: 9, <span>// version of Flash to tell SoundManager to use - either 8 or 9. Flash 9 required for peak / spectrum data.</span>
+ usePeakData: true, <span>// [Flash 9 only] whether or not to show peak data (no notable CPU cost)</span>
+ useWaveformData: true <span>// [Flash 9 only] show raw waveform data. WARNING: Experimental, likely CPU-heavy</span>
+ }</code></pre>
+
+<p>Any options specified in PP_CONFIG will override the defaults defined in page-player.js.</p>
+
+ <h3>Basic CSS</h3>
+
+<pre>
+ If you want to make your own UI from scratch, here is the base:
+
+ ul.playlist {}
+
+ Default + hover state, "click to play":
+
+ li.sm2_link {}
+ li.sm2_link:hover {}
+
+ Playing + hover state, "click to pause":
+
+ li.sm2_playing {}
+ li.sm2_playing:hover {}
+
+ Paused + hover state, "click to resume":
+
+ li.sm2_paused {}
+ li.sm2_paused:hover {}
+</pre>
+
+<p>The positioning (load status / control bar) template is also applied after each MP3 link, from an element named "control-template"</p>
+
+<p>"loading" and "position" have background colors applied, and have their width adjusted dynamically by SM2 as the sound(s) load/play. "timing" is replaced with the current time / duration, eg. 1:23 / 4:20</p>
+<p>The class names applied can be edited within the source JS also, for convenience.</p>
+<p>The controls are shown and hidden via the same dynamic CSS updates. See the source CSS for the timing / status bar layout.</p>
+
+<h2>Performance Considerations</h2>
+<h3>Experimental Flash 9 features</h3>
+<ul class="tight" style="padding-top:1px">
+ <li>
+ <h4>Dynamic "favicon" VU meter</h4>
+ <p>The VU meter "favicon" option as shown in the address/location bar for Firefox and Opera can cause a lot of disk access in Firefox (2.x/3.0 at time of writing, from what has been reported.) It may be garbage collection-related.</p>
+ <p>The behaviour seems to be connected to the dynamic swapping of &lt;link&gt; elements with data: URIs containing the VU meter data, and looks to be noticeable with the first sound played - after which point things settle down. Perhaps the browser is attempting to cache the favicon data being assigned.</p>
+ </li>
+ <li>
+ <h4>Waveform/spectrum visualization graph</h4>
+ <p>Enabling the waveformData and/or eqData features will result in some heavy DOM calls (manipulation of 256 &lt;div&gt; elements with each "frame" drawn) which can eat up a good amount of CPU and may make really old computers cower in fear.</p>
+ <p>Ultimately, the UI refresh rate will simply be limited if a CPU ceiling is hit, and audio playback should not be affected.</p>
+ </li>
+</ul>
+
+<h3>More CSS comments</h3>
+
+<div>
+<pre>
+ SoundManager 2: "page as playlist" example
+ ------------------------------------------
+
+ Clicks on links to MP3s are intercepted via JS, calls are
+ made to SoundManager to load/play sounds. CSS classes are
+ appended to the LI parent, which are used to highlight the
+ current play state and so on.
+
+ Class names are applied in addition to "sm2_link" base.
+
+ Default:
+
+ sm2_link
+
+ Additional states:
+
+ sm2_playing
+ sm2_paused
+
+ eg.
+
+ &lt;!-- default --&gt;
+ &lt;li class="sm2_link"&gt;&lt;a href="some.mp3"&gt;some.mp3&lt;/a&gt;&lt;/li&gt;
+
+ &lt;!-- playing --&gt;
+ &lt;li class="sm2_link sm2_playing"&gt;&lt;a href="some.mp3"&gt;some.mp3&lt;/a&gt;&lt;/li&gt;
+
+ The script also injects an HTML template containing control bar
+ and timing elements, which can also be targeted with CSS.
+
+
+ Note you don't necessarily require ul.playlist for your use
+ if only using one style on a page. You can just use .sm2_link
+ and so on, but isolate the CSS you want.
+
+ Side note: Would do multiple class definitions eg.
+
+ li.sm2_default.sm2_playing{}
+
+ .. except IE 6 has a parsing bug which may break behaviour,
+ applying sm2_playing {} even when the class is set to sm2_default.
+
+
+ If you want to make your own UI from scratch, here is the base:
+
+ Default + hover state, "click to play":
+
+ li.sm2_link {}
+ li.sm2_link:hover {}
+
+ Playing + hover state, "click to pause":
+
+ li.sm2_playing {}
+ li.sm2_playing:hover {}
+
+ Paused + hover state, "click to resume":
+
+ li.sm2_paused {}
+ li.sm2_paused:hover {}
+</pre>
+</div>
+
+<p><a href="http://www.schillmania.com/projects/soundmanager2/" title="Javascript MP3 sound player API">SoundManager 2 project home</a></p>
+
+</div>
+
+</body>
+</html>
diff --git a/docs/dymaxion/soundmanagerv297a-20101010/demo/page-player/script/page-player.js b/docs/dymaxion/soundmanagerv297a-20101010/demo/page-player/script/page-player.js
new file mode 100755
index 0000000..607cfff
--- /dev/null
+++ b/docs/dymaxion/soundmanagerv297a-20101010/demo/page-player/script/page-player.js
@@ -0,0 +1,936 @@
+/*
+
+ SoundManager 2 Demo: "Page as playlist"
+ ----------------------------------------------
+ http://schillmania.com/projects/soundmanager2/
+
+ An example of a Muxtape.com-style UI, where an
+ unordered list of MP3 links becomes a playlist
+
+ Flash 9 "MovieStar" edition supports MPEG4
+ audio as well.
+
+ Requires SoundManager 2 Javascript API.
+
+*/
+
+function PagePlayer(oConfigOverride) {
+ var self = this;
+ var pl = this;
+ var sm = soundManager; // soundManager instance
+ // sniffing for favicon stuff/IE workarounds
+ var uA = navigator.userAgent;
+ var isIE = uA.match(/msie/i);
+ var isOpera = uA.match(/opera/i);
+ var isFirefox = uA.match(/firefox/i);
+ var isTouchDevice = (uA.match(/ipad|iphone/i));
+
+ this.config = {
+ flashVersion: 8, // version of Flash to tell SoundManager to use - either 8 or 9. Flash 9 required for peak / spectrum data.
+ usePeakData: false, // [Flash 9 only]: show peak data
+ useWaveformData: false, // [Flash 9 only]: enable sound spectrum (raw waveform data) - WARNING: CPU-INTENSIVE: may set CPUs on fire.
+ useEQData: false, // [Flash 9 only]: enable sound EQ (frequency spectrum data) - WARNING: Also CPU-intensive.
+ fillGraph: false, // [Flash 9 only]: draw full lines instead of only top (peak) spectrum points
+ allowRightClick:true, // let users right-click MP3 links ("save as...", etc.) or discourage (can't prevent.)
+ useThrottling: true, // try to rate-limit potentially-expensive calls (eg. dragging position around)
+ autoStart: false, // begin playing first sound when page loads
+ playNext: true, // stop after one sound, or play through list until end
+ updatePageTitle: true, // change the page title while playing sounds
+ emptyTime: '-:--', // null/undefined timer values (before data is available)
+ useFavIcon: false // try to show peakData in address bar (Firefox + Opera) - may be too CPU heavy
+ }
+
+ sm.debugMode = (window.location.href.toString().match(/debug=1/i)?true:false); // enable with #debug=1 for example
+
+ this._mergeObjects = function(oMain,oAdd) {
+ // non-destructive merge
+ var o1 = {}; // clone o1
+ for (var i in oMain) {
+ o1[i] = oMain[i];
+ }
+ var o2 = (typeof oAdd == 'undefined'?{}:oAdd);
+ for (var o in o2) {
+ if (typeof o1[o] == 'undefined') o1[o] = o2[o];
+ }
+ return o1;
+ }
+
+ if (typeof oConfigOverride != 'undefined' && oConfigOverride) {
+ // allow overriding via arguments object
+ this.config = this._mergeObjects(oConfigOverride,this.config);
+ }
+
+ this.css = { // CSS class names appended to link during various states
+ sDefault: 'sm2_link', // default state
+ sLoading: 'sm2_loading',
+ sPlaying: 'sm2_playing',
+ sPaused: 'sm2_paused'
+ }
+
+ // apply externally-defined override, if applicable
+ this.cssBase = []; // optional features added to ul.playlist
+ if (this.config.usePeakData) this.cssBase.push('use-peak');
+ if (this.config.useWaveformData || this.config.useEQData) this.cssBase.push('use-spectrum');
+ this.cssBase = this.cssBase.join(' ');
+
+ // apply some items to SM2
+ sm.useFlashBlock = true;
+ sm.flashVersion = this.config.flashVersion;
+ if (sm.flashVersion >= 9) {
+ sm.useMovieStar = this.config.useMovieStar; // enable playing FLV, MP4 etc.
+ sm.defaultOptions.usePeakData = this.config.usePeakData;
+ sm.defaultOptions.useWaveformData = this.config.useWaveformData;
+ sm.defaultOptions.useEQData = this.config.useEQData;
+ }
+
+ this.links = [];
+ this.sounds = [];
+ this.soundsByObject = [];
+ this.lastSound = null;
+ this.soundCount = 0;
+ this.strings = [];
+ this.dragActive = false;
+ this.dragExec = new Date();
+ this.dragTimer = null;
+ this.pageTitle = document.title;
+ this.lastWPExec = new Date();
+ this.lastWLExec = new Date();
+ this.vuMeterData = [];
+ this.oControls = null;
+
+ this.addEventHandler = function(o,evtName,evtHandler) {
+ typeof(attachEvent)=='undefined'?o.addEventListener(evtName,evtHandler,false):o.attachEvent('on'+evtName,evtHandler);
+ }
+
+ this.removeEventHandler = function(o,evtName,evtHandler) {
+ typeof(attachEvent)=='undefined'?o.removeEventListener(evtName,evtHandler,false):o.detachEvent('on'+evtName,evtHandler);
+ }
+
+ this.hasClass = function(o,cStr) {
+ return (typeof(o.className)!='undefined'?new RegExp('(^|\\s)'+cStr+'(\\s|$)').test(o.className):false);
+ }
+
+ this.addClass = function(o,cStr) {
+ if (!o || !cStr) return false; // safety net
+ if (self.hasClass(o,cStr)) return false;
+ o.className = (o.className?o.className+' ':'')+cStr;
+ }
+
+ this.removeClass = function(o,cStr) {
+ if (!o || !cStr) return false; // safety net
+ if (!self.hasClass(o,cStr)) return false;
+ o.className = o.className.replace(new RegExp('( '+cStr+')|('+cStr+')','g'),'');
+ }
+
+ this.getElementsByClassName = function(className,tagNames,oParent) {
+ var doc = (oParent?oParent:document);
+ var matches = [];
+ var i,j;
+ var nodes = [];
+ if (typeof(tagNames)!='undefined' && typeof(tagNames)!='string') {
+ for (i=tagNames.length; i--;) {
+ if (!nodes || !nodes[tagNames[i]]) {
+ nodes[tagNames[i]] = doc.getElementsByTagName(tagNames[i]);
+ }
+ }
+ } else if (tagNames) {
+ nodes = doc.getElementsByTagName(tagNames);
+ } else {
+ nodes = doc.all||doc.getElementsByTagName('*');
+ }
+ if (typeof(tagNames)!='string') {
+ for (i=tagNames.length; i--;) {
+ for (j=nodes[tagNames[i]].length; j--;) {
+ if (self.hasClass(nodes[tagNames[i]][j],className)) {
+ matches[matches.length] = nodes[tagNames[i]][j];
+ }
+ }
+ }
+ } else {
+ for (i=0; i<nodes.length; i++) {
+ if (self.hasClass(nodes[i],className)) {
+ matches[matches.length] = nodes[i];
+ }
+ }
+ }
+ return matches;
+ }
+
+ this.getOffX = function(o) {
+ // http://www.xs4all.nl/~ppk/js/findpos.html
+ var curleft = 0;
+ if (o.offsetParent) {
+ while (o.offsetParent) {
+ curleft += o.offsetLeft;
+ o = o.offsetParent;
+ }
+ }
+ else if (o.x) curleft += o.x;
+ return curleft;
+ }
+
+ this.isChildOfClass = function(oChild,oClass) {
+ if (!oChild || !oClass) return false;
+ while (oChild.parentNode && !self.hasClass(oChild,oClass)) {
+ oChild = oChild.parentNode;
+ }
+ return (self.hasClass(oChild,oClass));
+ }
+
+ this.getParentByNodeName = function(oChild,sParentNodeName) {
+ if (!oChild || !sParentNodeName) return false;
+ sParentNodeName = sParentNodeName.toLowerCase();
+ while (oChild.parentNode && sParentNodeName != oChild.parentNode.nodeName.toLowerCase()) {
+ oChild = oChild.parentNode;
+ }
+ return (oChild.parentNode && sParentNodeName == oChild.parentNode.nodeName.toLowerCase()?oChild.parentNode:null);
+ }
+
+ this.getTime = function(nMSec,bAsString) {
+ // convert milliseconds to mm:ss, return as object literal or string
+ var nSec = Math.floor(nMSec/1000);
+ var min = Math.floor(nSec/60);
+ var sec = nSec-(min*60);
+ // if (min == 0 && sec == 0) return null; // return 0:00 as null
+ return (bAsString?(min+':'+(sec<10?'0'+sec:sec)):{'min':min,'sec':sec});
+ }
+
+ this.getSoundByObject = function(o) {
+ return (typeof self.soundsByObject[o.rel] != 'undefined'?self.soundsByObject[o.rel]:null);
+ }
+
+ this.getSoundIndex = function(o) {
+ for (var i=self.links.length; i--;) {
+ if (self.links[i].rel == o.rel) return i;
+ }
+ return -1;
+ }
+
+ this.setPageTitle = function(sTitle) {
+ if (!self.config.updatePageTitle) return false;
+ try {
+ document.title = (sTitle?sTitle+' - ':'')+self.pageTitle;
+ } catch(e) {
+ // oh well
+ self.setPageTitle = function() {return false;}
+ }
+ }
+
+ this.events = {
+
+ // handlers for sound events as they're started/stopped/played
+
+ play: function() {
+ pl.removeClass(this._data.oLI,this._data.className);
+ this._data.className = pl.css.sPlaying;
+ pl.addClass(this._data.oLI,this._data.className);
+ self.setPageTitle(this._data.originalTitle);
+ },
+
+ stop: function() {
+ pl.removeClass(this._data.oLI,this._data.className);
+ this._data.className = '';
+ this._data.oPosition.style.width = '0px';
+ self.setPageTitle();
+ self.resetPageIcon();
+ },
+
+ pause: function() {
+ if (pl.dragActive) return false;
+ pl.removeClass(this._data.oLI,this._data.className);
+ this._data.className = pl.css.sPaused;
+ pl.addClass(this._data.oLI,this._data.className);
+ self.setPageTitle();
+ self.resetPageIcon();
+ },
+
+ resume: function() {
+ if (pl.dragActive) return false;
+ pl.removeClass(this._data.oLI,this._data.className);
+ this._data.className = pl.css.sPlaying;
+ pl.addClass(this._data.oLI,this._data.className);
+ },
+
+ finish: function() {
+ pl.removeClass(this._data.oLI,this._data.className);
+ this._data.className = '';
+ this._data.oPosition.style.width = '0px';
+ // play next if applicable
+ if (self.config.playNext && this._data.nIndex<pl.links.length-1) {
+ pl.handleClick({target:pl.links[this._data.nIndex+1]}); // fake a click event - aren't we sneaky. ;)
+ } else {
+ self.setPageTitle();
+ self.resetPageIcon();
+ }
+ },
+
+ whileloading: function() {
+ function doWork() {
+ this._data.oLoading.style.width = (((this.bytesLoaded/this.bytesTotal)*100)+'%'); // theoretically, this should work.
+ if (!this._data.didRefresh && this._data.metadata) {
+ this._data.didRefresh = true;
+ this._data.metadata.refresh();
+ }
+ }
+ if (!pl.config.useThrottling) {
+ doWork.apply(this);
+ } else {
+ d = new Date();
+ if (d && d-self.lastWLExec>30 || this.bytesLoaded === this.bytesTotal) {
+ doWork.apply(this);
+ self.lastWLExec = d;
+ }
+ }
+
+ },
+
+ onload: function() {
+ if (!this.loaded) {
+ var oTemp = this._data.oLI.getElementsByTagName('a')[0];
+ var oString = oTemp.innerHTML;
+ var oThis = this;
+ oTemp.innerHTML = oString+' <span style="font-size:0.5em"> | Load failed, d\'oh! '+(sm.sandbox.noRemote?' Possible cause: Flash sandbox is denying remote URL access.':(sm.sandbox.noLocal?'Flash denying local filesystem access':'404?'))+'</span>';
+ setTimeout(function(){
+ oTemp.innerHTML = oString;
+ // pl.events.finish.apply(oThis); // load next
+ },5000);
+ } else {
+ if (this._data.metadata) {
+ this._data.metadata.refresh();
+ }
+ }
+ },
+
+ whileplaying: function() {
+ var d = null;
+ if (pl.dragActive || !pl.config.useThrottling) {
+ self.updateTime.apply(this);
+ if (sm.flashVersion >= 9) {
+ if (pl.config.usePeakData && this.instanceOptions.usePeakData) self.updatePeaks.apply(this);
+ if (pl.config.useWaveformData && this.instanceOptions.useWaveformData || pl.config.useEQData && this.instanceOptions.useEQData) {
+ self.updateGraph.apply(this);
+ }
+ }
+ if (this._data.metadata) {
+ d = new Date();
+ if (d && d-self.lastWPExec>500) {
+ self.refreshMetadata(this);
+ self.lastWPExec = d;
+ }
+ }
+ this._data.oPosition.style.width = (((this.position/self.getDurationEstimate(this))*100)+'%');
+ } else {
+ d = new Date();
+ if (d-self.lastWPExec>30) {
+ self.updateTime.apply(this);
+ if (sm.flashVersion >= 9) {
+ if (pl.config.usePeakData && this.instanceOptions.usePeakData) {
+ self.updatePeaks.apply(this);
+ }
+ if (pl.config.useWaveformData && this.instanceOptions.useWaveformData || pl.config.useEQData && this.instanceOptions.useEQData) {
+ self.updateGraph.apply(this);
+ }
+ }
+ if (this._data.metadata) self.refreshMetadata(this);
+ this._data.oPosition.style.width = (((this.position/self.getDurationEstimate(this))*100)+'%');
+ self.lastWPExec = d;
+ }
+ }
+ }
+
+ } // events{}
+
+ var _head = document.getElementsByTagName('head')[0];
+
+ this.setPageIcon = function(sDataURL) {
+ if (!self.config.useFavIcon || !self.config.usePeakData || !sDataURL) {
+ return false;
+ }
+ var link = document.getElementById('sm2-favicon');
+ if (link) {
+ _head.removeChild(link);
+ link = null;
+ }
+ if (!link) {
+ link = document.createElement('link');
+ link.id = 'sm2-favicon';
+ link.rel = 'shortcut icon';
+ link.type = 'image/png';
+ link.href = sDataURL;
+ document.getElementsByTagName('head')[0].appendChild(link);
+ }
+ }
+
+ this.resetPageIcon = function() {
+ if (!self.config.useFavIcon) {
+ return false;
+ }
+ var link = document.getElementById('favicon');
+ if (link) {
+ link.href = '/favicon.ico';
+ }
+ }
+
+ this.updatePeaks = function() {
+ var o = this._data.oPeak;
+ var oSpan = o.getElementsByTagName('span');
+ oSpan[0].style.marginTop = (13-(Math.floor(15*this.peakData.left))+'px');
+ oSpan[1].style.marginTop = (13-(Math.floor(15*this.peakData.right))+'px');
+ // highly experimental
+ if (self.config.flashVersion > 8 && self.config.useFavIcon && self.config.usePeakData) {
+ self.setPageIcon(self.vuMeterData[parseInt(16*this.peakData.left)][parseInt(16*this.peakData.right)]);
+ }
+ }
+
+ this.updateGraph = function() {
+ if ((!pl.config.useWaveformData && !pl.config.useEQData) || pl.config.flashVersion<9) return false;
+ var sbC = this._data.oGraph.getElementsByTagName('div');
+ if (pl.config.useWaveformData) {
+ // raw waveform
+ var scale = 8; // Y axis (+/- this distance from 0)
+ for (var i=255; i--;) {
+ sbC[255-i].style.marginTop = (1+scale+Math.ceil(this.waveformData.left[i]*-scale))+'px';
+ }
+ } else {
+ // eq spectrum
+ var offset = 9;
+ for (var i=255; i--;) {
+ sbC[255-i].style.marginTop = ((offset*2)-1+Math.ceil(this.eqData[i]*-offset))+'px';
+ }
+ }
+ }
+
+ this.resetGraph = function() {
+ if (!pl.config.useEQData || pl.config.flashVersion<9) return false;
+ var sbC = this._data.oGraph.getElementsByTagName('div');
+ var scale = (!pl.config.useEQData?'9px':'17px');
+ var nHeight = (!pl.config.fillGraph?'1px':'32px');
+ for (var i=255; i--;) {
+ sbC[255-i].style.marginTop = scale; // EQ scale
+ sbC[255-i].style.height = nHeight;
+ }
+ }
+
+ this.refreshMetadata = function(oSound) {
+ // Display info as appropriate
+ var index = null;
+ var now = oSound.position;
+ var metadata = oSound._data.metadata.data;
+ for (var i=0, j=metadata.length; i<j; i++) {
+ if (now >= metadata[i].startTimeMS && now <= metadata[i].endTimeMS) {
+ index = i;
+ break;
+ }
+ }
+ if (index != metadata.currentItem) {
+ // update
+ oSound._data.oLink.innerHTML = metadata.mainTitle+' <span class="metadata"><span class="sm2_divider"> | </span><span class="sm2_metadata">'+metadata[index].title+'</span></span>';
+ self.setPageTitle(metadata[index].title+' | '+metadata.mainTitle);
+ metadata.currentItem = index;
+ }
+ }
+
+ this.updateTime = function() {
+ var str = self.strings['timing'].replace('%s1',self.getTime(this.position,true));
+ str = str.replace('%s2',self.getTime(self.getDurationEstimate(this),true));
+ this._data.oTiming.innerHTML = str;
+ }
+
+ this.getTheDamnTarget = function(e) {
+ return (e.target||(window.event?window.event.srcElement:null));
+ }
+
+ this.withinStatusBar = function(o) {
+ return (self.isChildOfClass(o,'controls'));
+ }
+
+ this.handleClick = function(e) {
+ // a sound (or something) was clicked - determine what and handle appropriately
+ if (e.button == 2) {
+ if (!pl.config.allowRightClick) {
+ pl.stopEvent(e);
+ }
+ return pl.config.allowRightClick; // ignore right-clicks
+ }
+ var o = self.getTheDamnTarget(e);
+ if (!o) {
+ return true;
+ }
+ if (self.dragActive) self.stopDrag(); // to be safe
+ if (self.withinStatusBar(o)) {
+ // self.handleStatusClick(e);
+ return false;
+ }
+ if (o.nodeName.toLowerCase() != 'a') {
+ o = self.getParentByNodeName(o,'a');
+ }
+ if (!o) {
+ // not a link
+ return true;
+ }
+ var sURL = o.getAttribute('href');
+ if (!o.href || (!sm.canPlayLink(o) && !self.hasClass(o,'playable')) || self.hasClass(o,'exclude')) {
+ // do nothing, don't return anything.
+ } else {
+ // we have something we're interested in.
+ var soundURL = o.href;
+ var thisSound = self.getSoundByObject(o);
+ if (thisSound) {
+ // sound already exists
+ self.setPageTitle(thisSound._data.originalTitle);
+ if (thisSound == self.lastSound) {
+ // ..and was playing (or paused) and isn't in an error state
+ if (thisSound.readyState != 2) {
+ if (thisSound.playState != 1) {
+ // not yet playing
+ thisSound.play();
+ } else {
+ thisSound.togglePause();
+ }
+ } else {
+ sm._writeDebug('Warning: sound failed to load (security restrictions, 404 or bad format)',2);
+ }
+ } else {
+ // ..different sound
+ if (self.lastSound) self.stopSound(self.lastSound);
+ thisSound._data.oTimingBox.appendChild(document.getElementById('spectrum-container'));
+ thisSound.togglePause(); // start playing current
+ }
+ } else {
+ // create sound
+ thisSound = sm.createSound({
+ id:'pagePlayerMP3Sound'+(self.soundCount++),
+ url:decodeURI(soundURL),
+ onplay:self.events.play,
+ onstop:self.events.stop,
+ onpause:self.events.pause,
+ onresume:self.events.resume,
+ onfinish:self.events.finish,
+ whileloading:self.events.whileloading,
+ whileplaying:self.events.whileplaying,
+ onmetadata:self.events.metadata,
+ onload:self.events.onload
+ });
+ // append control template
+ var oControls = self.oControls.cloneNode(true);
+ o.parentNode.appendChild(oControls);
+ o.parentNode.appendChild(document.getElementById('spectrum-container'));
+ self.soundsByObject[o.rel] = thisSound;
+ // tack on some custom data
+ thisSound._data = {
+ oLink: o, // DOM reference within SM2 object event handlers
+ oLI: o.parentNode,
+ oControls: self.getElementsByClassName('controls','div',o.parentNode)[0],
+ oStatus: self.getElementsByClassName('statusbar','div',o.parentNode)[0],
+ oLoading: self.getElementsByClassName('loading','div',o.parentNode)[0],
+ oPosition: self.getElementsByClassName('position','div',o.parentNode)[0],
+ oTimingBox: self.getElementsByClassName('timing','div',o.parentNode)[0],
+ oTiming: self.getElementsByClassName('timing','div',o.parentNode)[0].getElementsByTagName('div')[0],
+ oPeak: self.getElementsByClassName('peak','div',o.parentNode)[0],
+ oGraph: self.getElementsByClassName('spectrum-box','div',o.parentNode)[0],
+ nIndex: self.getSoundIndex(o),
+ className: self.css.sPlaying,
+ originalTitle: o.innerHTML,
+ metadata: null
+ };
+ thisSound._data.oTimingBox.appendChild(document.getElementById('spectrum-container'));
+ // "Metadata"
+ if (thisSound._data.oLI.getElementsByTagName('ul').length) {
+ thisSound._data.metadata = new Metadata(thisSound);
+ }
+ // set initial timer stuff (before loading)
+ var str = self.strings['timing'].replace('%s1',self.config.emptyTime);
+ str = str.replace('%s2',self.config.emptyTime);
+ thisSound._data.oTiming.innerHTML = str;
+ self.sounds.push(thisSound);
+ if (self.lastSound) self.stopSound(self.lastSound);
+ self.resetGraph.apply(thisSound);
+ thisSound.play();
+ }
+ self.lastSound = thisSound; // reference for next call
+ return self.stopEvent(e);
+ }
+ }
+
+ this.handleMouseDown = function(e) {
+ // a sound link was clicked
+ if (isTouchDevice && e.touches) {
+ e = e.touches[0];
+ }
+ if (e.button == 2) {
+ if (!pl.config.allowRightClick) pl.stopEvent(e);
+ return (pl.config.allowRightClick); // ignore right-clicks
+ }
+ var o = self.getTheDamnTarget(e);
+ if (!o) {
+ return true;
+ }
+ if (!self.withinStatusBar(o)) return true;
+ self.dragActive = true;
+ self.lastSound.pause();
+ self.setPosition(e);
+ if (!isTouchDevice) {
+ self.addEventHandler(document,'mousemove',self.handleMouseMove);
+ } else {
+ self.addEventHandler(document,'touchmove',self.handleMouseMove);
+ }
+ self.addClass(self.lastSound._data.oControls,'dragging');
+ self.stopEvent(e);
+ return false;
+ }
+
+ this.handleMouseMove = function(e) {
+ if (isTouchDevice && e.touches) {
+ e = e.touches[0];
+ }
+ // set position accordingly
+ if (self.dragActive) {
+ if (self.config.useThrottling) {
+ // be nice to CPU/externalInterface
+ var d = new Date();
+ if (d-self.dragExec>20) {
+ self.setPosition(e);
+ } else {
+ window.clearTimeout(self.dragTimer);
+ self.dragTimer = window.setTimeout(function(){self.setPosition(e)},20);
+ }
+ self.dragExec = d;
+ } else {
+ // oh the hell with it
+ self.setPosition(e);
+ }
+ } else {
+ self.stopDrag();
+ }
+ e.stopPropagation = true;
+ return false;
+ }
+
+ this.stopDrag = function(e) {
+ if (self.dragActive) {
+ self.removeClass(self.lastSound._data.oControls,'dragging');
+ if (!isTouchDevice) {
+ self.removeEventHandler(document,'mousemove',self.handleMouseMove);
+ } else {
+ self.removeEventHandler(document,'touchmove',self.handleMouseMove);
+ }
+ // self.removeEventHandler(document,'mouseup',self.stopDrag);
+ if (!pl.hasClass(self.lastSound._data.oLI,self.css.sPaused)) {
+ self.lastSound.resume();
+ }
+ self.dragActive = false;
+ self.stopEvent(e);
+ return false;
+ }
+ }
+
+ this.handleStatusClick = function(e) {
+ self.setPosition(e);
+ if (!pl.hasClass(self.lastSound._data.oLI,self.css.sPaused)) self.resume();
+ return self.stopEvent(e);
+ }
+
+ this.stopEvent = function(e) {
+ if (typeof e != 'undefined') {
+ if (typeof e.preventDefault != 'undefined') {
+ e.preventDefault();
+ } else if (typeof e.returnValue != 'undefined' || typeof event != 'undefined') {
+ (e||event).cancelBubble = true;
+ (e||event).returnValue = false;
+ }
+ }
+ return false;
+ }
+
+ this.setPosition = function(e) {
+ // called from slider control
+ var oThis = self.getTheDamnTarget(e);
+ if (!oThis) {
+ return true;
+ }
+ var oControl = oThis;
+ while (!self.hasClass(oControl,'controls') && oControl.parentNode) {
+ oControl = oControl.parentNode;
+ }
+ var oSound = self.lastSound;
+ var x = parseInt(e.clientX);
+ // play sound at this position
+ var nMsecOffset = Math.floor((x-self.getOffX(oControl)-4)/(oControl.offsetWidth)*self.getDurationEstimate(oSound));
+ if (!isNaN(nMsecOffset)) nMsecOffset = Math.min(nMsecOffset,oSound.duration);
+ if (!isNaN(nMsecOffset)) oSound.setPosition(nMsecOffset);
+ }
+
+ this.stopSound = function(oSound) {
+ sm._writeDebug('stopping sound: '+oSound.sID);
+ sm.stop(oSound.sID);
+ sm.unload(oSound.sID);
+ }
+
+ this.getDurationEstimate = function(oSound) {
+ if (oSound.instanceOptions.isMovieStar) {
+ return (oSound.duration);
+ } else {
+ return (!oSound._data.metadata || !oSound._data.metadata.data.givenDuration?(oSound.durationEstimate||0):oSound._data.metadata.data.givenDuration);
+ }
+ }
+
+ this.createVUData = function() {
+ var i=0;
+ var j=0;
+ var canvas = vuDataCanvas.getContext('2d');
+ var vuGrad = canvas.createLinearGradient(0, 16, 0, 0);
+ vuGrad.addColorStop(0,'rgb(0,192,0)');
+ vuGrad.addColorStop(0.30,'rgb(0,255,0)');
+ vuGrad.addColorStop(0.625,'rgb(255,255,0)');
+ vuGrad.addColorStop(0.85,'rgb(255,0,0)');
+ var bgGrad = canvas.createLinearGradient(0, 16, 0, 0);
+ var outline = 'rgba(0,0,0,0.2)';
+ bgGrad.addColorStop(0,outline);
+ bgGrad.addColorStop(1,'rgba(0,0,0,0.5)');
+ for (i=0; i<16; i++) {
+ self.vuMeterData[i] = [];
+ }
+ for (var i=0; i<16; i++) {
+ for (j=0; j<16; j++) {
+ // reset/erase canvas
+ vuDataCanvas.setAttribute('width',16);
+ vuDataCanvas.setAttribute('height',16);
+ // draw new stuffs
+ canvas.fillStyle = bgGrad;
+ canvas.fillRect(0,0,7,15);
+ canvas.fillRect(8,0,7,15);
+ /*
+ // shadow
+ canvas.fillStyle = 'rgba(0,0,0,0.1)';
+ canvas.fillRect(1,15-i,7,17-(17-i));
+ canvas.fillRect(9,15-j,7,17-(17-j));
+ */
+ canvas.fillStyle = vuGrad;
+ canvas.fillRect(0,15-i,7,16-(16-i));
+ canvas.fillRect(8,15-j,7,16-(16-j));
+ // and now, clear out some bits.
+ canvas.clearRect(0,3,16,1);
+ canvas.clearRect(0,7,16,1);
+ canvas.clearRect(0,11,16,1);
+ self.vuMeterData[i][j] = vuDataCanvas.toDataURL('image/png');
+ // for debugging VU images
+ /*
+ var o = document.createElement('img');
+ o.style.marginRight = '5px';
+ o.src = self.vuMeterData[i][j];
+ document.documentElement.appendChild(o);
+ */
+ }
+ }
+ };
+
+ var vuDataCanvas = null;
+
+ this.testCanvas = function() {
+ // canvas + toDataURL();
+ var c = document.createElement('canvas');
+ var ctx = null;
+ if (!c || typeof c.getContext == 'undefined') {
+ return null;
+ }
+ ctx = c.getContext('2d');
+ if (!ctx || typeof c.toDataURL != 'function') {
+ return null;
+ }
+ // just in case..
+ try {
+ var ok = c.toDataURL('image/png');
+ } catch(e) {
+ // no canvas or no toDataURL()
+ return null;
+ }
+ // assume we're all good.
+ return c;
+ }
+
+ if (this.config.useFavIcon) {
+ vuDataCanvas = self.testCanvas();
+ if (vuDataCanvas && (isFirefox || isOpera)) {
+ // these browsers support dynamically-updating the favicon
+ self.createVUData();
+ } else {
+ // browser doesn't support doing this
+ this.config.useFavIcon = false;
+ }
+ }
+
+ this.init = function() {
+ sm._writeDebug('pagePlayer.init()');
+ var oLinks = document.getElementsByTagName('a');
+ // grab all links, look for .mp3
+ var foundItems = 0;
+ for (var i=0; i<oLinks.length; i++) {
+ if ((sm.canPlayLink(oLinks[i]) || self.hasClass(oLinks[i],'playable')) && !self.hasClass(oLinks[i],'exclude')) {
+ oLinks[i].rel = 'pagePlayerMP3Sound'+i;
+ self.links[self.links.length] = oLinks[i];
+ self.addClass(oLinks[i],self.css.sDefault); // add default CSS decoration
+ foundItems++;
+ }
+ }
+ if (foundItems>0) {
+ var oTiming = document.getElementById('sm2_timing');
+ self.strings['timing'] = oTiming.innerHTML;
+ oTiming.innerHTML = '';
+ oTiming.id = '';
+ self.addEventHandler(document,'click',self.handleClick);
+ if (!isTouchDevice) {
+ self.addEventHandler(document,'mousedown',self.handleMouseDown);
+ self.addEventHandler(document,'mouseup',self.stopDrag);
+ } else {
+ self.addEventHandler(document,'touchstart',self.handleMouseDown);
+ self.addEventHandler(document,'touchend',self.stopDrag);
+ }
+ // self.addEventHandler(window,'unload',function(){}); // force page reload when returning here via back button (Opera tries to remember old state, etc.)
+ }
+ sm._writeDebug('pagePlayer.init(): Found '+foundItems+' relevant items.');
+ if (self.config.autoStart) {
+ pl.handleClick({target:pl.links[0]});
+ }
+ }
+
+var Metadata = function(oSound) {
+ var self = this;
+ var oLI = oSound._data.oLI;
+ var o = oLI.getElementsByTagName('ul')[0];
+ var oItems = o.getElementsByTagName('li');
+ var oTemplate = document.createElement('div');
+ oTemplate.innerHTML = '<span>&nbsp;</span>';
+ oTemplate.className = 'annotation';
+ var oTemplate2 = document.createElement('div');
+ oTemplate2.innerHTML = '<span>&nbsp;</span>';
+ oTemplate2.className = 'annotation alt';
+
+ var oTemplate3 = document.createElement('div');
+ oTemplate3.className = 'note';
+
+ this.totalTime = 0;
+ this.strToTime = function(sTime) {
+ var segments = sTime.split(':');
+ var seconds = 0;
+ for (var i=segments.length; i--;) {
+ seconds += parseInt(segments[i])*Math.pow(60,segments.length-1-i,10); // hours, minutes
+ }
+ return seconds;
+ }
+ this.data = [];
+ this.data.givenDuration = null;
+ this.data.currentItem = null;
+ this.data.mainTitle = oSound._data.oLink.innerHTML;
+ for (var i=0; i<oItems.length; i++) {
+ this.data[i] = {
+ o: null,
+ title: oItems[i].getElementsByTagName('p')[0].innerHTML,
+ startTime: oItems[i].getElementsByTagName('span')[0].innerHTML,
+ startSeconds: self.strToTime(oItems[i].getElementsByTagName('span')[0].innerHTML.replace(/[()]/g,'')),
+ duration: 0,
+ durationMS: null,
+ startTimeMS: null,
+ endTimeMS: null,
+ oNote: null
+ }
+ }
+ var oDuration = pl.getElementsByClassName('duration','div',oLI);
+ this.data.givenDuration = (oDuration.length?self.strToTime(oDuration[0].innerHTML)*1000:0);
+ for (i=0; i<this.data.length; i++) {
+ this.data[i].duration = parseInt(this.data[i+1]?this.data[i+1].startSeconds:(self.data.givenDuration?self.data.givenDuration:oSound.durationEstimate)/1000)-this.data[i].startSeconds;
+ this.data[i].startTimeMS = this.data[i].startSeconds*1000;
+ this.data[i].durationMS = this.data[i].duration*1000;
+ this.data[i].endTimeMS = this.data[i].startTimeMS+this.data[i].durationMS;
+ this.totalTime += this.data[i].duration;
+ }
+ // make stuff
+ this.createElements = function() {
+ var oFrag = document.createDocumentFragment();
+ var oNode = null;
+ var oNodeSpan = null;
+ var oNode2 = null;
+ for (var i=0; i<self.data.length; i++) {
+ oNode = (i%2==0?oTemplate:oTemplate2).cloneNode(true);
+ oNodeSpan = oNode.getElementsByTagName('span')[0];
+ oNode.rel = i;
+ self.data[i].o = oNode;
+ oNode2 = oTemplate3.cloneNode(true);
+ if (i%2==0) oNode2.className = 'note alt';
+ oNode2.innerHTML = this.data[i].title;
+ // evil old-skool event handlers, css:hover-only ideally would be nice excluding IE 6
+ oNode.onmouseover = self.mouseover;
+ oNode.onmouseout = self.mouseout;
+ this.data[i].oNote = oNode2;
+ oSound._data.oControls.appendChild(oNode2);
+ oFrag.appendChild(oNode);
+ }
+ self.refresh();
+ oSound._data.oStatus.appendChild(oFrag);
+ }
+
+ this.refresh = function() {
+ var offset = 0;
+ var relWidth = null;
+ var duration = (self.data.givenDuration?self.data.givenDuration:oSound.durationEstimate);
+ for (var i=0; i<self.data.length; i++) {
+ if (duration) {
+ relWidth = (((self.data[i].duration*1000)/duration)*100);
+ self.data[i].o.style.left = (offset?offset+'%':'-2px');
+ self.data[i].oNote.style.left = (offset?offset+'%':'0px');
+ offset += relWidth;
+ }
+ }
+ }
+
+ this.mouseover = function(e) {
+ self.data[this.rel].oNote.style.visibility = 'hidden';
+ self.data[this.rel].oNote.style.display = 'inline-block';
+ self.data[this.rel].oNote.style.marginLeft = -parseInt(self.data[this.rel].oNote.offsetWidth/2)+'px';
+ self.data[this.rel].oNote.style.visibility = 'visible';
+ }
+
+ this.mouseout = function() {
+ self.data[this.rel].oNote.style.display = 'none';
+ }
+
+ // ----
+
+ this.createElements();
+ this.refresh();
+
+} // MetaData();
+
+ this.initDOM = function() {
+ // set up graph box stuffs
+ var sb = self.getElementsByClassName('spectrum-box','div',document.documentElement)[0];
+ if (sm.flashVersion >= 9) {
+ var lists = self.getElementsByClassName('playlist','ul',document.documentElement);
+ for (var i=lists.length; i--;) {
+ self.addClass(lists[i],self.cssBase);
+ }
+ var sbC = sb.getElementsByTagName('div')[0];
+ var oF = document.createDocumentFragment();
+ var oClone = null;
+ for (i=256; i--;) {
+ oClone = sbC.cloneNode(false);
+ oClone.style.left = (i)+'px';
+ oF.appendChild(oClone);
+ }
+ sb.removeChild(sbC);
+ sb.appendChild(oF);
+ }
+ this.oControls = document.getElementById('control-template').cloneNode(true);
+ this.oControls.id = '';
+ this.init();
+ }
+
+}
+
+var pagePlayer = new PagePlayer(typeof PP_CONFIG != 'undefined'?PP_CONFIG:null);
+
+soundManager.onready(function() {
+ if (soundManager.supported()) {
+ // soundManager.createSound() etc. may now be called
+ pagePlayer.initDOM();
+ }
+}); \ No newline at end of file