Switch to building an exe for Windows.
This commit is contained in:
parent
f09dfac4f2
commit
e6e93f41ad
11 changed files with 154 additions and 18 deletions
8
.gitignore
vendored
8
.gitignore
vendored
|
@ -4,3 +4,11 @@
|
||||||
__pycache__/
|
__pycache__/
|
||||||
|
|
||||||
state/
|
state/
|
||||||
|
|
||||||
|
*.egg-info/
|
||||||
|
|
||||||
|
build/build-exe-config.json
|
||||||
|
|
||||||
|
*.exe
|
||||||
|
|
||||||
|
*.pyo
|
||||||
|
|
77
build/build-exe-config.template.json
Normal file
77
build/build-exe-config.template.json
Normal file
|
@ -0,0 +1,77 @@
|
||||||
|
{
|
||||||
|
"version": "auto-py-to-exe-configuration_v1",
|
||||||
|
"pyinstallerOptions": [
|
||||||
|
{
|
||||||
|
"optionDest": "noconfirm",
|
||||||
|
"value": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"optionDest": "filenames",
|
||||||
|
"value": "../launch_standalone.py"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"optionDest": "onefile",
|
||||||
|
"value": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"optionDest": "console",
|
||||||
|
"value": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"optionDest": "icon_file",
|
||||||
|
"value": "\\icon.ico"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"optionDest": "name",
|
||||||
|
"value": "BAPSicle"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"optionDest": "ascii",
|
||||||
|
"value": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"optionDest": "clean_build",
|
||||||
|
"value": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"optionDest": "strip",
|
||||||
|
"value": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"optionDest": "noupx",
|
||||||
|
"value": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"optionDest": "uac_admin",
|
||||||
|
"value": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"optionDest": "uac_uiaccess",
|
||||||
|
"value": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"optionDest": "win_private_assemblies",
|
||||||
|
"value": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"optionDest": "win_no_prefer_redirects",
|
||||||
|
"value": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"optionDest": "bootloader_ignore_signals",
|
||||||
|
"value": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"optionDest": "datas",
|
||||||
|
"value": "\\templates;templates/"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"optionDest": "datas",
|
||||||
|
"value": "\\ui-static;ui-static/"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"nonPyinstallerOptions": {
|
||||||
|
"increaseRecursionLimit": false,
|
||||||
|
"manualArguments": ""
|
||||||
|
}
|
||||||
|
}
|
10
build/build-exe.bat
Normal file
10
build/build-exe.bat
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
cd /D "%~dp0"
|
||||||
|
pip install -r requirements.txt
|
||||||
|
pip install -r requirements-windows.txt
|
||||||
|
pip install -e ..\
|
||||||
|
|
||||||
|
python generate-build-exe-config.py
|
||||||
|
|
||||||
|
auto-py-to-exe -c build-exe-config.json -o ./
|
||||||
|
|
||||||
|
TIMEOUT 5
|
19
build/generate-build-exe-config.py
Normal file
19
build/generate-build-exe-config.py
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
import json
|
||||||
|
import os
|
||||||
|
|
||||||
|
dir_path = os.path.dirname(os.path.realpath(__file__))
|
||||||
|
parent_path = os.path.dirname(dir_path)
|
||||||
|
|
||||||
|
in_file = open('build-exe-config.template.json', 'r')
|
||||||
|
config = json.loads(in_file.read())
|
||||||
|
in_file.close()
|
||||||
|
|
||||||
|
for option in config["pyinstallerOptions"]:
|
||||||
|
if option["optionDest"] == "icon_file":
|
||||||
|
option["value"] = dir_path + option["value"]
|
||||||
|
if option["optionDest"] == "datas":
|
||||||
|
option["value"] = parent_path + option["value"]
|
||||||
|
|
||||||
|
out_file = open('build-exe-config.json', 'w')
|
||||||
|
out_file.write(json.dumps(config, indent=2))
|
||||||
|
out_file.close()
|
BIN
build/icon.ico
Normal file
BIN
build/icon.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 111 KiB |
2
build/requirements-windows.txt
Normal file
2
build/requirements-windows.txt
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
pywin32
|
||||||
|
auto-py-to-exe
|
|
@ -2,4 +2,5 @@ pygame==2.0.0.dev20
|
||||||
flask
|
flask
|
||||||
mutagen
|
mutagen
|
||||||
sounddevice
|
sounddevice
|
||||||
autopep8
|
autopep8
|
||||||
|
setproctitle
|
|
@ -1 +0,0 @@
|
||||||
pywin32
|
|
13
launch_standalone.py
Normal file
13
launch_standalone.py
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
import multiprocessing
|
||||||
|
import time
|
||||||
|
|
||||||
|
from server import BAPSicleServer
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
# On Windows calling this function is necessary.
|
||||||
|
# Causes all kinds of loops if not present.
|
||||||
|
multiprocessing.freeze_support()
|
||||||
|
server = multiprocessing.Process(target=BAPSicleServer).start()
|
||||||
|
while True:
|
||||||
|
time.sleep(1)
|
||||||
|
pass
|
36
player.py
36
player.py
|
@ -1,10 +1,13 @@
|
||||||
import pygame
|
from state_manager import StateManager
|
||||||
|
from mutagen.mp3 import MP3
|
||||||
|
from pygame import mixer
|
||||||
import time
|
import time
|
||||||
import json
|
import json
|
||||||
from mutagen.mp3 import MP3
|
|
||||||
import copy
|
import copy
|
||||||
|
import os
|
||||||
|
import setproctitle
|
||||||
|
|
||||||
from state_manager import StateManager
|
os.environ['PYGAME_HIDE_SUPPORT_PROMPT'] = "hide"
|
||||||
|
|
||||||
|
|
||||||
class Player():
|
class Player():
|
||||||
|
@ -24,54 +27,54 @@ class Player():
|
||||||
|
|
||||||
def isInit(self):
|
def isInit(self):
|
||||||
try:
|
try:
|
||||||
pygame.mixer.music.get_busy()
|
mixer.music.get_busy()
|
||||||
except:
|
except:
|
||||||
return False
|
return False
|
||||||
else:
|
else:
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def isPlaying(self):
|
def isPlaying(self):
|
||||||
return bool(pygame.mixer.music.get_busy())
|
return bool(mixer.music.get_busy())
|
||||||
|
|
||||||
def play(self):
|
def play(self):
|
||||||
|
|
||||||
pygame.mixer.music.play(0)
|
mixer.music.play(0)
|
||||||
|
|
||||||
def pause(self):
|
def pause(self):
|
||||||
pygame.mixer.music.pause()
|
mixer.music.pause()
|
||||||
|
|
||||||
def unpause(self):
|
def unpause(self):
|
||||||
pygame.mixer.music.play(0, self.state.state["pos"])
|
mixer.music.play(0, self.state.state["pos"])
|
||||||
|
|
||||||
def stop(self):
|
def stop(self):
|
||||||
pygame.mixer.music.stop()
|
mixer.music.stop()
|
||||||
|
|
||||||
def seek(self, pos):
|
def seek(self, pos):
|
||||||
if self.isPlaying():
|
if self.isPlaying():
|
||||||
pygame.mixer.music.play(0, pos)
|
mixer.music.play(0, pos)
|
||||||
else:
|
else:
|
||||||
self.updateState(pos)
|
self.updateState(pos)
|
||||||
|
|
||||||
def load(self, filename):
|
def load(self, filename):
|
||||||
if not self.isPlaying():
|
if not self.isPlaying():
|
||||||
self.state.update("filename", filename)
|
self.state.update("filename", filename)
|
||||||
pygame.mixer.music.load(filename)
|
mixer.music.load(filename)
|
||||||
if ".mp3" in filename:
|
if ".mp3" in filename:
|
||||||
song = MP3(filename)
|
song = MP3(filename)
|
||||||
self.state.update("length", song.info.length)
|
self.state.update("length", song.info.length)
|
||||||
else:
|
else:
|
||||||
self.state.update("length", pygame.mixer.Sound(filename).get_length()/1000)
|
self.state.update("length", mixer.Sound(filename).get_length()/1000)
|
||||||
|
|
||||||
def quit(self):
|
def quit(self):
|
||||||
pygame.mixer.quit()
|
mixer.quit()
|
||||||
|
|
||||||
def output(self, name=None):
|
def output(self, name=None):
|
||||||
self.quit()
|
self.quit()
|
||||||
try:
|
try:
|
||||||
if name:
|
if name:
|
||||||
pygame.mixer.init(44100, -16, 1, 1024, devicename=name)
|
mixer.init(44100, -16, 1, 1024, devicename=name)
|
||||||
else:
|
else:
|
||||||
pygame.mixer.init(44100, -16, 1, 1024)
|
mixer.init(44100, -16, 1, 1024)
|
||||||
except:
|
except:
|
||||||
return "FAIL:Failed to init mixer, check sound devices."
|
return "FAIL:Failed to init mixer, check sound devices."
|
||||||
else:
|
else:
|
||||||
|
@ -84,7 +87,7 @@ class Player():
|
||||||
if (pos):
|
if (pos):
|
||||||
self.state.update("pos", max(0, pos))
|
self.state.update("pos", max(0, pos))
|
||||||
else:
|
else:
|
||||||
self.state.update("pos", max(0, pygame.mixer.music.get_pos()/1000))
|
self.state.update("pos", max(0, mixer.music.get_pos()/1000))
|
||||||
self.state.update("remaining", self.state.state["length"] - self.state.state["pos"])
|
self.state.update("remaining", self.state.state["length"] - self.state.state["pos"])
|
||||||
|
|
||||||
def getDetails(self):
|
def getDetails(self):
|
||||||
|
@ -93,6 +96,7 @@ class Player():
|
||||||
|
|
||||||
def __init__(self, channel, in_q, out_q):
|
def __init__(self, channel, in_q, out_q):
|
||||||
self.running = True
|
self.running = True
|
||||||
|
setproctitle.setproctitle("BAPSicle - Player " + str(channel))
|
||||||
|
|
||||||
self.state = StateManager("channel" + str(channel), self.__default_state)
|
self.state = StateManager("channel" + str(channel), self.__default_state)
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,9 @@ import player
|
||||||
from flask import Flask, render_template, send_from_directory, request
|
from flask import Flask, render_template, send_from_directory, request
|
||||||
import json
|
import json
|
||||||
import sounddevice as sd
|
import sounddevice as sd
|
||||||
|
import setproctitle
|
||||||
|
|
||||||
|
setproctitle.setproctitle("BAPSicle - Server")
|
||||||
|
|
||||||
|
|
||||||
class BAPSicleServer():
|
class BAPSicleServer():
|
||||||
|
|
Loading…
Reference in a new issue