Skip to content

Commit

Permalink
Added visualizer
Browse files Browse the repository at this point in the history
  • Loading branch information
netham45 committed May 9, 2024
1 parent d934a7d commit 663ac8a
Show file tree
Hide file tree
Showing 7 changed files with 363 additions and 130 deletions.
Binary file modified images/ScreamRouter.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ The simplicity of Scream allows it to be very easy to work with while retaining
* Can use ffmpeg to delay any sink, route, source, or group so sinks line up better
* Can adjust equalization for any sink, route, source, or group
* Contains a plugin system to easily allow additional sources to be added
* Milkdrop Visualizations thanks to the browser-based [Butterchurn](https://github.com/jberg/butterchurn) project
* There are playback sinks available for common OSes such as [Windows](https://github.com/duncanthrax/scream/tree/master/Receivers/dotnet-windows/ScreamReader), [Linux](https://github.com/duncanthrax/scream/tree/master/Receivers/unix), and [Android](https://github.com/martinellimarco/scream-android/tree/90d1364ee36dd12ec9d7d2798926150b370030f3), as well as some embedded devices such as [the ESP32](http://tomeko.net/projects/esp32_rtp_pager/).

![Screenshot of ScreamRouter Equalizer](/images/Equalizer.png)
Expand Down
2 changes: 1 addition & 1 deletion site/imports/selects.html.jinja
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{% macro option(value, label, class="", data="{}", checked=False) %}
<SPAN VALUE="{{value}}" CLASS="{{class}}" ONCLICK="option_onclick(event)" {% for name, datum in data %}DATA-{{name}}="{{datum}}" {% endfor %}DATA-TYPE="{{data.__class__.__name__}}" {{"SELECTED" if checked}}><SPAN CLASS="button-icon" ONCLICK="equalizer_icon_onclick(event)">🎚️</SPAN><SPAN CLASS="button-icon" ONCLICK="update_icon_onclick(event)">⚙️</SPAN><SPAN CLASS="button-icon" ONCLICK="volume_icon_onclick(event)">{{ "🔊" if data["enabled"] else "🔇"}}</SPAN><SPAN CLASS="button-icon" ONCLICK="remove_icon_onclick(event)">➖</SPAN>{% if (data.__class__.__name__ == "SinkDescription" and not data.is_group) %}<SPAN CLASS="button-icon" ONCLICK="listen_icon_onclick(event)">📻</SPAN>{% endif %}{{label}}</SPAN>
<SPAN VALUE="{{value}}" CLASS="{{class}}" ONCLICK="option_onclick(event)" {% for name, datum in data %}DATA-{{name}}="{{datum}}" {% endfor %}DATA-TYPE="{{data.__class__.__name__}}" {{"SELECTED" if checked}}><SPAN CLASS="button-icon" ONCLICK="equalizer_icon_onclick(event)">🎚️</SPAN><SPAN CLASS="button-icon" ONCLICK="update_icon_onclick(event)">⚙️</SPAN><SPAN CLASS="button-icon" ONCLICK="volume_icon_onclick(event)">{{ "🔊" if data["enabled"] else "🔇"}}</SPAN><SPAN CLASS="button-icon" ONCLICK="remove_icon_onclick(event)">➖</SPAN>{% if (data.__class__.__name__ == "SinkDescription" and not data.is_group) %}<SPAN CLASS="button-icon" ONCLICK="listen_icon_onclick(event)">📻</SPAN><SPAN CLASS="button-icon" ONCLICK="visualizer_icon_onclick(event)">✨</SPAN>{% endif %}{{label}}</SPAN>
{%- endmacro %}

{% macro make_multiple_options(options, data="{}") %}
Expand Down
134 changes: 47 additions & 87 deletions site/index.html.jinja
Original file line number Diff line number Diff line change
Expand Up @@ -2,97 +2,57 @@
{%- import "imports/buttons.html.jinja" as buttons -%}
<!DOCTYPE html>
<HTML>
<HEAD>
<META NAME="viewport" CONTENT="width=device-width, initial-scale=1" />
<TITLE>ScreamRouter</TITLE>
<SCRIPT TYPE="text/javascript" SRC="{{url_for('site_javascript')}}"></SCRIPT>
<LINK REL="stylesheet" TYPE="text/css" HREF="{{url_for('site_css')}}">
</HEAD>
<BODY>

<HEAD>
<META NAME="viewport" CONTENT="width=device-width, initial-scale=1" />
<TITLE>ScreamRouter</TITLE>
<LINK REL="stylesheet" TYPE="text/css" HREF="{{url_for('site_css')}}">
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="description" content="Butterchurn Demo Example">
<meta name="viewport" content="width=device-width, initial-scale=1">

<script type="text/javascript" src="https://unpkg.com/lodash"></script>
<script type="text/javascript" src="https://unpkg.com/butterchurn"></script>
<script type="text/javascript" src="https://unpkg.com/butterchurn-presets"></script>
<script type="text/javascript" src="https://unpkg.com/butterchurn-presets/lib/butterchurnPresetsExtra.min.js"></script>

<link rel="stylesheet" href="https://unpkg.com/normalize.css/normalize.css" />
<SCRIPT TYPE="text/javascript" SRC="{{url_for('site_javascript')}}"></SCRIPT>
</HEAD>

<BODY>
<DIV ID="randomcontainer4" CLASS="title">
<DIV CLASS="blur">
ScreamRouter
<AUDIO ID="audio" PRELOAD="metadata" CONTROLS STYLE="display: none;"></audio>
<AUDIO ID="audio" PRELOAD="metadata" CONTROLS STYLE="display: none;"></audio>
<AUDIO ID="audio_visualizer" PRELOAD="metadata" CONTROLS STYLE="display: none;"></audio>
</DIV>
</DIV>
<DIV ID="randomcontainer1" CLASS="section">
<DIV CLASS="blur">
<DIV CLASS="section-name">
Sources
</DIV>
<DIV CLASS="section-buttons select-container">
<INPUT TYPE="range" ID="source_volume" ONCHANGE="source_volume_change()" DISABLED>
{{- buttons.button("add_source_button", "➕", "section-button")}}
{{- buttons.button("add_source_group_button", "Add Group", "section-button")}}
<DIV ID="select-sources" CLASS="main-select" SIZE="{{sources | length}}" ONCHANGE="select_source_change()" MULTIPLE>
{%- set options = namespace(options=[]) %}
{%- for source in sources %}
{{- source.type }}
{%- set enabled_class_str = "enabled" if source.enabled else "disabled" %}
{%- set _option = {"value": source.name,
"label": source.name,
"class": "option option-%s" % enabled_class_str,
"data": source} %}
{%- set options.options = options.options + [_option] %}
{%- endfor %}
{{- selects.make_multiple_options(options.options, sources) }}
</DIV>
</DIV>
</DIV>
</DIV>
<DIV ID="randomcontainer2" CLASS="section">
<DIV CLASS="blur">
<DIV CLASS="section-name">
Routes
</DIV>
<DIV CLASS="section-buttons select-container">
<INPUT TYPE="range" ID="route_volume" ONCHANGE="route_volume_change()" DISABLED>
{{- buttons.button("add_route_button", "➕", "section-button")}}
<DIV ID="select-routes" CLASS="main-select" SIZE="{{routes | length}}" ONCHANGE="select_route_change()" MULTIPLE>
{%- set options = namespace(options=[]) %}
{%- for route in routes %}
{{- route.type }}
{%- set enabled_class_str = "enabled" if route.enabled else "disabled" %}
{%- set _option = {"value": route.name,
"label": "%s [%s->%s]" % (route.name,
route.source,
route.sink),
"class": "option option-%s" % enabled_class_str,
"data": route} %}
{%- set options.options = options.options + [_option] %}
{%- endfor %}
{{- selects.make_multiple_options(options.options, routes) }}
</DIV>
</DIV>
</DIV>
</DIV>
<DIV ID="randomcontainer3" CLASS="section">
<DIV ID="reload">
{%- import "index_body.html.jinja" as index_body %}
{{ index_body.main_body(sources, sinks, routes) }}
</DIV>
<DIV ID="shadow" ONCLICK="dialog_cancel()">
</DIV>
<DIV ID="dialog">
</DIV>
<DIV ID="randomcontainer5">
<div id="mainWrapper" CLASS="section">
<DIV CLASS="blur">
<DIV CLASS="section-name">
Sinks
</DIV>
<DIV CLASS="section-buttons select-container">
<INPUT TYPE="range" ID="sink_volume" ONCHANGE="sink_volume_change()" DISABLED>
{{- buttons.button("add_sink_button", "➕", "section-button")}}
{{- buttons.button("add_sink_group_button", "Add Group", "section-button")}}
<DIV ID="select-sinks" CLASS="main-select" SIZE="{{sinks | length}}" ONCHANGE="select_sink_change()" MULTIPLE>
{%- set options = namespace(options=[]) %}
{%- for sink in sinks %}
{%- set enabled_class_str = "enabled" if sink.enabled else "disabled" %}
{%- set _option = {"value": sink.name,
"label": sink.name,
"class": "option option-%s" % enabled_class_str,
"data": sink} %}
{%- set options.options = options.options + [_option] %}
{%- endfor %}
{{- selects.make_multiple_options(options.options, sinks) }}
</DIV>
</DIV>
</DIV>
</DIV>
<DIV ID="shadow" ONCLICK="dialog_cancel()">
<div id="presetControls">
<div>Preset: <select id="presetSelect" ONCHANGE="presetSelect_change(e)"></select></div>
<div>Cycle:
<input type="checkbox" id="presetCycle" ONCHANGE="presetCycle_change(e)" checked></input>
<input type="number" id="presetCycleLength" step="1" value="15" min="1" ONCHANGE="presetCycleLength_change(e)"></input>
</div>
<div>Random: <input type="checkbox" id="presetRandom" ONCHANGE="presetRandom_change(e)" checked></input></div>
</div>
<canvas id='canvas' width="3840" height="2160" ONCLICK="canvas_click()" tabindex="0" ONKEYDOWN="canvas_onkeydown(event)" >
</canvas>
</div>
</DIV>
<DIV ID="dialog">
</DIV>
</BODY>
</HTML>
</DIV>
</BODY>

</HTML>
46 changes: 39 additions & 7 deletions site/screamrouter.css.jinja
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ DIV#dialog {
height: auto;
top: 12.5%;
margin-left: -16.5%;
background: linear-gradient(-45deg, rgba(0,10,0,.35), rgba(0,200,0,.7));
background: linear-gradient(-45deg, rgba(0,10,0,.15), rgba(0,200,0,.4));
border-radius: 30px;
display: none;
backdrop-filter: blur(5px);
Expand All @@ -34,7 +34,7 @@ DIV.title {
width: 100%;
overflow: hidden;
border-collapse: collapse;
background-color: #004400;
background-color: rgba(00,120,00,.2);
border-radius: 25px;
background-size: 60vmin 60vmin;
display: inline-block;
Expand All @@ -44,7 +44,7 @@ DIV.title {
DIV.section {
overflow: hidden;
border-collapse: collapse;
background-color: #004400;
background-color: rgba(00,120,00,.2);
border-radius: 25px;
background-size: 60vmin 60vmin;
width: 33%;
Expand Down Expand Up @@ -81,7 +81,7 @@ SELECT.main-select {
margin-left: -1%;
background:none;
width: 101%;
background-image: linear-gradient(rgba(60,221,90,.75),rgba(153,153,255,.75));
background-image: linear-gradient(rgba(60,221,90,.45),rgba(153,153,255,.45));
overflow: hidden;
padding-left: 2%;
font-size: 1.25vw;
Expand All @@ -96,7 +96,7 @@ DIV.main-select {
margin-left: -1%;
background:none;
width: 101%;
background-image: linear-gradient(rgba(60,221,90,.75),rgba(153,153,255,.75));
background-image: linear-gradient(rgba(60,221,90,.45),rgba(153,153,255,.45));
overflow: hidden;
padding-left: 2%;
font-size: 1.25vw;
Expand Down Expand Up @@ -128,12 +128,14 @@ option:active, option:focus, option:hover, option:checked:after {


HTML, BODY {
height: 99%;
height: 100%;
background-color: #000100;
font-family: "Arial";
user-select: none; /* Standard */
overflow: auto;
text-align: center;
position: relative;
z-index: -500;
}


Expand Down Expand Up @@ -163,8 +165,16 @@ DIV#randomcontainer4 {
border-radius: 25px;
}

DIV#randomcontainer5 {
background-image: {% for i in range(0, 30) %}radial-gradient(rgba({{ range(0, 10) | random}}, {{ range(40, 255) | random}}, {{ range(0, 10) | random}}, {{ range(0, 250) | random}}) {{ range(0, 20) | random}}%, transparent 0), {% endfor %}radial-gradient(#{{ "%02X" | format(range(0,45) | random | int) }}{{ "%02X" | format(range(0,150) | random | int) }}{{ "%02X" | format(range(0,45) | random | int) }} {{ range(0, 30) | random}}%, transparent 0);
background-position: {% for i in range(0, 30) %}{{ range(0, 250) | random}}% {{ range(0, 250) | random}}%, {% endfor %}{{ range(0, 250) | random}}% {{ range(0, 250) | random}}%;
overflow: hidden;
border-radius: 25px;
float: left;
}

DIV.blur {
backdrop-filter: blur(30px);
backdrop-filter: blur(15px);
height: 100%;
width: 100%;
border-collapse: collapse;
Expand Down Expand Up @@ -325,4 +335,26 @@ SELECT.main-select OPTION[DATA-TYPE="SinkDescription"].option-disabled::before {

SPAN.option-label {
overflow: visible;
}

DIV#presetControls {
padding-top: 15px;
color: #000000;
font-size: 14pt;
text-shadow: 0 0 20px #fff, 0 0 30px #AA7777, 0 0 40px #AA7777, 0 0 50px #AA7777, 0 0 60px #AA7777, 0 0 70px #AA7777, 0 0 80px #AA7777;
text-align: left;
}

DIV#mainWrapper {
display: none;
left: 0px;
top: 0px;
width: 100%;
}

canvas#canvas {
bottom: 0px;
margin-bottom: -5px;
width: 720px;
height: 480px;
}
Loading

0 comments on commit 663ac8a

Please sign in to comment.