From 3391c7e0768136fe6fe04fad6051983a9946be1a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20M=C3=BCller?= Date: Thu, 13 Jul 2017 22:38:05 +0200 Subject: [PATCH] Initial commit --- soundboard.py | 45 ++++++++++++++++++++++ static/main.css | 91 ++++++++++++++++++++++++++++++++++++++++++++ static/main.js | 53 ++++++++++++++++++++++++++ templates/index.html | 42 ++++++++++++++++++++ 4 files changed, 231 insertions(+) create mode 100644 soundboard.py create mode 100644 static/main.css create mode 100644 static/main.js create mode 100644 templates/index.html diff --git a/soundboard.py b/soundboard.py new file mode 100644 index 0000000..a501310 --- /dev/null +++ b/soundboard.py @@ -0,0 +1,45 @@ +#!/usr/bin/env python3 + +import os +import subprocess + +from flask import Flask, render_template, request, redirect, url_for + +path = "/home/pi/sounds" + +app = Flask(__name__) +app.jinja_env.trim_blocks = True +app.jinja_env.lstrip_blocks = True + +@app.route("/") +@app.route("/play/") +@app.route("/say/", methods=["POST"]) +@app.route("/say/") +def index(sound=None, text=None, video=None): + sounds = sorted(os.listdir(path)) + + if sound is not None and sound in sounds: + subprocess.Popen(["omxplayer", os.path.join(path, sound)], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) + + if text is None: + text = request.form.get("text") + + if text is not None: + voice = request.form.get("voice", default="") + voice = voice if voice.strip() != "" else "DE" + speed = request.form.get("speed", default="") + speed = speed if speed.strip() != "" else "160" + pitch = request.form.get("pitch", default="") + pitch = pitch if pitch.strip() != "" else "50" + + subprocess.Popen(["espeak", "-v", voice, "-s", speed, "-p", pitch, text], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) + return redirect("/") + + video = request.args.get("video") + + if video is not None: + url = subprocess.check_output(["youtube-dl", "-g", "-f", "mp4", video]).decode() + subprocess.Popen(["omxplayer", url.split("\n")[1]]) + subprocess.Popen(["omxplayer", "-b", url.split("\n")[0]]) + + return render_template("index.html", sounds=sounds) diff --git a/static/main.css b/static/main.css new file mode 100644 index 0000000..b2ecfac --- /dev/null +++ b/static/main.css @@ -0,0 +1,91 @@ +htl, body { + margin: 0; +} + +html { + font-family: Helvetica, "Open Sans", sans-serif; +} + +body { + background-color: #333; + color: #eee; +} + +a { + text-decoration: none; +} + +h1 { + text-align: center; +} + +form { + text-align: center; +} + +input { + background-color: #666; + border: 1px solid #999; + border-radius: 5px; + color: #eee; + margin: 0; + padding: 5px; + vertical-align: middle; +} + +label { + vertical-align: middle; +} + +nav { + text-align: center; + margin: 1em; +} + +nav a { + background-color: #eee; + border: 1px solid #000; + border-radius: 5px; + color: #333; + display: inline-block; + padding: 1em; +} + +content { + position: absolute; + width: 100%; +} + +section { + position: absolute; + left: 0; + text-align: center; + top: 0; + width: 100%; +} + +.sound { + display: inline-block; +} + +.sound a { + background-color: #ff4136; + border: 1px solid #000; + border-radius: 50px; + box-shadow: inset -5px -5px 5px rgba(0, 0, 0, 0.6); + color: #eee; + display: inline-block; + font-size: 0.6em; + height: 100px; + line-height: 100px; + margin: 10px; + overflow: hidden; + text-align: center; + text-shadow: -1px 0 black, 0 1px black, 1px 0 black, 0 -1px black; + width: 100px; +} + +.sound a:hover { + background-color: #ff4136; + box-shadow: inset 5px 5px 5px rgba(0, 0, 0, 0.6); +} diff --git a/static/main.js b/static/main.js new file mode 100644 index 0000000..1a55915 --- /dev/null +++ b/static/main.js @@ -0,0 +1,53 @@ +function ready(fn) { + if (document.attachEvent ? document.readyState === "complete" : document.readyState !== "loading") { + fn(); + } else { + document.addEventListener("DOMContentLoaded", fn); + } +} + +ready(function() { + hideSections(); + + var sections = document.querySelectorAll("section"); + var nav = document.querySelectorAll("nav a"); + + sections[0].style.display = "block"; + + nav.forEach(function(item) { + item.onclick = function(e) { + e.preventDefault(); + + var target = e.target.href.split("#"); + var id = target[target.length - 1]; + + hideSections(); + + document.querySelector("#" + id).style.display = "block"; + }; + }); + + var searchfield = document.querySelector("#search"); + + searchfield.addEventListener("keypress", function() { + console.log("Search!"); + + var buttons = document.querySelectorAll(".sound"); + + buttons.forEach(function(item) { + var name = item.firstChild.innerHTML; + + if (name.indexOf(searchfield.value) === -1) { + item.style.display = "none"; + } + }); + }); +}); + +function hideSections() { + var sections = document.querySelectorAll("section"); + + sections.forEach(function(item, i) { + item.style.display = "none"; + }); +} diff --git a/templates/index.html b/templates/index.html new file mode 100644 index 0000000..bb5419a --- /dev/null +++ b/templates/index.html @@ -0,0 +1,42 @@ + + + + + WIAI Soundboard + + + + + +
+
+ {% for sound in sounds %} + + {% endfor %} +
+
+
+ + + +
+
+
+
+ + + + + + + +
+
+
+ + +