/ audio_stream.html
audio_stream.html
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="utf-8"> 5 <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1"> 6 7 <title>Stream — Space.js</title> 8 9 <link rel="preconnect" href="https://fonts.gstatic.com"> 10 <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Roboto+Mono&family=Roboto:wght@300&family=Gothic+A1:wght@500;700"> 11 <link rel="stylesheet" href="assets/css/style.css"> 12 13 <script type="module"> 14 import { Panel, PanelItem, UI, WebAudio } from './src/index.js'; 15 16 class AudioController { 17 static init(ui) { 18 this.ui = ui; 19 20 this.initSounds(); 21 22 this.addListeners(); 23 } 24 25 static initSounds() { 26 this.cyberspace = WebAudio.get('cyberspace'); 27 this.cyberspace.gain.set(1); 28 } 29 30 static addListeners() { 31 document.addEventListener('visibilitychange', this.onVisibility); 32 document.addEventListener('click', this.onClick); 33 34 this.ui.instructions.animateIn(); 35 } 36 37 // Event handlers 38 39 static onVisibility = () => { 40 if (document.hidden) { 41 WebAudio.mute(); 42 } else { 43 WebAudio.unmute(); 44 } 45 }; 46 47 static onClick = () => { 48 document.removeEventListener('click', this.onClick); 49 50 WebAudio.resume(); 51 52 this.ui.instructions.animateOut(); 53 54 this.cyberspace.play(); 55 }; 56 } 57 58 class PanelController { 59 static init(ui) { 60 this.ui = ui; 61 62 this.initPanel(); 63 } 64 65 static initPanel() { 66 const { cyberspace } = AudioController; 67 68 const panel = new Panel(); 69 panel.animateIn(); 70 this.ui.add(panel); 71 72 const items = [ 73 { 74 name: 'Cyberspace' 75 }, 76 { 77 type: 'divider' 78 }, 79 { 80 type: 'slider', 81 name: 'Volume', 82 min: 0, 83 max: 1, 84 step: 0.01, 85 value: cyberspace.gain.value, 86 callback: value => { 87 cyberspace.gain.value = value; 88 } 89 }, 90 { 91 type: 'slider', 92 name: 'Pan', 93 min: -1, 94 max: 1, 95 step: 0.01, 96 value: cyberspace.stereoPan.value, 97 callback: value => { 98 cyberspace.stereoPan.value = value; 99 } 100 } 101 ]; 102 103 items.forEach(data => { 104 panel.add(new PanelItem(data)); 105 }); 106 } 107 } 108 109 class App { 110 static async init() { 111 this.initViews(); 112 this.initAudio(); 113 this.initPanel(); 114 } 115 116 static initViews() { 117 this.ui = new UI({ 118 instructions: { 119 content: `${navigator.maxTouchPoints ? 'Tap' : 'Click'} for sound` 120 } 121 }); 122 this.ui.css({ 123 minHeight: '100%', 124 display: 'flex', 125 justifyContent: 'center', 126 alignItems: 'center', 127 padding: '55px 0 125px' 128 }); 129 document.body.appendChild(this.ui.element); 130 } 131 132 static initAudio() { 133 WebAudio.init({ sampleRate: 48000 }); 134 WebAudio.load({ cyberspace: 'https://icecast.cyberspace.app/dive.ogg' }); 135 136 AudioController.init(this.ui); 137 } 138 139 static initPanel() { 140 PanelController.init(this.ui); 141 } 142 } 143 144 App.init(); 145 </script> 146 </head> 147 <body> 148 </body> 149 </html>