html语音消息支持导出,如果电脑转过文字那么转的文字也可以显示出来

This commit is contained in:
STDquantum 2023-12-12 01:17:21 +08:00
parent 8e20452bbb
commit fbe1f66660
6 changed files with 88 additions and 13 deletions

View File

@ -9,6 +9,7 @@
"""
from .hard_link import HardLink
from .micro_msg import MicroMsg
from .media_msg import MediaMsg
# from . import data
# from . import output
from .misc import Misc
@ -18,4 +19,5 @@ misc_db = Misc()
msg_db = Msg()
micro_msg_db = MicroMsg()
hard_link_db = HardLink()
__all__ = ["data", 'output', 'misc_db', 'micro_msg_db', 'msg_db', 'hard_link_db','MsgType']
media_msg_db = MediaMsg()
__all__ = ["data", 'output', 'misc_db', 'micro_msg_db', 'msg_db', 'hard_link_db','MsgType', "media_msg_db"]

View File

@ -1,9 +1,12 @@
import os.path
from os import system
import sqlite3
import threading
import xml.etree.ElementTree as ET
from pilk import decode
lock = threading.Lock()
db_path = "./app/Database/Msg/MediaMSG3.db"
db_path = "./app/Database/Msg/MediaMSG.db"
def singleton(cls):
@ -16,7 +19,6 @@ def singleton(cls):
return inner
@singleton
class MediaMsg:
def __init__(self):
@ -36,7 +38,6 @@ class MediaMsg:
lock.release()
def get_media_buffer(self, reserved0):
pass
sql = '''
select Buf
from Media
@ -45,14 +46,40 @@ class MediaMsg:
try:
lock.acquire(True)
self.cursor.execute(sql, [reserved0])
return self.cursor.fetchone()
return self.cursor.fetchone()[0]
finally:
lock.release()
def get_audio(self, reserved0, output_path):
buf = self.get_media_buffer(reserved0)
silk_path = f"{output_path}\\{reserved0}.silk"
pcm_path = f"{output_path}\\{reserved0}.pcm"
mp3_path = f"{output_path}\\{reserved0}.mp3"
slik_path = silk_path.replace("/", "\\")
pcm_path = pcm_path.replace("/", "\\")
mp3_path = mp3_path.replace("/", "\\")
print(mp3_path)
if os.path.exists(mp3_path):
return mp3_path
open(silk_path, "wb").write(buf)
decode(silk_path, pcm_path, 44100)
system(f'ffmpeg.exe -loglevel quiet -y -f s16le -i "{pcm_path}" -ar 44100 -ac 1 "{mp3_path}"')
system(f'del "{silk_path}"')
system(f'del "{pcm_path}"')
return mp3_path
def get_audio_text(self, content):
try:
root = ET.fromstring(content)
transtext = root.find(".//voicetrans").get("transtext")
return transtext
except ET.ParseError:
return ""
if __name__ == '__main__':
db_path = './Msg/MediaMSG3.db'
db_path = './Msg/MediaMSG.db'
media_msg_db = MediaMsg()
reserved = '823076859361714342'
buf = media_msg_db.get_media_buffer(reserved)
print(buf)
reserved = '2865682741418252473'
path = media_msg_db.get_audio(reserved, r"D:\gou\message\WeChatMsg")
print(path)

View File

@ -8,6 +8,7 @@ from PyQt5.QtWidgets import QFileDialog
from . import msg_db, micro_msg_db
from .package_msg import PackageMsg
from ..DataBase import hard_link_db
from ..DataBase import media_msg_db
from ..person_pc import MePC
from ..util import path
import shutil
@ -220,6 +221,30 @@ class ChildThread(QThread):
f'''{str_time} {name}\n[图片]\n\n'''
)
def audio(self, doc, message):
origin_docx_path = f"{os.path.abspath('.')}/data/聊天记录/{self.contact.remark}"
str_content = message[7]
str_time = message[8]
is_send = message[4]
avatar = 'myhead.png' if is_send else 'tahead.png'
timestamp = message[5]
msgSvrId = message[9]
if self.output_type == Output.HTML:
try:
audio_path = media_msg_db.get_audio(msgSvrId, output_path=origin_docx_path + "/voice")
audio_path = audio_path.replace('\\', '/')
voice_to_text = media_msg_db.get_audio_text(str_content)
except:
return
if self.is_5_min(timestamp):
doc.write(
f'''{{ type:0, text: '{str_time}',is_send:0,avatar_path:''}},'''
)
doc.write(
f'''{{ type:34, text:'{audio_path}',is_send:{is_send},avatar_path:'{avatar}',voice_to_text:'{voice_to_text}'}},'''
)
def emoji(self, doc, message):
origin_docx_path = f"{os.path.abspath('.')}/data/聊天记录/{self.contact.remark}"
str_content = message[7]
@ -381,6 +406,8 @@ class ChildThread(QThread):
self.text(f, message)
elif type_ == 3 and self.message_types.get(type_):
self.image(f, message)
elif type_ == 34 and self.message_types.get(type_):
self.audio(f, message)
elif type_ == 43 and self.message_types.get(type_):
self.video(f, message)
elif type_ == 47 and self.message_types.get(type_):
@ -694,6 +721,12 @@ body{
margin-left: 18px;
max-width: 350px;
}
.chat-audio{
max-width: 300px;
}
audio{
right: 25px;
}
.input-area{
border-top:0.5px solid #e0e0e0;
height: 150px;
@ -908,8 +941,8 @@ html_end = '''
else if (message.type == 49) {
if (message.sub_type == 57){
if (message.is_send == 1) {
messageElement.className = "item item-right";
messageElement.innerHTML = `<div class='chat-refer chat-refer-right'>${message.text}</div></div>`
messageElement.className = "item item-right";
messageElement.innerHTML = `<div class='chat-refer chat-refer-right'>${message.text}</div></div>`
}
else if (message.is_send == 0) {
messageElement.className = "item item-left";
@ -917,6 +950,16 @@ html_end = '''
}
}
}
else if (message.type == 34) {
if (message.is_send == 1) {
messageElement.className = "item item-right";
messageElement.innerHTML = `<div class='chat-audio'>${message.voice_to_text == "" ? "" : `<div class="bubble">${message.voice_to_text}</div>`}<audio src="${message.text}" controls></audio></div><div class='avatar'><img src="${message.avatar_path}" /></div>`
}
else if (message.is_send == 0) {
messageElement.className = "item item-left";
messageElement.innerHTML = `<div class='avatar'><img src="${message.avatar_path}" /></div><div class='chat-audio'>${message.voice_to_text == "" ? "" : `<div class="bubble">${message.voice_to_text}</div>`}<audio src="${message.text}" controls></audio></div>`
}
}
chatContainer.appendChild(messageElement);
}
document.querySelector("#chat-container").scrollTop = 0;

View File

@ -6,6 +6,7 @@ from app.DataBase.output_pc import Output
types = {
'文本': 1,
'图片': 3,
'语音': 34,
'视频': 43,
'表情包': 47,
'拍一拍等系统消息': 10000
@ -26,7 +27,7 @@ class ExportDialog(QDialog):
self.contact = contact
if file_type == 'html':
self.export_type = Output.HTML
self.export_choices = {"文本": True, "图片": True, "视频": True, "表情包": True,
self.export_choices = {"文本": True, "图片": True, "语音": True, "视频": True, "表情包": True,
'拍一拍等系统消息': True} # 定义导出的数据类型,默认全部选择
elif file_type == 'csv':
self.export_type = Output.CSV

View File

@ -41,6 +41,7 @@ def get_image_format(header):
@log
def parser_xml(xml_string):
assert type(xml_string) == str
# Parse the XML string
root = ET.fromstring(xml_string)
emoji = root.find('./emoji')

View File

@ -15,4 +15,5 @@ jieba==0.42.1
google==3.0.0
protobuf==4.25.1
soupsieve==2.5
lz4==4.3.2
lz4==4.3.2
pilk