web audio attempt
This commit is contained in:
parent
d864b3edf9
commit
5c975b8725
43
scorch.py
43
scorch.py
|
@ -2,7 +2,9 @@
|
||||||
"""
|
"""
|
||||||
A music streaming application.
|
A music streaming application.
|
||||||
"""
|
"""
|
||||||
from aiohttp import web
|
import asyncio
|
||||||
|
|
||||||
|
from aiohttp import web, WSMsgType
|
||||||
import jinja2
|
import jinja2
|
||||||
import aiohttp_jinja2
|
import aiohttp_jinja2
|
||||||
from aiohttp_jinja2 import render_template
|
from aiohttp_jinja2 import render_template
|
||||||
|
@ -14,12 +16,51 @@ import buckler_aiohttp
|
||||||
uvloop.install()
|
uvloop.install()
|
||||||
routes = web.RouteTableDef()
|
routes = web.RouteTableDef()
|
||||||
|
|
||||||
|
with open ('test.opus', 'rb') as file:
|
||||||
|
test_data = file.read()
|
||||||
|
|
||||||
|
def chunker(seq, size):
|
||||||
|
return (seq[pos:pos + size] for pos in range(0, len(seq), size))
|
||||||
|
|
||||||
|
async def send_files(ws):
|
||||||
|
for n, chunk in enumerate(chunker(test_data, 200*1024)):
|
||||||
|
print(f"sending packet #{n}")
|
||||||
|
await ws.send_bytes(chunk)
|
||||||
|
await asyncio.sleep(5)
|
||||||
|
|
||||||
|
|
||||||
@routes.get('/', name='index')
|
@routes.get('/', name='index')
|
||||||
async def index(request):
|
async def index(request):
|
||||||
"""The index page."""
|
"""The index page."""
|
||||||
return render_template('index.html', request, {})
|
return render_template('index.html', request, {})
|
||||||
|
|
||||||
|
|
||||||
|
@routes.get('/ws', name='ws')
|
||||||
|
async def websocket_handler(request):
|
||||||
|
"""The websocket endpoint."""
|
||||||
|
ws = web.WebSocketResponse(heartbeat=30)
|
||||||
|
ws_ready = ws.can_prepare(request)
|
||||||
|
if not ws_ready.ok:
|
||||||
|
return web.Response(text="Cannot start websocket.")
|
||||||
|
await ws.prepare(request)
|
||||||
|
|
||||||
|
async for msg in ws:
|
||||||
|
if msg.type != WSMsgType.TEXT:
|
||||||
|
break
|
||||||
|
|
||||||
|
if msg.data == "ping":
|
||||||
|
print('ping')
|
||||||
|
await ws.send_str("pong")
|
||||||
|
|
||||||
|
if msg.data == 'test':
|
||||||
|
print('initiating test')
|
||||||
|
asyncio.create_task(send_files(ws))
|
||||||
|
|
||||||
|
|
||||||
|
await ws.close()
|
||||||
|
return ws
|
||||||
|
|
||||||
|
|
||||||
async def init_app():
|
async def init_app():
|
||||||
"""Initializes the application."""
|
"""Initializes the application."""
|
||||||
app = web.Application(middlewares=[buckler_aiohttp.buckler_session])
|
app = web.Application(middlewares=[buckler_aiohttp.buckler_session])
|
||||||
|
|
|
@ -0,0 +1,73 @@
|
||||||
|
var socket;
|
||||||
|
var audioCtx = new window.AudioContext();
|
||||||
|
var source = audioCtx.createBufferSource();
|
||||||
|
var total_raw;
|
||||||
|
|
||||||
|
function appendBuffer(buffer1, buffer2) {
|
||||||
|
let numberOfChannels = Math.min( buffer1.numberOfChannels, buffer2.numberOfChannels );
|
||||||
|
let tmp = audioCtx.createBuffer( numberOfChannels, (buffer1.length + buffer2.length), buffer1.sampleRate );
|
||||||
|
for (let i=0; i<numberOfChannels; i++) {
|
||||||
|
let channel = tmp.getChannelData(i);
|
||||||
|
channel.set( buffer1.getChannelData(i), 0);
|
||||||
|
channel.set( buffer2.getChannelData(i), buffer1.length);
|
||||||
|
}
|
||||||
|
return tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
function appendBuffer2(buffer1, buffer2) {
|
||||||
|
var tmp = new Uint8Array(buffer1.byteLength + buffer2.byteLength);
|
||||||
|
var buff1 = new Uint8Array(buffer1);
|
||||||
|
var buff2 = new Uint8Array(buffer2);
|
||||||
|
tmp.set(buff1, 0);
|
||||||
|
tmp.set(buff2, buffer1.byteLength);
|
||||||
|
return tmp.buffer;
|
||||||
|
};
|
||||||
|
|
||||||
|
function load() {
|
||||||
|
socket = init_websocket();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Websocket setup */
|
||||||
|
function init_websocket() {
|
||||||
|
let socket = new WebSocket('wss://' + window.location.hostname + ws_uri);
|
||||||
|
socket.binaryType = "arraybuffer";
|
||||||
|
socket.onmessage = onmessage;
|
||||||
|
socket.onclose = onclose;
|
||||||
|
socket.onerror = onerror;
|
||||||
|
socket.events = {};
|
||||||
|
return socket;
|
||||||
|
}
|
||||||
|
|
||||||
|
function onmessage (e) {
|
||||||
|
console.log(e);
|
||||||
|
if (e.data.constructor === ArrayBuffer) {
|
||||||
|
console.log(e.data.byteLength);
|
||||||
|
if (source.buffer != null) {
|
||||||
|
total_raw = appendBuffer2(total_raw, e.data);
|
||||||
|
} else {
|
||||||
|
total_raw = e.data;
|
||||||
|
}
|
||||||
|
audioCtx.decodeAudioData(total_raw.slice(0)).then(function(decodedBuffer) {
|
||||||
|
if (source.buffer != null) {
|
||||||
|
source.stop();
|
||||||
|
}
|
||||||
|
source = audioCtx.createBufferSource();
|
||||||
|
source.buffer = decodedBuffer;
|
||||||
|
source.connect(audioCtx.destination);
|
||||||
|
source.start(0, audioCtx.currentTime);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function onclose(e) {
|
||||||
|
if (e.wasClean) { return; } // no need to reconnect
|
||||||
|
console.log(e);
|
||||||
|
console.log('Websocket lost connection to server. Re-trying...');
|
||||||
|
//socket = init_websocket();
|
||||||
|
//await sleep(5000);
|
||||||
|
}
|
||||||
|
|
||||||
|
function onerror(e) {
|
||||||
|
console.log("Websocket error!")
|
||||||
|
console.log(e);
|
||||||
|
}
|
|
@ -3,7 +3,9 @@
|
||||||
<head>
|
<head>
|
||||||
<title>Scorch</title>
|
<title>Scorch</title>
|
||||||
<link rel="stylesheet" type="text/css" href="/static/scorch.css">
|
<link rel="stylesheet" type="text/css" href="/static/scorch.css">
|
||||||
|
<script>const ws_uri = "{{ url('ws') }}";</script>
|
||||||
<script type="text/javascript" src="/static/scorch.js"></script>
|
<script type="text/javascript" src="/static/scorch.js"></script>
|
||||||
|
<script>window.onload = load;</script>
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=0.8">
|
<meta name="viewport" content="width=device-width, initial-scale=0.8">
|
||||||
<meta name="description" content="A music streaming service.">
|
<meta name="description" content="A music streaming service.">
|
||||||
</head>
|
</head>
|
||||||
|
@ -12,6 +14,8 @@
|
||||||
<h1>Scorch</h1>
|
<h1>Scorch</h1>
|
||||||
</header>
|
</header>
|
||||||
<main>
|
<main>
|
||||||
|
<button onclick="socket.send('test')">Test</button>
|
||||||
|
<audio controls></audio>
|
||||||
</main>
|
</main>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
Loading…
Reference in New Issue
Block a user