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__/
|
||||
|
||||
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
|
|
@ -3,3 +3,4 @@ flask
|
|||
mutagen
|
||||
sounddevice
|
||||
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 json
|
||||
from mutagen.mp3 import MP3
|
||||
import copy
|
||||
import os
|
||||
import setproctitle
|
||||
|
||||
from state_manager import StateManager
|
||||
os.environ['PYGAME_HIDE_SUPPORT_PROMPT'] = "hide"
|
||||
|
||||
|
||||
class Player():
|
||||
|
@ -24,54 +27,54 @@ class Player():
|
|||
|
||||
def isInit(self):
|
||||
try:
|
||||
pygame.mixer.music.get_busy()
|
||||
mixer.music.get_busy()
|
||||
except:
|
||||
return False
|
||||
else:
|
||||
return True
|
||||
|
||||
def isPlaying(self):
|
||||
return bool(pygame.mixer.music.get_busy())
|
||||
return bool(mixer.music.get_busy())
|
||||
|
||||
def play(self):
|
||||
|
||||
pygame.mixer.music.play(0)
|
||||
mixer.music.play(0)
|
||||
|
||||
def pause(self):
|
||||
pygame.mixer.music.pause()
|
||||
mixer.music.pause()
|
||||
|
||||
def unpause(self):
|
||||
pygame.mixer.music.play(0, self.state.state["pos"])
|
||||
mixer.music.play(0, self.state.state["pos"])
|
||||
|
||||
def stop(self):
|
||||
pygame.mixer.music.stop()
|
||||
mixer.music.stop()
|
||||
|
||||
def seek(self, pos):
|
||||
if self.isPlaying():
|
||||
pygame.mixer.music.play(0, pos)
|
||||
mixer.music.play(0, pos)
|
||||
else:
|
||||
self.updateState(pos)
|
||||
|
||||
def load(self, filename):
|
||||
if not self.isPlaying():
|
||||
self.state.update("filename", filename)
|
||||
pygame.mixer.music.load(filename)
|
||||
mixer.music.load(filename)
|
||||
if ".mp3" in filename:
|
||||
song = MP3(filename)
|
||||
self.state.update("length", song.info.length)
|
||||
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):
|
||||
pygame.mixer.quit()
|
||||
mixer.quit()
|
||||
|
||||
def output(self, name=None):
|
||||
self.quit()
|
||||
try:
|
||||
if name:
|
||||
pygame.mixer.init(44100, -16, 1, 1024, devicename=name)
|
||||
mixer.init(44100, -16, 1, 1024, devicename=name)
|
||||
else:
|
||||
pygame.mixer.init(44100, -16, 1, 1024)
|
||||
mixer.init(44100, -16, 1, 1024)
|
||||
except:
|
||||
return "FAIL:Failed to init mixer, check sound devices."
|
||||
else:
|
||||
|
@ -84,7 +87,7 @@ class Player():
|
|||
if (pos):
|
||||
self.state.update("pos", max(0, pos))
|
||||
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"])
|
||||
|
||||
def getDetails(self):
|
||||
|
@ -93,6 +96,7 @@ class Player():
|
|||
|
||||
def __init__(self, channel, in_q, out_q):
|
||||
self.running = True
|
||||
setproctitle.setproctitle("BAPSicle - Player " + str(channel))
|
||||
|
||||
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
|
||||
import json
|
||||
import sounddevice as sd
|
||||
import setproctitle
|
||||
|
||||
setproctitle.setproctitle("BAPSicle - Server")
|
||||
|
||||
|
||||
class BAPSicleServer():
|
||||
|
|
Loading…
Reference in a new issue