Compare commits

...

20 Commits
v0.0.2 ... main

Author SHA1 Message Date
Martyn 762b8f81ca Merge remote-tracking branch 'origin/main' into main
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/tag Build is passing Details
2020-11-01 17:32:36 +01:00
Martyn 3fd5fd0b70 New Feature: Song list!
Also build fix, and lots of other fixes.
2020-11-01 17:30:44 +01:00
Martyn 09e69ba7b8 Merge pull request 'Configure Renovate' (#2) from renovate/configure into main
Reviewed-on: #2
2020-10-12 22:09:43 +00:00
Renovate Bot 5bd2594990 Add renovate.json 2020-10-12 22:02:32 +00:00
Martyn 62800253d8 Look at other cluster
continuous-integration/drone/push Build is passing Details
2020-10-09 16:50:27 +02:00
Martyn 0f525f04bd Newer drone needs kubernetes
continuous-integration/drone/push Build is failing Details
2020-10-09 16:46:54 +02:00
Martyn 54626c9f08 More mastodon stuff
continuous-integration/drone/push Build was killed Details
2020-10-09 12:19:56 +02:00
Martyn d480f43f63 Fix ci
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/tag Build is passing Details
2020-09-27 23:11:30 +02:00
Martyn f75a008f5a Source assets
continuous-integration/drone/push Build is failing Details
2020-09-27 23:09:13 +02:00
Martyn 6f6d64fcd8 Fix sliders
continuous-integration/drone/tag Build is failing Details
2020-09-27 23:08:34 +02:00
Martyn 4f97d9bc47 Initial work on Mastodon API stuff
continuous-integration/drone/tag Build is failing Details
continuous-integration/drone/push Build is failing Details
2020-09-27 22:58:03 +02:00
Martyn bdb53d763a Delay possible for each track
continuous-integration/drone/push Build is failing Details
2020-09-26 14:59:15 +02:00
Martyn c1b696d8cc Ask the server to quit itself
continuous-integration/drone/push Build is failing Details
2020-09-26 13:16:01 +02:00
Martyn 5725eaf8a7 Two seconds is plenty of time. 2020-09-26 13:15:19 +02:00
Martyn f431336f8d Hide Ugly Windows Terminal Window and allow for quit signal remotely
continuous-integration/drone/push Build is failing Details
2020-09-26 12:56:08 +02:00
Martyn 9948a9fc26 Settings and Multi-layer
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/tag Build is passing Details
Had to implement multi-layer playback for duet playback, so
why not implement multi-local-layer recording?
2020-09-26 00:38:08 +02:00
Martyn e1dc2d2be6 Settings page, globals stored to config file
continuous-integration/drone/push Build is passing Details
2020-09-25 20:55:30 +02:00
Martyn 2f73aa671e Plinky sound for audio test on settings page
Source: https://freesound.org/people/ani_music/sounds/165316/
2020-09-25 20:54:25 +02:00
Martyn 6b61262f44 Include duration in the download status
continuous-integration/drone/push Build is passing Details
2020-09-25 20:53:31 +02:00
Martyn 27bf8b453a Sync actually works. Gobsmacked. Next: seeking.
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/tag Build is passing Details
2020-09-24 23:00:40 +02:00
72 changed files with 2845 additions and 53 deletions

287
assets/duetnoteslyrics.svg Normal file
View File

@ -0,0 +1,287 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Creator: CorelDRAW X5 -->
<svg
xmlns:i="http://ns.adobe.com/AdobeIllustrator/10.0/"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
style="clip-rule:evenodd;fill-rule:evenodd;image-rendering:optimizeQuality;shape-rendering:geometricPrecision;text-rendering:geometricPrecision"
xml:space="preserve"
viewBox="0 0 4000 4000"
version="1.1"
id="svg837"
sodipodi:docname="duetnoteslyrics.svg"
inkscape:version="0.92.5 (2060ec1f9f, 2020-04-08)"
width="4000"
height="4000"><sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="2560"
inkscape:window-height="1377"
id="namedview839"
showgrid="false"
inkscape:zoom="0.096743465"
inkscape:cx="-5533.2293"
inkscape:cy="5250.1841"
inkscape:window-x="2552"
inkscape:window-y="1072"
inkscape:window-maximized="1"
inkscape:current-layer="svg837"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0" />
<defs
id="defs830">
<style
type="text/css"
id="style828">
.fil0 {fill:black}
</style>
</defs>
<g
id="Layer_x0020_1"
transform="translate(383.07114,136.99379)">
<path
class="fil0"
d="M 1714,2044 C 1714,1454 1330,976 857,976 384,976 0,1454 0,2044 c 0,92 384,167 857,167 473,0 857,-75 857,-167 z M 857,0 c 258,0 467,209 467,467 0,258 -209,467 -467,467 C 599,934 390,725 390,467 390,209 599,0 857,0 Z"
id="path832"
inkscape:connector-curvature="0"
style="fill:#000000" />
</g>
<metadata
id="metadata835"><rdf:RDF><cc:Work><dc:format>image/svg+xml</dc:format><dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><cc:license
rdf:resource="http://creativecommons.org/publicdomain/zero/1.0/" /><dc:publisher><cc:Agent
rdf:about="http://openclipart.org/"><dc:title>Openclipart</dc:title></cc:Agent></dc:publisher><dc:title></dc:title></cc:Work><cc:License
rdf:about="http://creativecommons.org/publicdomain/zero/1.0/"><cc:permits
rdf:resource="http://creativecommons.org/ns#Reproduction" /><cc:permits
rdf:resource="http://creativecommons.org/ns#Distribution" /><cc:permits
rdf:resource="http://creativecommons.org/ns#DerivativeWorks" /></cc:License></rdf:RDF></metadata><g
transform="matrix(10.176514,0,0,10.176514,-2647.2254,1460.5477)"
inkscape:label="Layer 1"
id="layer1"><g
id="g3941"><g
id="g3675"><path
d="m 291.68135,174.49459 c 31.703,-22.41099 64.34217,-65.17177 96.89565,-52.84759 14.74318,5.58151 5.33002,37.08446 20,42.857 19.34757,7.61314 47.39366,-2.33559 72.22462,-15.44699"
style="fill:none;stroke:#000000;stroke-width:1px"
sodipodi:nodetypes="cssc"
id="path2816"
inkscape:connector-curvature="0" /><path
d="m 291.78301,184.15651 c 31.67476,-22.42629 63.91307,-64.6155 96.43699,-52.30251 14.74318,5.58151 5.33002,37.08446 20,42.857 19.70452,7.7536 48.43146,-2.70865 73.59558,-16.1758"
style="fill:none;stroke:#000000;stroke-width:1px"
sodipodi:nodetypes="cssc"
id="path2816-9"
inkscape:connector-curvature="0" /><path
d="m 291.71813,194.70229 c 32.01462,-22.22966 64.33613,-65.29299 97.21587,-52.84529 14.74318,5.58151 5.33002,37.08446 20,42.857 19.7367,7.76626 48.52532,-2.74288 73.71885,-16.24181"
style="fill:none;stroke:#000000;stroke-width:1px"
sodipodi:nodetypes="cssc"
id="path2816-7"
inkscape:connector-curvature="0" /><path
d="m 291.0798,206.78971 c 31.98988,-22.2449 64.28637,-65.2306 97.1402,-52.79271 14.74318,5.58151 5.33002,37.08446 20,42.857 20.18416,7.94234 49.83536,-3.22879 75.42671,-17.16438"
style="fill:none;stroke:#000000;stroke-width:1px"
sodipodi:nodetypes="cssc"
id="path2816-5"
inkscape:connector-curvature="0" /><path
d="m 291.14,217.19 c 31.53799,-22.49773 63.98524,-64.02179 96.366,-51.763 14.74318,5.58151 5.33002,37.08446 20,42.857 20.60023,8.10606 51.04942,-3.94792 76.9916,-18.28"
style="fill:none;stroke:#000000;stroke-width:1px"
sodipodi:nodetypes="cssc"
id="path2816-54"
inkscape:connector-curvature="0" /></g><g
transform="matrix(0.96741,-0.25321,0.25321,0.96741,-19.363,15.795)"
id="g3733"><ellipse
transform="matrix(0.80217,0.27436,0.24665,-0.89229,191.08,342.3)"
style="color:#000000;fill:#000000"
id="path2874-4"
cx="150.35715"
cy="197.36218"
rx="8.9285717"
ry="5.7142859" /><path
d="m 354.12,204.69 -14.028,41.671 c 17.229,-6.2125 14.629,-7.4468 14.543,-18.641 7.7854,15.797 -1.695,16.744 -14.702,18.775"
style="fill:#000000;stroke:#000000;stroke-width:1.39999998;stroke-linecap:round;stroke-linejoin:round"
sodipodi:nodetypes="cccc"
id="path3684-88"
inkscape:connector-curvature="0" /></g><g
transform="translate(195.16,-91.314)"
id="g3823"><ellipse
transform="matrix(0.78619,0,0,0.83335,127.4,129.94)"
style="color:#000000;fill:#000000"
id="path2874-8"
cx="150.35715"
cy="197.36218"
rx="8.9285717"
ry="5.7142859" /><ellipse
transform="matrix(0.78619,0,0,0.83335,147.61,122.89)"
style="color:#000000;fill:#000000"
id="path2874-8-2"
cx="150.35715"
cy="197.36218"
rx="8.9285717"
ry="5.7142859" /><path
d="m 251.77,294.21 -2.1351,-35.293 20.827,-5.2223 -20.212,6.5279 19.619,-5.0358 2.1233,31.715"
style="fill:none;stroke:#000000;stroke-width:1.70000005"
sodipodi:nodetypes="cccccc"
id="path3800"
inkscape:connector-curvature="0" /></g><g
transform="matrix(-0.84355,0,0,-0.88405,541.16,423.06)"
id="g3823-1"><ellipse
transform="matrix(0.78619,0,0,0.83335,127.4,129.94)"
style="color:#000000;fill:#000000"
id="path2874-8-1"
cx="150.35715"
cy="197.36218"
rx="8.9285717"
ry="5.7142859" /><ellipse
transform="matrix(0.78619,0,0,0.83335,147.61,122.89)"
style="color:#000000;fill:#000000"
id="path2874-8-2-0"
cx="150.35715"
cy="197.36218"
rx="8.9285717"
ry="5.7142859" /><path
d="m 251.62,294.51 -1.9852,-35.593 20.675,-5.2223 -20.059,6.5279 19.619,-5.0358 2.2498,32.151"
style="fill:none;stroke:#000000;stroke-width:1.96860003"
sodipodi:nodetypes="cccccc"
id="path3800-3"
inkscape:connector-curvature="0" /></g><path
d="M 291.10277,217.59952 291.8709,174.067"
style="fill:none;stroke:#000000;stroke-width:1px"
id="path3881"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" /><path
d="m 481.00968,148.65141 3.48792,41.67857"
style="fill:none;stroke:#000000;stroke-width:1px"
sodipodi:nodetypes="cc"
id="path3917"
inkscape:connector-curvature="0" /><path
d="m 345.57,136.85 c 4.9886,4.568 4.0714,9.4869 4.4538,10.103 l 7.8975,3.895 c -11.357,-2.5808 -8.029,9.8877 1.3513,12.421 -9.5726,-10.73 -5.6408,-8.0368 0.86038,-12.08 -6.5385,-5.5984 -2.3748,-9.3138 -4.4455,-10.429 l -10.118,-3.9094 h 5e-5 z"
style="fill:#000000"
sodipodi:nodetypes="cccccccc"
id="path3931"
inkscape:connector-curvature="0" /><g
transform="translate(54.61,-59.086)"
id="g3937"><path
d="m 367.64,233.4 c -4.9555,2.4597 -7.9704,-2.1826 -9.3032,-2.8985 -1.294,-0.69507 -3.2452,1.4315 -3.3192,2.8985 -0.0667,1.3213 0.98646,3.2708 2.431,3.366 6.3801,-0.69042 10.35,-2.6032 17.204,-8.789 l -17.484,38.054"
style="fill:none;stroke:#000000;stroke-width:1px"
sodipodi:nodetypes="cssccc"
id="path3933"
inkscape:connector-curvature="0" /><path
d="m 356.9,236.17 c -0.73798,-0.4419 -1.3609,-1.4449 -1.4732,-2.3721 -0.16636,-1.3734 1.5082,-3.3844 2.5887,-3.1088 0.12842,0.0327 0.74267,0.49725 1.365,1.0322 1.9995,1.7188 3.2228,2.4456 4.6869,2.7848 l 0.80015,0.18539 -0.92276,0.3236 c -1.3319,0.46708 -3.1146,0.90153 -4.6608,1.1358 -1.6636,0.25211 -1.9904,0.25473 -2.384,0.019 z"
style="color:#000000;fill:#000000"
id="path3935"
inkscape:connector-curvature="0" /></g></g></g><g
id="g1016"
transform="translate(83.309279,33.627631)"><switch
transform="matrix(9.1058381,0,0,9.1058381,1994.57,2186.6803)"
id="switch953">
<foreignObject
y="0"
x="0"
height="1"
width="1"
requiredExtensions="http://ns.adobe.com/AdobeIllustrator/10.0/">
</foreignObject>
<g
i:extraneous="self"
id="g951">
<g
style="clip-rule:evenodd;fill-rule:evenodd"
id="g949">
<path
style="fill:#ffffff"
inkscape:connector-curvature="0"
d="M 166.38,132.42 56.85,148.6 H 56.7 v 0.2 C 49.067,159 45.266,170.617 45.3,183.651 v 0.3 c 0.034,1.6 0.067,3.233 0.1,4.899 C 39.9,148.25 34.417,107.651 28.95,67.05 27.717,51.783 31.483,38.367 40.25,26.8 v 0.05 l 114.05,-16.8 17.3,121.65 -4.199,0.55 c -0.014,-0.068 -0.047,-0.135 -0.101,-0.2 -0.091,-0.112 -0.208,-0.179 -0.35,-0.2 -0.13,-0.018 -0.247,0.016 -0.351,0.101 -0.112,0.091 -0.179,0.208 -0.199,0.35 0,0.04 -0.01,0.08 -0.02,0.12 z M 40.25,26.85 56.7,148.6 Z"
id="path927" />
<linearGradient
id="SVGID_1_"
y2="139.28"
gradientUnits="userSpaceOnUse"
x2="-603.57001"
gradientTransform="matrix(-0.1058,-0.9944,0.9919,-0.1289,-100.9,-468.66)"
y1="139.28"
x1="-663.60999">
<stop
style="stop-color:#FFFFFF"
offset="0"
id="stop929" />
<stop
style="stop-color:#000000"
offset="1"
id="stop931" />
</linearGradient>
<path
style="fill:url(#SVGID_1_)"
inkscape:connector-curvature="0"
d="m 158.12,164.15 c -0.033,-0.115 -0.074,-0.232 -0.125,-0.351 l 0.025,0.025 c -0.061,-0.155 -0.094,-0.264 -0.101,-0.325 0.073,-0.026 0.206,-0.026 0.4,0 l -0.2,0.65 z m 1.23,-4.35 -0.6,2.15 -0.15,0.55 c -0.034,0.004 -0.068,0.004 -0.1,0 -0.672,-0.07 -1.113,0.047 -1.325,0.35 -0.31,0.264 -0.343,0.706 -0.1,1.325 l 0.024,0.025 c 0.273,0.674 0.24,1.391 -0.1,2.149 -0.062,0.125 -0.07,0.25 -0.025,0.375 0.054,0.128 0.146,0.22 0.275,0.275 0.018,0.008 0.033,0.017 0.05,0.025 l -0.2,0.675 -111.81,16.25 v -0.3 c -0.033,-13.03 3.767,-24.65 11.4,-34.85 l 0.1,0.3 -0.1,-0.3 c 0.066,-0.066 0.117,-0.134 0.15,-0.2 l 109.52,-16.175 c -0.154,1.298 -0.18,2.007 -0.075,2.125 h -0.024 c -0.359,-0.112 -0.877,0.188 -1.551,0.9 v 0.024 c -0.574,0.639 -0.783,1.438 -0.625,2.4 0.129,0.795 0.196,1.32 0.2,1.575 0.001,0.137 0.052,0.253 0.15,0.35 0.097,0.099 0.213,0.149 0.35,0.15 0.05,-0.001 0.099,-0.009 0.15,-0.025 l -0.101,0.375 -0.024,-0.024 c -0.108,-0.092 -0.233,-0.134 -0.375,-0.125 -0.132,0.011 -0.24,0.068 -0.325,0.175 -0.092,0.108 -0.134,0.233 -0.125,0.375 0.02,0.375 -0.089,0.884 -0.325,1.524 -0.267,0.75 -0.501,1.517 -0.7,2.301 -0.177,0.703 -0.469,1.261 -0.875,1.675 l -0.024,0.024 c -0.548,0.625 -0.739,1.334 -0.575,2.125 l 0.025,0.025 c 0.138,0.586 0.088,1.262 -0.15,2.025 -0.218,0.732 -0.359,1.149 -0.425,1.25 -0.112,0.082 -0.179,0.189 -0.2,0.324 -0.018,0.139 0.016,0.264 0.1,0.375 0.082,0.113 0.19,0.18 0.325,0.2 0.081,0.011 0.156,0.003 0.226,-0.024 l -0.11,0.38 c -0.081,-0.09 -0.182,-0.141 -0.3,-0.15 -0.141,-0.009 -0.266,0.033 -0.375,0.125 -0.105,0.084 -0.164,0.192 -0.175,0.325 -0.066,0.806 -0.1,1.239 -0.101,1.3 -0.509,-0.021 -0.859,0.571 -1.05,1.775 v 0.024 c -0.104,0.897 -0.104,1.88 0,2.95 v 0.025 c 0.03,0.17 0.05,0.35 0.06,0.52 z m 5.9,-20.98 c -0.03,-0.291 -0.08,-0.657 -0.15,-1.101 -0.107,-0.638 0.018,-1.171 0.375,-1.6 v 0.025 c 0.331,-0.359 0.548,-0.559 0.65,-0.601 l -0.05,-0.024 c 0.038,0.012 0.071,0.02 0.1,0.024 l -0.93,3.28 z m -2.7,9.66 c -0.021,-0.12 -0.046,-0.236 -0.075,-0.35 l 0.025,0.025 c -0.1,-0.464 0,-0.881 0.3,-1.25 l 0.025,-0.025 c 0.089,-0.09 0.172,-0.181 0.25,-0.275 l -0.52,1.88 z m -2.25,8 c -0.003,-0.023 -0.003,-0.049 0,-0.074 0.079,-0.537 0.13,-0.838 0.15,-0.9 0.043,0.002 0.085,0.002 0.125,0 l -0.28,0.97 z"
id="path934" />
<linearGradient
id="SVGID_2_"
y2="88.695"
gradientUnits="userSpaceOnUse"
x2="-572.71002"
gradientTransform="matrix(-0.1133,-0.9936,0.9908,-0.1379,-103.08,-470.12)"
y1="88.695"
x1="-675.34003">
<stop
style="stop-color:#FFFFFF"
offset="0"
id="stop936" />
<stop
style="stop-color:#000000"
offset="1"
id="stop938" />
</linearGradient>
<path
style="fill:url(#SVGID_2_)"
inkscape:connector-curvature="0"
d="m 56.85,148.6 c -0.033,0.066 -0.083,0.134 -0.15,0.2 v -0.2 z"
id="path941" />
<polygon
style="fill:#ffffcc"
points="45.45,189.4 45.4,189.3 45.45,189.3 "
id="polygon943" />
<path
inkscape:connector-curvature="0"
d="m 166.38,132.42 c 0.012,-0.04 0.02,-0.082 0.025,-0.125 0.021,-0.142 0.087,-0.259 0.199,-0.35 0.104,-0.085 0.221,-0.118 0.351,-0.101 0.142,0.021 0.259,0.088 0.35,0.2 0.054,0.065 0.087,0.132 0.101,0.2 0.006,0.052 0.006,0.102 0,0.15 -0.264,2.129 -0.672,3.18 -1.226,3.149 -0.028,-0.005 -0.062,-0.013 -0.1,-0.024 l 0.05,0.024 c -0.103,0.042 -0.319,0.241 -0.65,0.601 v -0.025 c -0.357,0.429 -0.482,0.962 -0.375,1.6 0.07,0.443 0.12,0.81 0.15,1.101 0.035,0.279 0.053,0.487 0.05,0.625 -0.001,0.137 -0.051,0.253 -0.149,0.35 -0.063,0.063 -0.129,0.105 -0.2,0.125 -0.052,0.017 -0.101,0.024 -0.15,0.025 -0.137,-0.001 -0.253,-0.052 -0.35,-0.15 -0.099,-0.097 -0.149,-0.213 -0.15,-0.35 -0.004,-0.255 -0.071,-0.78 -0.2,-1.575 -0.158,-0.963 0.051,-1.762 0.625,-2.4 v -0.024 c 0.674,-0.713 1.191,-1.013 1.551,-0.9 h 0.024 c -0.09,-0.11 -0.07,-0.82 0.09,-2.12 z m -5.08,20.48 0.025,0.024 c 0.092,0.11 0.134,0.235 0.125,0.375 -0.126,1.368 -0.417,2.103 -0.875,2.2 -0.04,0.002 -0.082,0.002 -0.125,0 -0.021,0.063 -0.071,0.363 -0.15,0.9 -0.003,0.025 -0.003,0.051 0,0.074 -0.093,0.812 -0.093,1.695 0,2.65 0.138,1.08 0.171,2.037 0.101,2.875 -0.063,0.955 -0.538,1.463 -1.426,1.525 -0.178,0.006 -0.369,-0.002 -0.574,-0.025 -0.029,-0.004 -0.055,-0.004 -0.075,0 -0.194,-0.026 -0.327,-0.026 -0.4,0 0.007,0.062 0.04,0.17 0.101,0.325 l -0.02,-0.02 c 0.051,0.118 0.092,0.235 0.125,0.351 0.252,0.825 0.177,1.691 -0.225,2.6 -0.057,0.129 -0.147,0.221 -0.275,0.275 -0.108,0.038 -0.217,0.038 -0.325,0 -0.017,-0.009 -0.032,-0.018 -0.05,-0.025 -0.13,-0.056 -0.222,-0.147 -0.275,-0.275 -0.045,-0.125 -0.036,-0.25 0.025,-0.375 0.34,-0.759 0.373,-1.476 0.1,-2.149 l -0.024,-0.025 c -0.243,-0.619 -0.21,-1.062 0.1,-1.325 0.212,-0.303 0.653,-0.42 1.325,-0.35 0.031,0.004 0.065,0.004 0.1,0 0.08,0.01 0.155,0.01 0.226,0 0.339,-0.045 0.53,-0.244 0.575,-0.6 0.051,-0.627 0.034,-1.326 -0.051,-2.101 -0.01,-0.173 -0.026,-0.348 -0.05,-0.524 v -0.025 c -0.104,-1.07 -0.104,-2.053 0,-2.95 v -0.024 c 0.19,-1.204 0.541,-1.796 1.05,-1.775 0.001,-0.061 0.034,-0.494 0.101,-1.3 0.011,-0.133 0.069,-0.241 0.175,-0.325 0.109,-0.092 0.234,-0.134 0.375,-0.125 0.12,0 0.22,0.05 0.3,0.14 z m 1.78,-6.3 c -0.078,0.095 -0.161,0.186 -0.25,0.275 l -0.03,0.02 c -0.3,0.369 -0.399,0.786 -0.3,1.25 l -0.025,-0.025 c 0.029,0.113 0.055,0.229 0.075,0.35 0.101,0.66 0.026,1.402 -0.225,2.226 -0.316,1.068 -0.575,1.651 -0.775,1.75 -0.046,0.034 -0.097,0.06 -0.149,0.075 -0.069,0.027 -0.145,0.035 -0.226,0.024 -0.135,-0.021 -0.243,-0.087 -0.325,-0.2 -0.084,-0.111 -0.117,-0.236 -0.1,-0.375 0.021,-0.135 0.088,-0.242 0.2,-0.324 0.065,-0.101 0.207,-0.518 0.425,-1.25 0.238,-0.764 0.288,-1.439 0.15,-2.025 l -0.025,-0.025 c -0.164,-0.791 0.027,-1.5 0.575,-2.125 l 0.024,-0.024 c 0.406,-0.414 0.698,-0.972 0.875,-1.675 0.199,-0.784 0.434,-1.551 0.7,-2.301 0.236,-0.641 0.345,-1.149 0.325,-1.524 -0.009,-0.142 0.033,-0.267 0.125,-0.375 0.085,-0.106 0.193,-0.164 0.325,-0.175 0.142,-0.009 0.267,0.033 0.375,0.125 l 0.024,0.024 c 0.09,0.077 0.141,0.178 0.15,0.3 0.047,0.492 -0.078,1.15 -0.375,1.976 -0.266,0.717 -0.5,1.45 -0.7,2.2 -0.18,0.75 -0.46,1.35 -0.84,1.84 z"
id="path945" />
<path
style="fill:none;stroke:#000000;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:3"
inkscape:connector-curvature="0"
d="M 45.4,188.85 C 39.9,148.25 34.417,107.651 28.95,67.05 27.717,51.783 31.483,38.367 40.25,26.8 v 0.05 l 114.05,-16.8 17.3,121.65 -4.199,0.55 m -8.42,31.27 1.275,9.024 -114.06,16.81 -0.75,-0.05 v 0.101 l -0.05,-0.1 v -0.45 m 11.45,-40.25 h -0.15 v 0.2 c 0.067,-0.07 0.117,-0.13 0.15,-0.2 l 109.52,-16.175 m -109.67,16.38 0.1,0.3 m -11.5,34.85 c 0.034,1.6 0.067,3.233 0.1,4.899 m 0,0.45 h 0.05 m -0.15,-5.35 v -0.3 c -0.033,-13.03 3.767,-24.65 11.4,-34.85 m 102.05,13.15 0.075,0.55 m -1.52,4.52 -0.2,0.675 -111.8,16.25 m -5.05,-157.1 16.45,121.75"
stroke-miterlimit="3"
id="path947" />
</g>
</g>
</switch><text
transform="rotate(-8.925618)"
id="text979"
y="3407.6045"
x="1980.4675"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:73.24398041px;line-height:1.25;font-family:MuOnline;-inkscape-font-specification:MuOnline;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:2.74664927"
xml:space="preserve"><tspan
style="font-style:italic;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:263.67831421px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold Italic';stroke-width:2.74664927"
y="3407.6045"
x="1980.4675"
id="tspan977"
sodipodi:role="line">LYRICS</tspan></text>
</g><g
style="clip-rule:evenodd;fill-rule:evenodd;image-rendering:optimizeQuality;shape-rendering:geometricPrecision;text-rendering:geometricPrecision"
id="Layer_x0020_1-1"
transform="translate(1758.7802,146.81254)"><path
inkscape:connector-curvature="0"
class="fil0"
d="M 1714,2044 C 1714,1454 1330,976 857,976 384,976 0,1454 0,2044 c 0,92 384,167 857,167 473,0 857,-75 857,-167 z M 857,0 c 258,0 467,209 467,467 0,258 -209,467 -467,467 C 599,934 390,725 390,467 390,209 599,0 857,0 Z"
id="path832-1"
style="fill:#000000" /></g></svg>

After

Width:  |  Height:  |  Size: 18 KiB

12
assets/pawn.svg Normal file
View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Creator: CorelDRAW X5 -->
<svg xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://www.w3.org/2000/svg" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:ns1="http://sozi.baierouge.fr" xmlns:cc="http://web.resource.org/cc/" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" style="fill-rule:evenodd;text-rendering:geometricPrecision;image-rendering:optimizeQuality;clip-rule:evenodd;shape-rendering:geometricPrecision" xml:space="preserve" viewBox="0 0 1714 2211">
<defs>
<style type="text/css">
.fil0 {fill:black}
</style>
</defs>
<g id="Layer_x0020_1">
<path class="fil0" d="m1714 2044c0-590-384-1068-857-1068s-857 478-857 1068c0 92 384 167 857 167s857-75 857-167zm-857-2044c258 0 467 209 467 467s-209 467-467 467-467-209-467-467 209-467 467-467z"/>
</g>
<metadata><rdf:RDF><cc:Work><dc:format>image/svg+xml</dc:format><dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/><cc:license rdf:resource="http://creativecommons.org/licenses/publicdomain/"/><dc:publisher><cc:Agent rdf:about="http://openclipart.org/"><dc:title>Openclipart</dc:title></cc:Agent></dc:publisher></cc:Work><cc:License rdf:about="http://creativecommons.org/licenses/publicdomain/"><cc:permits rdf:resource="http://creativecommons.org/ns#Reproduction"/><cc:permits rdf:resource="http://creativecommons.org/ns#Distribution"/><cc:permits rdf:resource="http://creativecommons.org/ns#DerivativeWorks"/></cc:License></rdf:RDF></metadata></svg>

After

Width:  |  Height:  |  Size: 1.6 KiB

78
assets/purpleprogress.svg Normal file
View File

@ -0,0 +1,78 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="210mm"
height="297mm"
viewBox="0 0 210 297"
version="1.1"
id="svg8"
inkscape:version="0.92.5 (2060ec1f9f, 2020-04-08)"
sodipodi:docname="purpleprogress.svg">
<defs
id="defs2" />
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="0.7"
inkscape:cx="-390.44542"
inkscape:cy="767.87209"
inkscape:document-units="mm"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:window-width="2560"
inkscape:window-height="1377"
inkscape:window-x="2552"
inkscape:window-y="-8"
inkscape:window-maximized="1" />
<metadata
id="metadata5">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1">
<rect
style="opacity:1;fill:none;fill-opacity:1;stroke:#800080;stroke-width:1.12813807;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="rect815"
width="500"
height="20"
x="-297.08929"
y="23.755953"
ry="4.7435899"
rx="0"
inkscape:export-xdpi="100"
inkscape:export-ydpi="100" />
<rect
rx="0"
ry="4.0320516"
y="25.255953"
x="-295.08929"
height="17"
width="496"
id="rect819"
style="opacity:1;fill:#800080;fill-opacity:1;stroke:none;stroke-width:1.03592324;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
inkscape:export-xdpi="100"
inkscape:export-ydpi="100" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 912 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 73 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 760 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 67 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

@ -1,5 +1,5 @@
kind: pipeline
type: docker
type: kubernetes
name: linux-amd64-taggedver
platform:
@ -13,7 +13,7 @@ steps:
- cd dlserver
- go mod download
- go build .
- CGO_ENABLED=0 GOOS=windows go build -a -installsuffix cgo -o dlserver.exe .
- CGO_ENABLED=0 GOOS=windows go build -ldflags -H=windowsgui -a -installsuffix cgo -o dlserver.exe .
- name: get_win_ffmpeg
image: busybox
@ -21,7 +21,7 @@ steps:
- mkdir -p tmp
- cd tmp
# local cache, local pls
- echo "10.43.14.171 nextcloud.martyn.berlin" >> /etc/hosts
- echo "192.168.1.11 nextcloud.martyn.berlin" >> /etc/hosts
# original url : wget http://www.gyan.dev/ffmpeg/builds/packages/ffmpeg-4.3.1-essentials_build.zip
- wget -O ffmpeg.zip https://nextcloud.martyn.berlin/s/WdHk8sfZ28JXqjH/download
- unzip ffmpeg.zip
@ -31,7 +31,9 @@ steps:
commands:
- mkdir -p tmp
- cd tmp
- wget https://github.com/ytdl-org/youtube-dl/releases/download/2020.09.14/youtube-dl.exe
# riaa getting greedy again : original url : https://github.com/ytdl-org/youtube-dl/releases/download/2020.09.14/youtube-dl.exe
# google took advantage too and broke the 09.14 release, so yeah... arms race now.
- wget -o youtube-dl.exe https://nextcloud.martyn.berlin/s/t59bd4GBaiiqKqb/download
- name: build_godot_windows
image: barichello/godot-ci:3.2.3

View File

@ -26,6 +26,7 @@ func limitLength(s string, length int) string {
// globals, huh, faster than channels and oddly more appropriate, we care less about races than feedback.
var lastPercentage float64
var lastFilename string
var lastDurationSeconds float64
func convertFile(sourceFileName string, destinationFilename string) error {
launch := "./ffmpeg"
@ -35,6 +36,7 @@ func convertFile(sourceFileName string, destinationFilename string) error {
os.Remove(destinationFilename)
DurationRe := regexp.MustCompile(`DURATION *: ([0-9]+):([0-9]+):([0-9]+)\.([0-9]+)`)
OtherDurationRe := regexp.MustCompile(`Duration: ([0-9]+):([0-9]+):([0-9]+)\.([0-9]+)`)
FrameRe := regexp.MustCompile(`frame= ?([0-9]+) `)
FPSValue := 0.0
finalFramesValue := 0.0
@ -61,20 +63,27 @@ func convertFile(sourceFileName string, destinationFilename string) error {
if len(fpses) > 0 {
fmt.Printf("FPS' is %v\n", fpses)
FPSValue, _ = strconv.ParseFloat(fpses[0][1], 64)
fmt.Printf("\nSet fps to %0.2f\n", FPSValue)
if lastDurationSeconds != 0 {
finalFramesValue = lastDurationSeconds * FPSValue
}
}
durations := DurationRe.FindAllStringSubmatch(line, 1)
if len(durations) < 1 {
durations = OtherDurationRe.FindAllStringSubmatch(line, 1)
}
if len(durations) > 0 {
fmt.Printf("Durations is %v\n", durations)
// we have an fps, we can work out max frames!
hrs, _ := strconv.ParseFloat(durations[0][1], 64)
mins, _ := strconv.ParseFloat(durations[0][2], 64)
secs, _ := strconv.ParseFloat(durations[0][3], 64)
aaand, _ := strconv.ParseFloat("0."+durations[0][4], 64)
lastDurationSeconds = (hrs * 60 * 60) + (mins * 60) + secs + aaand
if FPSValue != 0.0 {
// we have an fps, we can work out max frames!
hrs, _ := strconv.ParseFloat(durations[0][1], 64)
mins, _ := strconv.ParseFloat(durations[0][2], 64)
secs, _ := strconv.ParseFloat(durations[0][3], 64)
aaand, _ := strconv.ParseFloat("0."+durations[0][4], 64)
total := (hrs * 60 * 60) + (mins * 60) + secs + aaand
finalFramesValue = total * FPSValue
fmt.Printf("%0f:%0f:%0f%0.4f * %0.2f = %0.2f seconds = %0.2f frames\n", hrs, mins, secs, aaand, FPSValue, total, finalFramesValue)
finalFramesValue = lastDurationSeconds * FPSValue
}
fmt.Printf("%0f:%0f:%0f%0.4f * %0.2f = %0.2f seconds = %0.2f frames\n", hrs, mins, secs, aaand, FPSValue, lastDurationSeconds, finalFramesValue)
}
currentFrames := FrameRe.FindAllStringSubmatch(line, 1)
if len(currentFrames) > 0 {
@ -169,6 +178,10 @@ func downloadFile(sourceURL string, outputFile string, statusChannel chan float6
fmt.Printf(" > Failed with error: %v\n", err)
return err
}
if lastFilename == "" {
// we probably didn't get a merge into a single file, so it probably just streamed to the output without an extension
lastFilename = "test"
}
return convertFile(lastFilename, "converted.webm")
}
@ -190,6 +203,28 @@ func FetchHandler(w http.ResponseWriter, r *http.Request) {
fmt.Fprint(w, "OK\n")
}
func PidHandler(w http.ResponseWriter, r *http.Request) {
//vars := mux.Vars(r)
w.WriteHeader(http.StatusOK)
if lastFilename != "" {
os.Remove(lastFilename)
}
fmt.Fprintf(w, "%d\n", os.Getpid())
}
func QuitHandler(w http.ResponseWriter, r *http.Request) {
//vars := mux.Vars(r)
w.WriteHeader(http.StatusOK)
if lastFilename != "" {
os.Remove(lastFilename)
}
fmt.Fprint(w, "BYE!\n")
go func() {
time.Sleep(2 * time.Second)
os.Exit(0)
}()
}
func StatusHandler(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-type", "application/json")
w.WriteHeader(http.StatusOK)
@ -201,7 +236,7 @@ func StatusHandler(w http.ResponseWriter, r *http.Request) {
lastFilename = <-n
} */
fmt.Printf("Returning %0.2f for %s\n", lastPercentage, lastFilename)
fmt.Fprintf(w, `{"filename": "%s","percentage":%0.2f}`+"\n", lastFilename, lastPercentage)
fmt.Fprintf(w, `{"filename": "%s","percentage":%0.2f,"duration_seconds":%0.6f}`+"\n", lastFilename, lastPercentage, lastDurationSeconds)
}
func main() {
@ -212,6 +247,8 @@ func main() {
r.SkipClean(true)
r.Path("/get").Queries("url", "{.*}").HandlerFunc(FetchHandler)
r.HandleFunc("/status/", StatusHandler)
r.HandleFunc("/pid/", PidHandler)
r.HandleFunc("/quit/", QuitHandler)
r.HandleFunc("/", HomeHandler)
http.Handle("/", r)
c = make(chan float64, 999)

View File

@ -0,0 +1,145 @@
extends Node
# Declare member variables here. Examples:
# var a = 2
# var b = "text"
var SongTitle = ""
var SongArtist = ""
var CompletionType
var Tags = ""
var OriginalURL = ""
var PartsURLs = []
var PartsVolumes = []
var PartsDelays = []
var PartsOthers = []
var BackVolume = 0
enum CompletionTypeOptions {
OpenSeed,
SoloCompletion,
DuetCompletion,
AllHarmony,
AllMelody
}
# Called when the node enters the scene tree for the first time.
func _ready():
print(unBundle("""Hey, I sang part of Don't Give Up by Peter Gabriel at https://no.where and it's not complete until you sing the rest of it with me!
With #ASingCrow, you can join it and other songs.
The audio track(s) are attached.
Backing volume recommendation: 1db.
Parts volume recommendations: 40db, 40db.
Audio delay recommendations: 0.166s
#test #ignore
"""))
pass # Replace with function body.
func setSongTitle(value):
SongTitle = value
func setSongArtist(value):
SongArtist = value
func setCompletionType(value):
CompletionType = value
func setTags(value):
Tags = value
func setOriginalURL(value):
OriginalURL = value
func setPartsURLs(value):
PartsURLs = value
func setPartsVolumes(value):
PartsVolumes = value
func setPartsDelays(value):
PartsDelays = value
func setBackVolume(value):
BackVolume = value
func getFinalText():
var completiontext = ""
var partof = ""
var i = 0
match CompletionType :
CompletionTypeOptions.OpenSeed:
completiontext = " and it's not complete until you sing the rest of it with me!"
partof = "part of "
CompletionTypeOptions.SoloCompletion:
completiontext = " let me know what you think!"
CompletionTypeOptions.DuetCompletion:
completiontext = " with "+PartsOthers+" and it sounds great, don't you think!?"
CompletionTypeOptions.AllHarmony:
partof = "only the harmonies of "
completiontext = " and would love someone to put the melody on top!"
CompletionTypeOptions.AllMelody:
partof = "only the melody of "
completiontext = " and would love someone to put some harmonies underneath!"
var partstext = "The audio track(s) are attached"
if len(PartsURLs) > 0:
partstext = "The audio track urls are :"
for parturl in PartsURLs:
partstext += " "+parturl
partstext += ".\n"
var volumetext = "Backing volume recommendation: "+String(BackVolume)+"db.\nParts volume recommendations: "
i = 0
for partvolume in PartsVolumes:
volumetext += String(partvolume)+"db"
if len(PartsVolumes) > i+1:
volumetext += ", "
i += 1
volumetext += ".\n"
var partdelaytext = "Audio delay recommendations: "
i = 0
for partDelay in PartsDelays:
partdelaytext += String(partDelay)+"s"
if len(PartsDelays) > i+1:
partdelaytext += ", "
return "Hey, I sang "+partof+SongTitle+" by "+SongArtist+" at "+OriginalURL+completiontext+" "+\
"\nWith #ASingCrow, you can join it and other songs.\n"+partstext+volumetext+partdelaytext+"\n"+Tags
func unBundle(text):
var result = {}
var regex = RegEx.new()
regex.compile("(part of|only the (?<parttype>\\w) of) (?<trackname>.+) by (?<originalartist>.+) at (?<trackurl>[^ ]*) (and[^!]*!|let[^!]*!|with[^!]*!)")
var search = regex.search(text)
result.parttype = search.get_string("parttype")
result.trackname = search.get_string("trackname")
result.originalartist = search.get_string("originalartist")
result.trackurl = search.get_string("trackurl")
regex.compile("(?<embeddedaudio>audio track(s|\\(s\\))? are attached)|audio track urls are : (?<trackurls>.*)")
search = regex.search(text)
if search.get_string("embeddedaudio"):
result.embeddedaudio = true
else:
result.embeddedaudio = false
regex.compile("Backing volume recommendation: (?<mainvol>[^d]+)db")
search = regex.search(text)
result.mainvol = search.get_string("mainvol")
regex.compile("Parts volume recommendations: (?<partvol>([^d]+db(, )?)+)")
search = regex.search(text)
var partsstr = search.get_string("partvol")
regex.compile("(?<db>[\\d\\.]+)db")
search = regex.search_all(partsstr)
var partvols = []
for each in search:
partvols.append(each.get_string("db"))
result.partvols = partvols
regex.compile("Audio delay recommendations: (?<partsdelays>([\\d\\.]+s(, )?)+)")
search = regex.search(text)
partsstr = search.get_string("partsdelays")
regex.compile("(?<seconds>[\\d\\.]+)s")
search = regex.search_all(partsstr)
var partsdelays = []
for each in search:
partsdelays.append(each.get_string("seconds"))
result.partsdelays = partsdelays
return result
# Called every frame. 'delta' is the elapsed time since the previous frame.
#func _process(delta):
# pass

View File

@ -0,0 +1,25 @@
extends Control
signal on_cancel
signal on_authorize(code)
# Declare member variables here. Examples:
# var a = 2
# var b = "text"
# Called when the node enters the scene tree for the first time.
func _ready():
pass # Replace with function body.
# Called every frame. 'delta' is the elapsed time since the previous frame.
#func _process(delta):
# pass
func _on_Button2_pressed():
emit_signal("on_cancel")
func _on_Button_pressed():
emit_signal("on_authorize",$VBoxContainer/LineEdit.text)

View File

@ -0,0 +1,55 @@
[gd_scene load_steps=2 format=2]
[ext_resource path="res://Components/MastoAuthCode.gd" type="Script" id=1]
[node name="Control" type="Control"]
anchor_right = 1.0
anchor_bottom = 1.0
script = ExtResource( 1 )
__meta__ = {
"_edit_use_anchors_": false
}
[node name="Button2" type="Button" parent="."]
anchor_left = 1.0
anchor_right = 1.0
margin_left = -71.0
margin_top = 10.0
margin_right = -17.0
margin_bottom = 30.0
text = "Cancel"
__meta__ = {
"_edit_use_anchors_": false
}
[node name="VBoxContainer" type="VBoxContainer" parent="."]
anchor_top = 0.5
anchor_right = 1.0
anchor_bottom = 0.5
margin_top = -33.0
__meta__ = {
"_edit_use_anchors_": false
}
[node name="Label" type="Label" parent="VBoxContainer"]
margin_right = 1024.0
margin_bottom = 14.0
text = "Launched an authorisation request in your system's browser, please note down the code and enter it in the box below to continue"
align = 1
valign = 1
[node name="LineEdit" type="LineEdit" parent="VBoxContainer"]
margin_top = 18.0
margin_right = 1024.0
margin_bottom = 42.0
[node name="Button" type="Button" parent="VBoxContainer"]
margin_top = 46.0
margin_right = 1024.0
margin_bottom = 66.0
text = "Authorize"
__meta__ = {
"_edit_use_anchors_": false
}
[connection signal="pressed" from="Button2" to="." method="_on_Button2_pressed"]
[connection signal="pressed" from="VBoxContainer/Button" to="." method="_on_Button_pressed"]

View File

@ -0,0 +1,127 @@
extends Control
var ca_request
var auth_request
var toot_request
# Called when the node enters the scene tree for the first time.
func _ready():
Globals.loadConfig()
if len(Globals.providers.mastodon) > 0:
if Globals.providers.mastodon[0].has("baseURL"):
print("Setting base url")
$VBoxContainer/HBoxContainer/TextEdit.text = Globals.providers.mastodon[0].baseURL
if Globals.providers.mastodon[0].has("oauth_token"):
print("Already Registered")
$VBoxContainer/AuthUser.disabled = true
# Called every frame. 'delta' is the elapsed time since the previous frame.
#func _process(delta):
# pass
func _on_Login_pressed():
if len(Globals.providers.mastodon) == 0:
Globals.providers.mastodon = {}
if !Globals.providers.mastodon[0].has("app_client_id"):
register_app()
if !Globals.providers.mastodon[0].has("oauth_token"):
auth_user()
func register_app():
var headers = ["Content-Type: application/json"]
var data = {
"client_name": "ASingCrow",
"redirect_uris": "urn:ietf:wg:oauth:2.0:oob",
"scopes": "read write follow push",
"website": "https://asingcrow.martyn.berlin"
}
ca_request = HTTPRequest.new()
add_child(ca_request)
ca_request.connect("request_completed",self,"_on_app_created")
ca_request.request("https://toot.martyn.berlin/api/v1/apps",headers,true,HTTPClient.METHOD_POST,JSON.print(data))
func _on_app_created(result, response_code, headers, body):
print("Response...")
if response_code != 200:
print("PANIC! got "+String(response_code))
print(body.get_string_from_utf8)
return
var response = parse_json(body.get_string_from_utf8())
var dict = {
"app_client_id": response.client_id,
"app_client_secret": response.client_secret }
Globals.providers.mastodon.append(dict)
Globals.saveConfig()
remove_child(ca_request)
func _on_token_requested(result, response_code, headers, body):
print("Response...")
if response_code != 200:
print("PANIC! got "+String(response_code))
print(body.get_string_from_utf8())
return
var response = parse_json(body.get_string_from_utf8())
Globals.providers.mastodon[0].oauth_token = response.access_token
Globals.saveConfig()
remove_child(auth_request)
pass
func _on_Button3_pressed():
var client = Globals.providers.mastodon
var headers = ["Content-Type: application/json",
"Authorization: Bearer "+client[0].oauth_token]
var data = {
"status": "Test toot",
}
toot_request = HTTPRequest.new()
add_child(toot_request)
toot_request.connect("request_completed",self,"_on_tooted")
toot_request.request("https://toot.martyn.berlin/api/v1/statuses",headers,true,HTTPClient.METHOD_POST,JSON.print(data))
print("Headers: ")
print(headers)
print("Sending...")
print(JSON.print(data))
func _on_tooted(result, response_code, headers, body):
if response_code != 200:
print("PANIC! got "+String(response_code))
print(body.get_string_from_utf8())
return
var response = parse_json(body.get_string_from_utf8())
print("Tooted successfully!")
print(body)
remove_child(toot_request)
func auth_user():
var client = Globals.providers.mastodon
OS.shell_open("https://toot.martyn.berlin/oauth/authorize?client_id="+client[0].app_client_id+"&scope=read+write+follow+push&redirect_uri=urn:ietf:wg:oauth:2.0:oob&response_type=code")
$VBoxContainer/CodeEntry.visible=true
func _on_CodeEntry_on_authorize(code):
var client = Globals.providers.mastodon
var headers = ["Content-Type: application/json"]
var data = {
"client_id": client[0].app_client_id,
"client_secret": client[0].app_client_secret,
"redirect_uri": "urn:ietf:wg:oauth:2.0:oob",
"grant_type": "authorization_code",
"scope": "read write follow push",
"code": code
}
auth_request = HTTPRequest.new()
add_child(auth_request)
auth_request.connect("request_completed",self,"_on_token_requested")
auth_request.request("https://toot.martyn.berlin/oauth/token",headers,true,HTTPClient.METHOD_POST,JSON.print(data))
pass # Replace with function body.
func _on_TextEdit_text_changed(new_text):
var dict
if len(Globals.providers.mastodon) > 0:
dict = Globals.providers.mastodon[0]
else:
dict = {}
Globals.providers.mastodon[0] = dict
Globals.providers.mastodon[0].baseURL = $VBoxContainer/HBoxContainer/TextEdit.text
Globals.saveConfig()

View File

@ -0,0 +1,110 @@
[gd_scene load_steps=3 format=2]
[ext_resource path="res://Components/MastoConfig.gd" type="Script" id=1]
[ext_resource path="res://Components/MastoAuthCode.tscn" type="PackedScene" id=2]
[node name="MastoConfig" type="Control"]
anchor_right = 1.0
anchor_bottom = 1.0
script = ExtResource( 1 )
__meta__ = {
"_edit_use_anchors_": false
}
[node name="VBoxContainer" type="VBoxContainer" parent="."]
anchor_right = 1.0
anchor_bottom = 1.0
margin_left = 5.0
margin_top = 5.0
margin_right = -5.0
margin_bottom = -5.0
__meta__ = {
"_edit_use_anchors_": false
}
[node name="HBoxContainer" type="HBoxContainer" parent="VBoxContainer"]
margin_right = 1014.0
margin_bottom = 24.0
[node name="Label" type="Label" parent="VBoxContainer/HBoxContainer"]
margin_top = 5.0
margin_right = 328.0
margin_bottom = 19.0
text = "Mastodon root url (e.g. https://toot.martyn.berlin) : "
[node name="TextEdit" type="LineEdit" parent="VBoxContainer/HBoxContainer"]
margin_left = 332.0
margin_right = 1014.0
margin_bottom = 24.0
size_flags_horizontal = 3
size_flags_vertical = 3
[node name="AuthUser" type="Button" parent="VBoxContainer"]
margin_top = 28.0
margin_right = 1014.0
margin_bottom = 48.0
text = "Authenticate as user..."
[node name="CodeEntry" parent="VBoxContainer" instance=ExtResource( 2 )]
visible = false
anchor_right = 0.0
anchor_bottom = 0.0
margin_top = 100.0
margin_right = 1014.0
margin_bottom = 400.0
rect_min_size = Vector2( 0, 300 )
[node name="TestToot" type="Button" parent="VBoxContainer"]
margin_top = 52.0
margin_right = 1014.0
margin_bottom = 72.0
text = "Test Post"
[node name="Panel" type="Panel" parent="VBoxContainer"]
margin_top = 76.0
margin_right = 1014.0
margin_bottom = 76.0
__meta__ = {
"_edit_use_anchors_": false
}
[node name="Label" type="Label" parent="VBoxContainer/Panel"]
margin_right = 122.0
margin_bottom = 14.0
text = "Mastodon settings:"
__meta__ = {
"_edit_use_anchors_": false
}
[node name="GridContainer" type="GridContainer" parent="VBoxContainer/Panel"]
anchor_right = 1.0
margin_top = 20.0
margin_bottom = 20.0
size_flags_horizontal = 3
size_flags_vertical = 3
__meta__ = {
"_edit_use_anchors_": false
}
[node name="CheckBox" type="CheckBox" parent="VBoxContainer/Panel/GridContainer"]
margin_right = 741.0
margin_bottom = 24.0
text = "Attach Audio to Toot (Mastodon Admins may not like this, audio takes up a fair amount of space and bandwidth)"
[node name="CheckBox2" type="CheckBox" parent="VBoxContainer/Panel/GridContainer"]
margin_top = 28.0
margin_right = 741.0
margin_bottom = 52.0
text = "Send Audio to binary pastebin paste.c-net.org - again, might upset their admins..."
[node name="Label" type="Label" parent="VBoxContainer/Panel/GridContainer"]
margin_top = 56.0
margin_right = 741.0
margin_bottom = 70.0
text = "We'll add more options as time goes on."
[node name="HTTPRequest" type="HTTPRequest" parent="."]
[connection signal="text_changed" from="VBoxContainer/HBoxContainer/TextEdit" to="." method="_on_TextEdit_text_changed"]
[connection signal="pressed" from="VBoxContainer/AuthUser" to="." method="_on_Login_pressed"]
[connection signal="on_authorize" from="VBoxContainer/CodeEntry" to="." method="_on_CodeEntry_on_authorize"]
[connection signal="pressed" from="VBoxContainer/TestToot" to="." method="_on_Button3_pressed"]

View File

@ -0,0 +1,19 @@
extends Control
# Declare member variables here. Examples:
# var a = 2
# var b = "text"
var spectrum_record
# Called when the node enters the scene tree for the first time.
func _ready():
var idx = AudioServer.get_bus_index("Record")
spectrum_record = AudioServer.get_bus_effect_instance(1,1)
# Called every frame. 'delta' is the elapsed time since the previous frame.
func _process(delta):
var magnitude = spectrum_record.get_magnitude_for_frequency_range(0,11050.0).length()
var energy = clamp((60 + linear2db(magnitude)) / 60, 0, 1)
$RecordMeter.value = energy * 100

View File

@ -0,0 +1,31 @@
[gd_scene load_steps=4 format=2]
[ext_resource path="res://UI/src/meter.png" type="Texture" id=1]
[ext_resource path="res://Components/MicMeterHoriz.gd" type="Script" id=2]
[sub_resource type="AudioStreamMicrophone" id=1]
[node name="Control" type="Control"]
anchor_right = 1.0
anchor_bottom = 1.0
script = ExtResource( 2 )
__meta__ = {
"_edit_use_anchors_": false
}
[node name="RecordMeter" type="TextureProgress" parent="."]
anchor_right = 1.0
anchor_bottom = 1.0
rect_min_size = Vector2( 0, 16 )
size_flags_horizontal = 3
size_flags_vertical = 0
texture_progress = ExtResource( 1 )
nine_patch_stretch = true
__meta__ = {
"_edit_use_anchors_": false
}
[node name="AudioStreamRecorder" type="AudioStreamPlayer" parent="."]
stream = SubResource( 1 )
autoplay = true
bus = "Record"

View File

@ -0,0 +1,55 @@
extends Control
signal delay_changed(slider,value)
var count = 0
var sliders = []
var values = []
var deets = []
func set_count(value):
for slice in $VBoxContainer.get_children():
slice.remove_and_skip()
sliders = []
deets = []
for i in range(0,value):
if len(values) < value+1:
values.append(Globals.audio_delay_seconds * 1000)
var slice = HBoxContainer.new()
var label = Label.new()
label.text = String(i+1)
label.hint_tooltip = "Vocal delay track "+String(i+1)
label.mouse_filter = Control.MOUSE_FILTER_STOP
slice.add_child(label)
var slider = HSlider.new()
slider.hint_tooltip = "Vocal delay track "+String(i+1)
slider.size_flags_horizontal = SIZE_EXPAND_FILL
print("Set track "+String(i)+" to "+String(values[i]))
slider.value = values[i]
slider.max_value = 1000
slider.connect("value_changed",self,"on_value_changed")
slice.add_child(slider)
sliders.append(slider)
var deet = Label.new()
deet.text = String(values[i]/1000) + "s"
deet.rect_min_size = Vector2(50,0)
deet.hint_tooltip = "Vocal delay track "+String(i+1)
deet.mouse_filter = Control.MOUSE_FILTER_STOP
deets.append(deet)
slice.add_child(deet)
$VBoxContainer.add_child(slice)
func on_value_changed(value):
for i in range(0,len(sliders)):
if values[i] != sliders[i].value:
values[i] = sliders[i].value
deets[i].text = String(values[i]/1000) + "s"
emit_signal("delay_changed",i,sliders[i].value)
# Called when the node enters the scene tree for the first time.
func _ready():
pass # Replace with function body.
# Called every frame. 'delta' is the elapsed time since the previous frame.
#func _process(delta):
# pass

View File

@ -0,0 +1,18 @@
[gd_scene load_steps=2 format=2]
[ext_resource path="res://Components/MultiDelaySlider.gd" type="Script" id=1]
[node name="Control" type="Control"]
anchor_right = 1.0
anchor_bottom = 1.0
script = ExtResource( 1 )
__meta__ = {
"_edit_use_anchors_": false
}
[node name="VBoxContainer" type="VBoxContainer" parent="."]
anchor_right = 1.0
anchor_bottom = 1.0
__meta__ = {
"_edit_use_anchors_": false
}

View File

@ -0,0 +1,113 @@
extends Control
var players = []
# Declare member variables here. Examples:
# var a = 2
# var b = "text"
var AudioSyncs = []
var AudioStreams = []
var AudioVolumes = []
var playing = false
export(VideoStreamWebm) var VideoStream
export(bool) var paused
export(int) var VideoDurationSeconds
export(float) var stream_position
export(float) var volume_db
signal finished
# Called when the node enters the scene tree for the first time.
func _ready():
$VideoPlayer.stream = VideoStream
$VideoPlayer.paused = paused
$TextureProgress.max_value = VideoDurationSeconds
$VideoPlayer.volume_db = volume_db
print(">>>count is "+String(len(AudioSyncs))+","+String(len(players))+","+String(len(AudioStreams)))
func play():
$VideoPlayer.play()
playing = true
func stop():
$VideoPlayer.stop()
for playerid in range(0,len(players)):
print(">>>Stopping player"+String(playerid))
players[playerid].stop()
playing = false
func set_VideoStream(new_stream):
VideoStream = new_stream
if !is_inside_tree(): return
$VideoPlayer.stream = new_stream
print(">>>VideoStream is now "+new_stream.to_string())
func set_paused(value):
if !is_inside_tree(): return
$VideoPlayer.paused = value
paused = value
print(">>>Paused is now "+String(value))
func set_VideoDurationSeconds(value):
if !is_inside_tree(): return
$TextureProgress.max_value = value
VideoDurationSeconds = value
print(">>>VideoDurationSeconds is now "+String(value))
func set_volume_db(value):
if !is_inside_tree(): return
$VideoPlayer.volume_db = value
volume_db = value
print(">>>volume_db is now "+String(value))
func set_audio_volume_db(which, value):
players[which].set_volume_db(value)
func set_stream_delay(which, value):
if playing:
if !paused:
$VideoPlayer.paused = true
for playerid in range(0,len(players)):
players[playerid].stream_paused = true
players[which].seek($VideoPlayer.stream_position + value)
if !paused:
$VideoPlayer.paused = false
for playerid in range(0,len(players)):
players[playerid].stream_paused = false
AudioSyncs[which] = value
func get_stream_position():
return $VideoPlayer.stream_position
func add_audio_stream(stream, delay):
var player = AudioStreamPlayer.new()
player.set_stream(stream)
player.volume_db = 1
player.pitch_scale = 1
add_child(player)
players.append(player)
AudioSyncs.append(delay)
AudioStreams.append(stream)
print(">>>added stream, count is now "+String(len(AudioSyncs))+","+String(len(players))+","+String(len(AudioStreams)))
func play_combined():
playing = true
$VideoPlayer.play()
for playerid in range(0,len(players)):
print(">>>Playing player"+String(playerid))
players[playerid].play()
players[playerid].stream_paused = true
players[playerid].seek(AudioSyncs[playerid])
players[playerid].stream_paused = false
# Called every frame. 'delta' is the elapsed time since the previous frame.
func _process(delta):
$TextureProgress.value = $VideoPlayer.stream_position
func _on_VideoPlayer_finished():
playing = false
for playerid in range(0,len(players)):
print(">>>Stopping player"+String(playerid))
players[playerid].stop()
emit_signal("finished")

View File

@ -0,0 +1,57 @@
[gd_scene load_steps=4 format=2]
[ext_resource path="res://Components/MultiStreamPlayer.gd" type="Script" id=1]
[ext_resource path="res://UI/src/progressinner.png" type="Texture" id=2]
[ext_resource path="res://UI/src/progressouter.png" type="Texture" id=3]
[node name="Control" type="Control"]
anchor_right = 1.0
anchor_bottom = 1.0
script = ExtResource( 1 )
__meta__ = {
"_edit_use_anchors_": false
}
[node name="VideoPlayer" type="VideoPlayer" parent="."]
anchor_right = 1.0
anchor_bottom = 1.0
margin_left = 5.0
margin_top = 5.0
margin_right = -5.0
margin_bottom = -5.0
autoplay = true
__meta__ = {
"_edit_use_anchors_": false
}
[node name="TextureProgress" type="TextureProgress" parent="."]
anchor_top = 1.0
anchor_right = 1.0
anchor_bottom = 1.0
margin_left = 20.0
margin_top = -47.0
margin_right = -27.0
margin_bottom = -14.0
max_value = 313.701
step = 0.1
texture_progress = ExtResource( 2 )
nine_patch_stretch = true
__meta__ = {
"_edit_use_anchors_": false
}
[node name="TextureRect" type="TextureRect" parent="."]
anchor_top = 1.0
anchor_right = 1.0
anchor_bottom = 1.0
margin_left = 15.0
margin_top = -51.0
margin_right = -5.0
margin_bottom = -5.0
rect_scale = Vector2( 0.5, 0.5 )
texture = ExtResource( 3 )
stretch_mode = 1
__meta__ = {
"_edit_use_anchors_": false
}
[connection signal="finished" from="VideoPlayer" to="." method="_on_VideoPlayer_finished"]

View File

@ -0,0 +1,47 @@
extends Control