mirror of
https://github.com/HIllya51/LunaTranslator.git
synced 2024-12-26 23:24:13 +08:00
.
This commit is contained in:
parent
c03c6ac257
commit
e7adc51431
@ -1,7 +1,7 @@
|
||||
|
||||
set(VERSION_MAJOR 6)
|
||||
set(VERSION_MINOR 14)
|
||||
set(VERSION_PATCH 10)
|
||||
set(VERSION_PATCH 11)
|
||||
set(VERSION_REVISION 0)
|
||||
set(LUNA_VERSION "{${VERSION_MAJOR},${VERSION_MINOR},${VERSION_PATCH},${VERSION_REVISION}}")
|
||||
add_library(VERSION_DEF ${CMAKE_CURRENT_LIST_DIR}/version_def.cpp)
|
||||
|
@ -2,6 +2,7 @@ import math, base64, uuid, gobject
|
||||
from cishu.cishubase import DictTree
|
||||
from myutils.config import isascii
|
||||
from traceback import print_exc
|
||||
from myutils.audioplayer import bass_decode
|
||||
|
||||
|
||||
class FlexBuffer:
|
||||
@ -2235,21 +2236,6 @@ class mdict(cishubase):
|
||||
# print(html)
|
||||
return html
|
||||
|
||||
def parseaudio(self, html_content, url, file_content):
|
||||
base64_content = base64.b64encode(file_content).decode("utf-8")
|
||||
|
||||
uid = str(uuid.uuid4())
|
||||
# with open(uid+'.mp3','wb') as ff:
|
||||
# ff.write(file_content)
|
||||
audio = '<audio controls id="{}" style="display: none"><source src="data:application/octet-stream;base64,{}"></audio>'.format(
|
||||
uid, base64_content
|
||||
)
|
||||
html_content = audio + html_content.replace(
|
||||
url,
|
||||
"javascript:document.getElementById('{}').play()".format(uid),
|
||||
)
|
||||
return html_content
|
||||
|
||||
def parse_url_in_mdd(self, index: IndexBuilder, url1: str):
|
||||
url1 = url1.replace("/", "\\")
|
||||
if not url1.startswith("\\"):
|
||||
@ -2282,12 +2268,17 @@ class mdict(cishubase):
|
||||
return
|
||||
ext = os.path.splitext(url)[1].lower()
|
||||
if ext in (".aac", ".spx"):
|
||||
mp3 = bass_decode(file_content, ext)
|
||||
if not mp3:
|
||||
print(ext, "decode error")
|
||||
return
|
||||
file_content = mp3
|
||||
ext = ".mp3"
|
||||
varname = "var_" + hashlib.md5(file_content).hexdigest()
|
||||
audiob64vals[varname] = base64.b64encode(file_content).decode()
|
||||
return 3, "javascript:safe_mdict_sound_call('{}',{})".format(
|
||||
ext, varname
|
||||
return 3, "javascript:mdict_play_sound('{}',{})".format(
|
||||
ext[1:], varname
|
||||
)
|
||||
return 2, file_content
|
||||
file_content = self.parse_url_in_mdd(index, url)
|
||||
if not file_content:
|
||||
return
|
||||
@ -2433,8 +2424,6 @@ class mdict(cishubase):
|
||||
if css:
|
||||
csscollect[url] = css
|
||||
html_content = html_content.replace(url, "")
|
||||
elif _type == 2:
|
||||
html_content = self.parseaudio(html_content, url, file_content)
|
||||
elif _type == 0:
|
||||
varname = "var_" + hashlib.md5(file_content).hexdigest()
|
||||
hrefsrcvals[varname] = base64.b64encode(file_content).decode()
|
||||
@ -2470,7 +2459,7 @@ class mdict(cishubase):
|
||||
print_exc()
|
||||
if not results:
|
||||
return
|
||||
divid = "luna_internal_" + str(uuid.uuid4())
|
||||
divid = "luna_" + str(uuid.uuid4())
|
||||
csscollect = {}
|
||||
for i in range(len(results)):
|
||||
results[i] = self.repairtarget(
|
||||
@ -2648,11 +2637,16 @@ let elements = document.querySelectorAll('[src="'+varname+'"]');
|
||||
for(let i=0;i<elements.length;i++)
|
||||
elements[i].src="data:application/octet-stream;base64," + varval
|
||||
}
|
||||
function safe_mdict_sound_call(ext, b64){
|
||||
if(window.mdict_sound_call)
|
||||
window.mdict_sound_call(ext, b64)
|
||||
else if(window.LUNAJSObject)
|
||||
window.LUNAJSObject.mdict_sound_call(ext, b64)
|
||||
var lastmusicplayer=false;
|
||||
function mdict_play_sound(ext, b64){
|
||||
const music = new Audio();
|
||||
music.src="data:audio/"+ext+";base64,"+b64
|
||||
if(lastmusicplayer!=false)
|
||||
{
|
||||
lastmusicplayer.pause()
|
||||
}
|
||||
lastmusicplayer=music
|
||||
music.play();
|
||||
}
|
||||
function safe_mdict_entry_call(word){
|
||||
if(window.mdict_entry_call)
|
||||
|
@ -1168,7 +1168,6 @@ class searchwordW(closeashidewindow):
|
||||
self.textOutput.bind(
|
||||
"mdict_entry_call", lambda word: self.search_word.emit(word, False)
|
||||
)
|
||||
self.textOutput.bind("mdict_sound_call", self.mdict_sound_call)
|
||||
self.cache_results = {}
|
||||
self.hiding = True
|
||||
|
||||
@ -1187,12 +1186,6 @@ class searchwordW(closeashidewindow):
|
||||
|
||||
self.spliter.addWidget(w)
|
||||
|
||||
def mdict_sound_call(self, ext, soundb64: str):
|
||||
|
||||
gobject.baseobject.audioplayer.play(
|
||||
base64.b64decode(soundb64.encode()), force=True, ext=ext
|
||||
)
|
||||
|
||||
def onceaddankiwindow(self, idx):
|
||||
if idx == 1:
|
||||
if self.isfirstshowanki:
|
||||
|
@ -2,8 +2,8 @@ import time
|
||||
from traceback import print_exc
|
||||
from myutils.config import globalconfig
|
||||
import threading
|
||||
import gobject
|
||||
from ctypes.wintypes import BOOL, DWORD, HWND
|
||||
import gobject, winsharedutils
|
||||
from ctypes.wintypes import BOOL, DWORD, HWND, WORD
|
||||
from ctypes import (
|
||||
WinDLL,
|
||||
WINFUNCTYPE,
|
||||
@ -13,6 +13,12 @@ from ctypes import (
|
||||
c_int64,
|
||||
c_void_p,
|
||||
c_char_p,
|
||||
Structure,
|
||||
POINTER,
|
||||
pointer,
|
||||
c_void_p,
|
||||
create_string_buffer,
|
||||
sizeof,
|
||||
)
|
||||
|
||||
|
||||
@ -21,9 +27,12 @@ HSAMPLE = c_ulong # sample handle
|
||||
HPLUGIN = c_ulong # Plugin handle
|
||||
QWORD = c_int64
|
||||
HSTREAM = c_ulong # sample stream handle
|
||||
|
||||
BASS_SAMPLE_FLOAT = 0x100
|
||||
BASS_STREAM_DECODE = 0x200000
|
||||
BASS_UNICODE = 0x80000000 # -2147483648
|
||||
BASS_ATTRIB_VOL = 2
|
||||
BASS_ATTRIB_FREQ = 1
|
||||
BASS_SAMPLE_8BITS = 1
|
||||
BASS_POS_BYTE = 0 # byte position
|
||||
bass_module = WinDLL(gobject.GetDllpath("bass.dll"))
|
||||
|
||||
@ -51,6 +60,40 @@ BASS_PluginLoad = WINFUNCTYPE(c_ulong, c_char_p, c_ulong)(
|
||||
)
|
||||
|
||||
|
||||
class WAVEFORMATEX(Structure):
|
||||
_fields_ = [
|
||||
("wFormatTag", WORD),
|
||||
("nChannels", WORD),
|
||||
("nSamplesPerSec", DWORD),
|
||||
("nAvgBytesPerSec", DWORD),
|
||||
("nBlockAlign", WORD),
|
||||
("wBitsPerSample", WORD),
|
||||
("cbSize", WORD),
|
||||
]
|
||||
|
||||
|
||||
class BASS_CHANNELINFO(Structure):
|
||||
_fields_ = [
|
||||
("freq", DWORD),
|
||||
("chans", DWORD),
|
||||
("flags", DWORD),
|
||||
("ctype", DWORD),
|
||||
("origres", DWORD),
|
||||
("plugin", HPLUGIN),
|
||||
("sample", HSAMPLE),
|
||||
("filename", c_char_p),
|
||||
]
|
||||
|
||||
|
||||
BASS_ChannelGetInfo = WINFUNCTYPE(BOOL, DWORD, POINTER(BASS_CHANNELINFO))(
|
||||
("BASS_ChannelGetInfo", bass_module)
|
||||
)
|
||||
BASS_ChannelIsActive = WINFUNCTYPE(DWORD, DWORD)(("BASS_ChannelIsActive", bass_module))
|
||||
BASS_ChannelGetData = WINFUNCTYPE(DWORD, DWORD, c_void_p, DWORD)(
|
||||
("BASS_ChannelGetData", bass_module)
|
||||
)
|
||||
|
||||
|
||||
class playonce:
|
||||
def __init__(self, fileormem, volume) -> None:
|
||||
self.handle = None
|
||||
@ -100,6 +143,51 @@ BASS_Init(-1, 44100, 0, 0, 0)
|
||||
# https://www.un4seen.com/
|
||||
plugins = {".spx": "bass_spx.dll"}
|
||||
|
||||
pluginshandle = {}
|
||||
|
||||
|
||||
def load_ext(ext=None):
|
||||
if ext and plugins.get(ext) and not pluginshandle.get(ext):
|
||||
pluginshandle[ext] = BASS_PluginLoad(
|
||||
gobject.GetDllpath(plugins.get(ext)).encode("utf8"), 0
|
||||
)
|
||||
|
||||
|
||||
def bass_decode(bs, ext=None):
|
||||
load_ext(ext)
|
||||
stream = BASS_StreamCreateFile(True, bs, 0, len(bs), BASS_STREAM_DECODE)
|
||||
if not stream:
|
||||
return
|
||||
info = BASS_CHANNELINFO()
|
||||
if not BASS_ChannelGetInfo(stream, pointer(info)):
|
||||
return
|
||||
wf = WAVEFORMATEX()
|
||||
wf.wFormatTag = 1
|
||||
wf.nChannels = info.chans
|
||||
wf.wBitsPerSample = 8 if info.flags & BASS_SAMPLE_8BITS else 16
|
||||
wf.nBlockAlign = wf.nChannels * wf.wBitsPerSample // 8
|
||||
wf.nSamplesPerSec = info.freq
|
||||
wf.nAvgBytesPerSec = wf.nSamplesPerSec * wf.nBlockAlign
|
||||
res = []
|
||||
size = 0
|
||||
buff = create_string_buffer(0x10000)
|
||||
while BASS_ChannelIsActive(stream):
|
||||
get = BASS_ChannelGetData(stream, buff, 0x10000)
|
||||
res.append(buff[:get])
|
||||
size += get
|
||||
header = []
|
||||
header.append(b"RIFF")
|
||||
header.append(bytes(c_int(size + 44)))
|
||||
header.append(b"WAVE")
|
||||
header.append(b"fmt ")
|
||||
header.append(bytes(c_int(sizeof(WAVEFORMATEX))))
|
||||
header.append(bytes(wf))
|
||||
header.append(b"data")
|
||||
header.append(bytes(c_int(size)))
|
||||
header.extend(res)
|
||||
data = b"".join(header)
|
||||
return winsharedutils.encodemp3(data)
|
||||
|
||||
|
||||
class series_audioplayer:
|
||||
def __init__(self, playovercallback=None):
|
||||
@ -111,7 +199,6 @@ class series_audioplayer:
|
||||
self.lock.acquire()
|
||||
self.timestamp = None
|
||||
self.lastcontext = None
|
||||
self.plugins = {}
|
||||
threading.Thread(target=self.__dotasks).start()
|
||||
|
||||
def stop(self):
|
||||
@ -126,10 +213,7 @@ class series_audioplayer:
|
||||
if timestamp and (timestamp != self.timestamp):
|
||||
return
|
||||
self.timestamp = timestamp
|
||||
if ext and plugins.get(ext) and not self.plugins.get(ext):
|
||||
self.plugins[ext] = BASS_PluginLoad(
|
||||
gobject.GetDllpath(plugins.get(ext)).encode("utf8"), 0
|
||||
)
|
||||
load_ext(ext)
|
||||
try:
|
||||
self.tasks = (binary, volume, force)
|
||||
self.lock.release()
|
||||
|
Loading…
x
Reference in New Issue
Block a user