mirror of
https://github.com/LC044/WeChatMsg
synced 2025-02-21 01:52:35 +08:00
html语音消息支持导出,如果电脑转过文字那么转的文字也可以显示出来
This commit is contained in:
parent
8e20452bbb
commit
fbe1f66660
@ -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"]
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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')
|
||||
|
@ -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
|
Loading…
Reference in New Issue
Block a user