diff --git a/gui/guimain.py b/gui/guimain.py index c0b27cc..cc1d785 100644 --- a/gui/guimain.py +++ b/gui/guimain.py @@ -419,7 +419,9 @@ def get_widget_all_items(wid: QListWidget): widget: QListWidget = getattr(self.ui, f"listWidget_mx_{i}") args0 += [int(i.text()) for i in get_widget_all_items(widget)] ex = self.get_live_extractor() - save_names = ex.mix_live_song_all_sing(music_id, list(set(args0)), float(self.ui.lineEdit_chara_vol.text())) + chara_vol_str = self.ui.lineEdit_chara_vol.text().strip() + chara_vol_str = chara_vol_str or "-2" + save_names = ex.mix_live_song_all_sing(music_id, list(set(args0)), float(chara_vol_str)) voiceex.log.logger(f"Extract success: {save_names}") else: args = [] @@ -427,7 +429,9 @@ def get_widget_all_items(wid: QListWidget): widget: QListWidget = getattr(self.ui, f"listWidget_mx_{i}") args.append([int(i.text()) for i in get_widget_all_items(widget)]) ex = self.get_live_extractor() - save_names = ex.mix_live_song_by_parts(music_id, *args, volume=float(self.ui.lineEdit_chara_vol.text())) + chara_vol_str = self.ui.lineEdit_chara_vol.text().strip() + chara_vol_str = chara_vol_str or "-2" + save_names = ex.mix_live_song_by_parts(music_id, *args, volume=float(chara_vol_str)) voiceex.log.logger(f"Extract success: {save_names}") finally: self.set_start_btn_stat_signal.emit(True) diff --git a/gui/qtui/main_ui.py b/gui/qtui/main_ui.py index c447621..978fb71 100644 --- a/gui/qtui/main_ui.py +++ b/gui/qtui/main_ui.py @@ -471,6 +471,7 @@ def setupUi(self, MainWindow): self.label_15.setObjectName("label_15") self.gridLayout_5.addWidget(self.label_15, 1, 0, 1, 1) self.lineEdit_chara_vol = QtWidgets.QLineEdit(self.groupBox_9) + self.lineEdit_chara_vol.setInputMask("") self.lineEdit_chara_vol.setObjectName("lineEdit_chara_vol") self.gridLayout_5.addWidget(self.lineEdit_chara_vol, 1, 1, 1, 1) self.pushButton_start_mix = QtWidgets.QPushButton(self.groupBox_9) @@ -530,7 +531,7 @@ def setupUi(self, MainWindow): self.tabWidget.setCurrentIndex(0) self.tabWidget_4.setCurrentIndex(0) self.tabWidget_music_type.setCurrentIndex(0) - self.tabWidget_2.setCurrentIndex(0) + self.tabWidget_2.setCurrentIndex(1) self.tabWidget_parts.setCurrentIndex(0) QtCore.QMetaObject.connectSlotsByName(MainWindow) @@ -607,7 +608,9 @@ def retranslateUi(self, MainWindow): self.pushButton_me_clear.setText(_translate("MainWindow", "Clear")) self.groupBox_9.setTitle(_translate("MainWindow", "Mix Config")) self.label_15.setText(_translate("MainWindow", "Character Volume")) - self.lineEdit_chara_vol.setText(_translate("MainWindow", "0.85")) + self.lineEdit_chara_vol.setToolTip(_translate("MainWindow", "Leave blank to automatically balance the loudness. -1 will not change volume. 1.0 is the full volume.")) + self.lineEdit_chara_vol.setText(_translate("MainWindow", "-1")) + self.lineEdit_chara_vol.setPlaceholderText(_translate("MainWindow", "Leave blank to automatically balance the loudness. -1 will not change volume. 1.0 is the full volume.")) self.pushButton_start_mix.setText(_translate("MainWindow", "Start Mix")) self.checkBox_all_singing.setText(_translate("MainWindow", "Force All Singing")) self.tabWidget_2.setTabText(self.tabWidget_2.indexOf(self.tab_4), _translate("MainWindow", "Mixer")) diff --git a/gui/qtui/main_ui.qm b/gui/qtui/main_ui.qm index bbd96b6..b16c0cb 100644 Binary files a/gui/qtui/main_ui.qm and b/gui/qtui/main_ui.qm differ diff --git a/gui/qtui/main_ui.ts b/gui/qtui/main_ui.ts index d78088c..b25d3d2 100644 --- a/gui/qtui/main_ui.ts +++ b/gui/qtui/main_ui.ts @@ -4,257 +4,257 @@ MainWindow - + Umamusume Voice Text Extractor - + Character List 角色列表 - + Config 配置 - + ./save - + select 选择 - + Save path 保存路径 - + Proxy 代理设置 - + eg. http://127.0.0.1:10087 - + Use Proxy 使用代理 - + Wave Format Wave参数 - + Rate: - + 22050 - + Bits: - + 16 - + Channels: - + 1 - + Get voice from all stories 从所有故事中提取对应角色的语音 - + Download missing voice files 下载缺失的语音文件 - + Use cache 使用缓存 - + Character ID 角色ID - + Start 开始提取 - + Single Character Mode 单角色提取模式 - + CharaID 角色ID - + SaveID 保存ID - + Remove Selecting 移除选择 - + Multi Character Mode 多角色提取模式 - + Voice Extractor 角色语音提取 - + Music List 音乐列表 - + Singing Character List 歌唱角色 - + Download missing files 下载缺失的文件 - + Music ID 音乐ID - + Chara ID 角色ID - + Extract BGM 提取BGM - + Extract Full Chara Sound 提取角色清唱 - + Extract Chara Sound By Lrc 提取角色清唱并根据歌词分割 - + Remove Silence Part 删除音频首尾空白 - + Extractor 提取器 - + Position Sets 位置设定 - + Singing Pos Count: 歌唱角色位置数: - + 0 - + 2 - + 3 - + 4 - + 5 - + 6 - + 7 - + Clear 清除 - + Mix Config 音频混合设置 - + Force All Singing 强制全部歌唱 - + Start Mix 开始混合 - + Mixer 混合器 @@ -264,52 +264,47 @@ Live 音乐提取 - + Character Volume 角色音量 - - 0.85 - - - - + Live Music Live 音乐 - + Jukebox Music 点唱机音乐 - + 48000 - + Music Extractor 音乐提取 - + Extracted Volume 提取音量 - + 1.0 - + About 关于 - + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } @@ -325,14 +320,19 @@ p, li { white-space: pre-wrap; } - + More Settings 更多设置 - + Global Config 全局设置 + + + Leave blank to automatically balance the loudness. -1 will not change volume. 1.0 is the full volume. + 留空自动平衡响度。-1不改变音量。满音量为 1.0。 + diff --git a/gui/qtui/main_ui.ui b/gui/qtui/main_ui.ui index 3deafb5..47dbc64 100644 --- a/gui/qtui/main_ui.ui +++ b/gui/qtui/main_ui.ui @@ -542,7 +542,7 @@ - 0 + 1 @@ -932,8 +932,17 @@ + + Leave blank to automatically balance the loudness. -1 will not change volume. 1.0 is the full volume. + + + + - 0.85 + -1 + + + Leave blank to automatically balance the loudness. -1 will not change volume. 1.0 is the full volume. diff --git a/gui/qtui/msrc_rc.py b/gui/qtui/msrc_rc.py index 16a4a96..4ed52cd 100644 --- a/gui/qtui/msrc_rc.py +++ b/gui/qtui/msrc_rc.py @@ -9,98 +9,110 @@ from PyQt5 import QtCore qt_resource_data = b"\ -\x00\x00\x0a\x99\ +\x00\x00\x0b\x59\ \x3c\ \xb8\x64\x18\xca\xef\x9c\x95\xcd\x21\x1c\xbf\x60\xa1\xbd\xdd\xa7\ -\x00\x00\x00\x05\x7a\x68\x5f\x43\x4e\x42\x00\x00\x01\x58\x00\x47\ +\x00\x00\x00\x05\x7a\x68\x5f\x43\x4e\x42\x00\x00\x01\x60\x00\x47\ \x96\xc4\x00\x00\x00\x00\x00\x4a\x2b\x82\x00\x00\x01\x24\x00\x54\ -\x0e\xc2\x00\x00\x04\x9d\x00\x57\x96\xf9\x00\x00\x06\x06\x00\x5a\ -\xa8\x94\x00\x00\x07\xc8\x00\xe1\xab\xc3\x00\x00\x03\x70\x02\x72\ -\xb3\x52\x00\x00\x05\x3c\x02\xcd\x6e\x94\x00\x00\x00\xb8\x03\x6f\ -\x96\x03\x00\x00\x05\xd2\x03\xbc\xe8\x94\x00\x00\x02\x8c\x04\x10\ -\xbc\xc2\x00\x00\x08\x84\x04\x29\x20\xf4\x00\x00\x06\x69\x04\x78\ -\x7a\x47\x00\x00\x06\x32\x04\xa1\x0c\x57\x00\x00\x04\x68\x04\xa6\ -\x4c\xf7\x00\x00\x01\x4c\x04\xab\x1f\xf4\x00\x00\x08\xbe\x05\x98\ -\xc9\xd4\x00\x00\x06\xdb\x05\xb3\x9d\x2a\x00\x00\x07\x45\x06\x2f\ -\x71\x95\x00\x00\x07\x86\x07\x51\xf9\x33\x00\x00\x04\x31\x07\x57\ -\xea\x69\x00\x00\x08\x24\x07\x69\x25\x75\x00\x00\x08\x54\x07\x9c\ -\x2b\xa4\x00\x00\x08\xf4\x07\xea\xbd\x3d\x00\x00\x02\x05\x08\x96\ -\x2a\xa8\x00\x00\x07\xf4\x08\xd2\x91\x23\x00\x00\x04\xc7\x09\x24\ -\xdd\x83\x00\x00\x01\xb8\x09\xe8\x85\x94\x00\x00\x00\x57\x0a\x5b\ -\x21\x73\x00\x00\x02\x39\x0a\xb1\xcb\x57\x00\x00\x03\xc7\x0b\x87\ -\xe7\x92\x00\x00\x03\x06\x0b\x95\x70\xc3\x00\x00\x03\xfb\x0c\x77\ -\x31\x28\x00\x00\x06\xab\x0c\x9f\x51\x94\x00\x00\x05\x72\x0c\xce\ -\x7e\xd4\x00\x00\x07\x08\x0d\xcc\x0a\xf5\x00\x00\x00\xed\x0d\xcc\ -\x60\xe5\x00\x00\x02\xcf\x0e\x32\xcc\xa4\x00\x00\x00\x85\x0e\x57\ -\xa2\x13\x00\x00\x01\x75\x0e\x88\x30\x44\x00\x00\x00\x28\x0e\xf8\ -\x0e\xd5\x00\x00\x04\xfb\x0f\x0f\x9a\x87\x00\x00\x03\x34\x0f\x52\ -\x7c\x34\x00\x00\x05\xa1\x69\x00\x00\x09\x1d\x03\x00\x00\x00\x04\ -\x51\x73\x4e\x8e\x08\x00\x00\x00\x00\x06\x00\x00\x00\x05\x41\x62\ -\x6f\x75\x74\x07\x00\x00\x00\x0a\x4d\x61\x69\x6e\x57\x69\x6e\x64\ -\x6f\x77\x01\x03\x00\x00\x00\x08\x89\xd2\x82\x72\x00\x49\x00\x44\ -\x08\x00\x00\x00\x00\x06\x00\x00\x00\x08\x43\x68\x61\x72\x61\x20\ -\x49\x44\x07\x00\x00\x00\x0a\x4d\x61\x69\x6e\x57\x69\x6e\x64\x6f\ -\x77\x01\x03\x00\x00\x00\x08\x89\xd2\x82\x72\x00\x49\x00\x44\x08\ -\x00\x00\x00\x00\x06\x00\x00\x00\x07\x43\x68\x61\x72\x61\x49\x44\ -\x07\x00\x00\x00\x0a\x4d\x61\x69\x6e\x57\x69\x6e\x64\x6f\x77\x01\ -\x03\x00\x00\x00\x08\x89\xd2\x82\x72\x00\x49\x00\x44\x08\x00\x00\ -\x00\x00\x06\x00\x00\x00\x0c\x43\x68\x61\x72\x61\x63\x74\x65\x72\ -\x20\x49\x44\x07\x00\x00\x00\x0a\x4d\x61\x69\x6e\x57\x69\x6e\x64\ -\x6f\x77\x01\x03\x00\x00\x00\x08\x89\xd2\x82\x72\x52\x17\x88\x68\ -\x08\x00\x00\x00\x00\x06\x00\x00\x00\x0e\x43\x68\x61\x72\x61\x63\ -\x74\x65\x72\x20\x4c\x69\x73\x74\x07\x00\x00\x00\x0a\x4d\x61\x69\ +\x0e\xc2\x00\x00\x05\x55\x00\x57\x96\xf9\x00\x00\x06\xbe\x00\x5a\ +\xa8\x94\x00\x00\x08\x80\x00\xe1\xab\xc3\x00\x00\x03\x70\x02\x72\ +\xb3\x52\x00\x00\x05\xf4\x02\xcd\x6e\x94\x00\x00\x00\xb8\x03\x6f\ +\x96\x03\x00\x00\x06\x8a\x03\xbc\xe8\x94\x00\x00\x02\x8c\x04\x10\ +\xbc\xc2\x00\x00\x09\x3c\x04\x29\x20\xf4\x00\x00\x07\x21\x04\x78\ +\x7a\x47\x00\x00\x06\xea\x04\xa1\x0c\x57\x00\x00\x05\x20\x04\xa6\ +\x4c\xf7\x00\x00\x01\x4c\x04\xab\x1f\xf4\x00\x00\x09\x76\x05\x98\ +\xc9\xd4\x00\x00\x07\x93\x05\xb3\x9d\x2a\x00\x00\x07\xfd\x06\x2f\ +\x71\x95\x00\x00\x08\x3e\x07\x51\xf9\x33\x00\x00\x04\xe9\x07\x57\ +\xea\x69\x00\x00\x08\xdc\x07\x69\x25\x75\x00\x00\x09\x0c\x07\x9c\ +\x2b\xa4\x00\x00\x09\xac\x07\xea\xbd\x3d\x00\x00\x02\x05\x07\xf3\ +\xb2\x2e\x00\x00\x04\x31\x08\x96\x2a\xa8\x00\x00\x08\xac\x08\xd2\ +\x91\x23\x00\x00\x05\x7f\x09\x24\xdd\x83\x00\x00\x01\xb8\x09\xe8\ +\x85\x94\x00\x00\x00\x57\x0a\x5b\x21\x73\x00\x00\x02\x39\x0a\xb1\ +\xcb\x57\x00\x00\x03\xc7\x0b\x87\xe7\x92\x00\x00\x03\x06\x0b\x95\ +\x70\xc3\x00\x00\x03\xfb\x0c\x77\x31\x28\x00\x00\x07\x63\x0c\x9f\ +\x51\x94\x00\x00\x06\x2a\x0c\xce\x7e\xd4\x00\x00\x07\xc0\x0d\xcc\ +\x0a\xf5\x00\x00\x00\xed\x0d\xcc\x60\xe5\x00\x00\x02\xcf\x0e\x32\ +\xcc\xa4\x00\x00\x00\x85\x0e\x57\xa2\x13\x00\x00\x01\x75\x0e\x88\ +\x30\x44\x00\x00\x00\x28\x0e\xf8\x0e\xd5\x00\x00\x05\xb3\x0f\x0f\ +\x9a\x87\x00\x00\x03\x34\x0f\x52\x7c\x34\x00\x00\x06\x59\x69\x00\ +\x00\x09\xd5\x03\x00\x00\x00\x04\x51\x73\x4e\x8e\x08\x00\x00\x00\ +\x00\x06\x00\x00\x00\x05\x41\x62\x6f\x75\x74\x07\x00\x00\x00\x0a\ +\x4d\x61\x69\x6e\x57\x69\x6e\x64\x6f\x77\x01\x03\x00\x00\x00\x08\ +\x89\xd2\x82\x72\x00\x49\x00\x44\x08\x00\x00\x00\x00\x06\x00\x00\ +\x00\x08\x43\x68\x61\x72\x61\x20\x49\x44\x07\x00\x00\x00\x0a\x4d\ +\x61\x69\x6e\x57\x69\x6e\x64\x6f\x77\x01\x03\x00\x00\x00\x08\x89\ +\xd2\x82\x72\x00\x49\x00\x44\x08\x00\x00\x00\x00\x06\x00\x00\x00\ +\x07\x43\x68\x61\x72\x61\x49\x44\x07\x00\x00\x00\x0a\x4d\x61\x69\ \x6e\x57\x69\x6e\x64\x6f\x77\x01\x03\x00\x00\x00\x08\x89\xd2\x82\ -\x72\x97\xf3\x91\xcf\x08\x00\x00\x00\x00\x06\x00\x00\x00\x10\x43\ -\x68\x61\x72\x61\x63\x74\x65\x72\x20\x56\x6f\x6c\x75\x6d\x65\x07\ -\x00\x00\x00\x0a\x4d\x61\x69\x6e\x57\x69\x6e\x64\x6f\x77\x01\x03\ -\x00\x00\x00\x04\x6e\x05\x96\x64\x08\x00\x00\x00\x00\x06\x00\x00\ -\x00\x05\x43\x6c\x65\x61\x72\x07\x00\x00\x00\x0a\x4d\x61\x69\x6e\ -\x57\x69\x6e\x64\x6f\x77\x01\x03\x00\x00\x00\x04\x91\x4d\x7f\x6e\ -\x08\x00\x00\x00\x00\x06\x00\x00\x00\x06\x43\x6f\x6e\x66\x69\x67\ -\x07\x00\x00\x00\x0a\x4d\x61\x69\x6e\x57\x69\x6e\x64\x6f\x77\x01\ -\x03\x00\x00\x00\x0e\x4e\x0b\x8f\x7d\x7f\x3a\x59\x31\x76\x84\x65\ -\x87\x4e\xf6\x08\x00\x00\x00\x00\x06\x00\x00\x00\x16\x44\x6f\x77\ -\x6e\x6c\x6f\x61\x64\x20\x6d\x69\x73\x73\x69\x6e\x67\x20\x66\x69\ -\x6c\x65\x73\x07\x00\x00\x00\x0a\x4d\x61\x69\x6e\x57\x69\x6e\x64\ -\x6f\x77\x01\x03\x00\x00\x00\x12\x4e\x0b\x8f\x7d\x7f\x3a\x59\x31\ -\x76\x84\x8b\xed\x97\xf3\x65\x87\x4e\xf6\x08\x00\x00\x00\x00\x06\ -\x00\x00\x00\x1c\x44\x6f\x77\x6e\x6c\x6f\x61\x64\x20\x6d\x69\x73\ -\x73\x69\x6e\x67\x20\x76\x6f\x69\x63\x65\x20\x66\x69\x6c\x65\x73\ +\x72\x00\x49\x00\x44\x08\x00\x00\x00\x00\x06\x00\x00\x00\x0c\x43\ +\x68\x61\x72\x61\x63\x74\x65\x72\x20\x49\x44\x07\x00\x00\x00\x0a\ +\x4d\x61\x69\x6e\x57\x69\x6e\x64\x6f\x77\x01\x03\x00\x00\x00\x08\ +\x89\xd2\x82\x72\x52\x17\x88\x68\x08\x00\x00\x00\x00\x06\x00\x00\ +\x00\x0e\x43\x68\x61\x72\x61\x63\x74\x65\x72\x20\x4c\x69\x73\x74\ \x07\x00\x00\x00\x0a\x4d\x61\x69\x6e\x57\x69\x6e\x64\x6f\x77\x01\ -\x03\x00\x00\x00\x0a\x63\xd0\x53\xd6\x00\x42\x00\x47\x00\x4d\x08\ -\x00\x00\x00\x00\x06\x00\x00\x00\x0b\x45\x78\x74\x72\x61\x63\x74\ -\x20\x42\x47\x4d\x07\x00\x00\x00\x0a\x4d\x61\x69\x6e\x57\x69\x6e\ -\x64\x6f\x77\x01\x03\x00\x00\x00\x1a\x63\xd0\x53\xd6\x89\xd2\x82\ -\x72\x6e\x05\x55\x31\x5e\x76\x68\x39\x63\x6e\x6b\x4c\x8b\xcd\x52\ -\x06\x52\x72\x08\x00\x00\x00\x00\x06\x00\x00\x00\x1a\x45\x78\x74\ -\x72\x61\x63\x74\x20\x43\x68\x61\x72\x61\x20\x53\x6f\x75\x6e\x64\ -\x20\x42\x79\x20\x4c\x72\x63\x07\x00\x00\x00\x0a\x4d\x61\x69\x6e\ -\x57\x69\x6e\x64\x6f\x77\x01\x03\x00\x00\x00\x0c\x63\xd0\x53\xd6\ -\x89\xd2\x82\x72\x6e\x05\x55\x31\x08\x00\x00\x00\x00\x06\x00\x00\ -\x00\x18\x45\x78\x74\x72\x61\x63\x74\x20\x46\x75\x6c\x6c\x20\x43\ -\x68\x61\x72\x61\x20\x53\x6f\x75\x6e\x64\x07\x00\x00\x00\x0a\x4d\ -\x61\x69\x6e\x57\x69\x6e\x64\x6f\x77\x01\x03\x00\x00\x00\x08\x63\ -\xd0\x53\xd6\x97\xf3\x91\xcf\x08\x00\x00\x00\x00\x06\x00\x00\x00\ -\x10\x45\x78\x74\x72\x61\x63\x74\x65\x64\x20\x56\x6f\x6c\x75\x6d\ -\x65\x07\x00\x00\x00\x0a\x4d\x61\x69\x6e\x57\x69\x6e\x64\x6f\x77\ -\x01\x03\x00\x00\x00\x06\x63\xd0\x53\xd6\x56\x68\x08\x00\x00\x00\ -\x00\x06\x00\x00\x00\x09\x45\x78\x74\x72\x61\x63\x74\x6f\x72\x07\ +\x03\x00\x00\x00\x08\x89\xd2\x82\x72\x97\xf3\x91\xcf\x08\x00\x00\ +\x00\x00\x06\x00\x00\x00\x10\x43\x68\x61\x72\x61\x63\x74\x65\x72\ +\x20\x56\x6f\x6c\x75\x6d\x65\x07\x00\x00\x00\x0a\x4d\x61\x69\x6e\ +\x57\x69\x6e\x64\x6f\x77\x01\x03\x00\x00\x00\x04\x6e\x05\x96\x64\ +\x08\x00\x00\x00\x00\x06\x00\x00\x00\x05\x43\x6c\x65\x61\x72\x07\ +\x00\x00\x00\x0a\x4d\x61\x69\x6e\x57\x69\x6e\x64\x6f\x77\x01\x03\ +\x00\x00\x00\x04\x91\x4d\x7f\x6e\x08\x00\x00\x00\x00\x06\x00\x00\ +\x00\x06\x43\x6f\x6e\x66\x69\x67\x07\x00\x00\x00\x0a\x4d\x61\x69\ +\x6e\x57\x69\x6e\x64\x6f\x77\x01\x03\x00\x00\x00\x0e\x4e\x0b\x8f\ +\x7d\x7f\x3a\x59\x31\x76\x84\x65\x87\x4e\xf6\x08\x00\x00\x00\x00\ +\x06\x00\x00\x00\x16\x44\x6f\x77\x6e\x6c\x6f\x61\x64\x20\x6d\x69\ +\x73\x73\x69\x6e\x67\x20\x66\x69\x6c\x65\x73\x07\x00\x00\x00\x0a\ +\x4d\x61\x69\x6e\x57\x69\x6e\x64\x6f\x77\x01\x03\x00\x00\x00\x12\ +\x4e\x0b\x8f\x7d\x7f\x3a\x59\x31\x76\x84\x8b\xed\x97\xf3\x65\x87\ +\x4e\xf6\x08\x00\x00\x00\x00\x06\x00\x00\x00\x1c\x44\x6f\x77\x6e\ +\x6c\x6f\x61\x64\x20\x6d\x69\x73\x73\x69\x6e\x67\x20\x76\x6f\x69\ +\x63\x65\x20\x66\x69\x6c\x65\x73\x07\x00\x00\x00\x0a\x4d\x61\x69\ +\x6e\x57\x69\x6e\x64\x6f\x77\x01\x03\x00\x00\x00\x0a\x63\xd0\x53\ +\xd6\x00\x42\x00\x47\x00\x4d\x08\x00\x00\x00\x00\x06\x00\x00\x00\ +\x0b\x45\x78\x74\x72\x61\x63\x74\x20\x42\x47\x4d\x07\x00\x00\x00\ +\x0a\x4d\x61\x69\x6e\x57\x69\x6e\x64\x6f\x77\x01\x03\x00\x00\x00\ +\x1a\x63\xd0\x53\xd6\x89\xd2\x82\x72\x6e\x05\x55\x31\x5e\x76\x68\ +\x39\x63\x6e\x6b\x4c\x8b\xcd\x52\x06\x52\x72\x08\x00\x00\x00\x00\ +\x06\x00\x00\x00\x1a\x45\x78\x74\x72\x61\x63\x74\x20\x43\x68\x61\ +\x72\x61\x20\x53\x6f\x75\x6e\x64\x20\x42\x79\x20\x4c\x72\x63\x07\ \x00\x00\x00\x0a\x4d\x61\x69\x6e\x57\x69\x6e\x64\x6f\x77\x01\x03\ -\x00\x00\x00\x0c\x5f\x3a\x52\x36\x51\x68\x90\xe8\x6b\x4c\x55\x31\ -\x08\x00\x00\x00\x00\x06\x00\x00\x00\x11\x46\x6f\x72\x63\x65\x20\ -\x41\x6c\x6c\x20\x53\x69\x6e\x67\x69\x6e\x67\x07\x00\x00\x00\x0a\ -\x4d\x61\x69\x6e\x57\x69\x6e\x64\x6f\x77\x01\x03\x00\x00\x00\x1e\ -\x4e\xce\x62\x40\x67\x09\x65\x45\x4e\x8b\x4e\x2d\x63\xd0\x53\xd6\ -\x5b\xf9\x5e\x94\x89\xd2\x82\x72\x76\x84\x8b\xed\x97\xf3\x08\x00\ -\x00\x00\x00\x06\x00\x00\x00\x1a\x47\x65\x74\x20\x76\x6f\x69\x63\ -\x65\x20\x66\x72\x6f\x6d\x20\x61\x6c\x6c\x20\x73\x74\x6f\x72\x69\ -\x65\x73\x07\x00\x00\x00\x0a\x4d\x61\x69\x6e\x57\x69\x6e\x64\x6f\ -\x77\x01\x03\x00\x00\x00\x08\x51\x68\x5c\x40\x8b\xbe\x7f\x6e\x08\ -\x00\x00\x00\x00\x06\x00\x00\x00\x0d\x47\x6c\x6f\x62\x61\x6c\x20\ -\x43\x6f\x6e\x66\x69\x67\x07\x00\x00\x00\x0a\x4d\x61\x69\x6e\x57\ -\x69\x6e\x64\x6f\x77\x01\x03\x00\x00\x00\x0a\x70\xb9\x55\x31\x67\ -\x3a\x97\xf3\x4e\x50\x08\x00\x00\x00\x00\x06\x00\x00\x00\x0d\x4a\ -\x75\x6b\x65\x62\x6f\x78\x20\x4d\x75\x73\x69\x63\x07\x00\x00\x00\ +\x00\x00\x00\x0c\x63\xd0\x53\xd6\x89\xd2\x82\x72\x6e\x05\x55\x31\ +\x08\x00\x00\x00\x00\x06\x00\x00\x00\x18\x45\x78\x74\x72\x61\x63\ +\x74\x20\x46\x75\x6c\x6c\x20\x43\x68\x61\x72\x61\x20\x53\x6f\x75\ +\x6e\x64\x07\x00\x00\x00\x0a\x4d\x61\x69\x6e\x57\x69\x6e\x64\x6f\ +\x77\x01\x03\x00\x00\x00\x08\x63\xd0\x53\xd6\x97\xf3\x91\xcf\x08\ +\x00\x00\x00\x00\x06\x00\x00\x00\x10\x45\x78\x74\x72\x61\x63\x74\ +\x65\x64\x20\x56\x6f\x6c\x75\x6d\x65\x07\x00\x00\x00\x0a\x4d\x61\ +\x69\x6e\x57\x69\x6e\x64\x6f\x77\x01\x03\x00\x00\x00\x06\x63\xd0\ +\x53\xd6\x56\x68\x08\x00\x00\x00\x00\x06\x00\x00\x00\x09\x45\x78\ +\x74\x72\x61\x63\x74\x6f\x72\x07\x00\x00\x00\x0a\x4d\x61\x69\x6e\ +\x57\x69\x6e\x64\x6f\x77\x01\x03\x00\x00\x00\x0c\x5f\x3a\x52\x36\ +\x51\x68\x90\xe8\x6b\x4c\x55\x31\x08\x00\x00\x00\x00\x06\x00\x00\ +\x00\x11\x46\x6f\x72\x63\x65\x20\x41\x6c\x6c\x20\x53\x69\x6e\x67\ +\x69\x6e\x67\x07\x00\x00\x00\x0a\x4d\x61\x69\x6e\x57\x69\x6e\x64\ +\x6f\x77\x01\x03\x00\x00\x00\x1e\x4e\xce\x62\x40\x67\x09\x65\x45\ +\x4e\x8b\x4e\x2d\x63\xd0\x53\xd6\x5b\xf9\x5e\x94\x89\xd2\x82\x72\ +\x76\x84\x8b\xed\x97\xf3\x08\x00\x00\x00\x00\x06\x00\x00\x00\x1a\ +\x47\x65\x74\x20\x76\x6f\x69\x63\x65\x20\x66\x72\x6f\x6d\x20\x61\ +\x6c\x6c\x20\x73\x74\x6f\x72\x69\x65\x73\x07\x00\x00\x00\x0a\x4d\ +\x61\x69\x6e\x57\x69\x6e\x64\x6f\x77\x01\x03\x00\x00\x00\x08\x51\ +\x68\x5c\x40\x8b\xbe\x7f\x6e\x08\x00\x00\x00\x00\x06\x00\x00\x00\ +\x0d\x47\x6c\x6f\x62\x61\x6c\x20\x43\x6f\x6e\x66\x69\x67\x07\x00\ +\x00\x00\x0a\x4d\x61\x69\x6e\x57\x69\x6e\x64\x6f\x77\x01\x03\x00\ +\x00\x00\x0a\x70\xb9\x55\x31\x67\x3a\x97\xf3\x4e\x50\x08\x00\x00\ +\x00\x00\x06\x00\x00\x00\x0d\x4a\x75\x6b\x65\x62\x6f\x78\x20\x4d\ +\x75\x73\x69\x63\x07\x00\x00\x00\x0a\x4d\x61\x69\x6e\x57\x69\x6e\ +\x64\x6f\x77\x01\x03\x00\x00\x00\x34\x75\x59\x7a\x7a\x81\xea\x52\ +\xa8\x5e\x73\x88\x61\x54\xcd\x5e\xa6\x30\x02\x00\x2d\x00\x31\x4e\ +\x0d\x65\x39\x53\xd8\x97\xf3\x91\xcf\x30\x02\x6e\xe1\x97\xf3\x91\ +\xcf\x4e\x3a\x00\x20\x00\x31\x00\x2e\x00\x30\x30\x02\x08\x00\x00\ +\x00\x00\x06\x00\x00\x00\x65\x4c\x65\x61\x76\x65\x20\x62\x6c\x61\ +\x6e\x6b\x20\x74\x6f\x20\x61\x75\x74\x6f\x6d\x61\x74\x69\x63\x61\ +\x6c\x6c\x79\x20\x62\x61\x6c\x61\x6e\x63\x65\x20\x74\x68\x65\x20\ +\x6c\x6f\x75\x64\x6e\x65\x73\x73\x2e\x20\x2d\x31\x20\x77\x69\x6c\ +\x6c\x20\x6e\x6f\x74\x20\x63\x68\x61\x6e\x67\x65\x20\x76\x6f\x6c\ +\x75\x6d\x65\x2e\x20\x31\x2e\x30\x20\x69\x73\x20\x74\x68\x65\x20\ +\x66\x75\x6c\x6c\x20\x76\x6f\x6c\x75\x6d\x65\x2e\x07\x00\x00\x00\ \x0a\x4d\x61\x69\x6e\x57\x69\x6e\x64\x6f\x77\x01\x03\x00\x00\x00\ \x0e\x00\x4c\x00\x69\x00\x76\x00\x65\x00\x20\x97\xf3\x4e\x50\x08\ \x00\x00\x00\x00\x06\x00\x00\x00\x0a\x4c\x69\x76\x65\x20\x4d\x75\ @@ -17110,7 +17122,7 @@ \x00\x00\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x04\ \x00\x00\x00\x0c\x00\x02\x00\x00\x00\x01\x00\x00\x00\x03\ \x00\x00\x00\x1c\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\ -\x00\x00\x00\x36\x00\x00\x00\x00\x00\x01\x00\x00\x0a\x9d\ +\x00\x00\x00\x36\x00\x00\x00\x00\x00\x01\x00\x00\x0b\x5d\ " qt_resource_struct_v2 = b"\ @@ -17121,8 +17133,8 @@ \x00\x00\x00\x0c\x00\x02\x00\x00\x00\x01\x00\x00\x00\x03\ \x00\x00\x00\x00\x00\x00\x00\x00\ \x00\x00\x00\x1c\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\ -\x00\x00\x01\x8a\x22\x60\x83\x56\ -\x00\x00\x00\x36\x00\x00\x00\x00\x00\x01\x00\x00\x0a\x9d\ +\x00\x00\x01\x8a\x30\xc5\x08\xb5\ +\x00\x00\x00\x36\x00\x00\x00\x00\x00\x01\x00\x00\x0b\x5d\ \x00\x00\x01\x86\x12\x11\x04\xf2\ " diff --git a/voiceex/live_music/live_music_ex.py b/voiceex/live_music/live_music_ex.py index 5000d13..fcbb2e8 100644 --- a/voiceex/live_music/live_music_ex.py +++ b/voiceex/live_music/live_music_ex.py @@ -1,3 +1,4 @@ +import math import os import shutil from .. import resource as umares @@ -86,11 +87,13 @@ def extract_live_music_bgm(self, music_id, oke_index="01", raise_notfound_error= acb_path = self.bundle_hash_to_path(acb_hash) awb_path = self.bundle_hash_to_path(awb_hash) exactor = self.get_extractor(awb_path, acb_path) - if self.wav_format is not None: - exactor.SetWaveFormat(*self.wav_format) - ret = exactor.ExtractAudioFromWaveId(f"{self.save_path}/{'jukebox' if is_jukebox else 'music'}/{music_id}", - f"bgm_{oke_index}_", 0) - exactor.Close() + try: + if self.wav_format is not None: + exactor.SetWaveFormat(*self.wav_format) + ret = exactor.ExtractAudioFromWaveId(f"{self.save_path}/{'jukebox' if is_jukebox else 'music'}/{music_id}", + f"bgm_{oke_index}_", 0) + finally: + exactor.Close() return ret @staticmethod @@ -193,22 +196,53 @@ def get_charas_singing_data(self, music_id, chara_list: t.Optional[t.List[int]], def mix_live_song_all_sing(self, music_id: int, chara_list: t.Optional[t.List[int]], volume: float): save_names = [] + + save_singing_file_names = self.get_charas_singing_data(music_id, chara_list) + temp_singing_name = f"temp/live/{music_id}/mix_all_no_bgm.wav" + save_singing_name = f"{self.save_path}/music/{music_id}/mix_all_no_bgm.wav" + file_list = [] + for chara_id in save_singing_file_names: + for wave_id in save_singing_file_names[chara_id]: + file_list.append(save_singing_file_names[chara_id][wave_id]) + self.mix_wavs(file_list, temp_singing_name, -1) + self.AdjustVolume(temp_singing_name, + [{"start": 0, "end": 600000, "db": -10 * math.log10(len(save_singing_file_names))}], + save_singing_name) + os.remove(temp_singing_name) + for oke in ["01", "02"]: music_bgm = self.extract_live_music_bgm(music_id, oke_index=oke, raise_notfound_error=False) if not music_bgm: continue - save_file_names = self.get_charas_singing_data(music_id, chara_list) save_name = f"{self.save_path}/music/{music_id}/mix_all_oke_{oke}.wav" - file_list = [music_bgm] - for chara_id in save_file_names: - for wave_id in save_file_names[chara_id]: - file_list.append(save_file_names[chara_id][wave_id]) - self.mix_wavs(file_list, save_name, volume) + self.mix_wavs([music_bgm, save_singing_name], save_name, volume) save_names.append(save_name) return save_names + @staticmethod + def get_overlap_times(dictionary): + overlap_times = [] + time_counts = {} + + for file, times in dictionary.items(): + for time in times: + start = time[0] + end = time[1] + + # 更新时间段的文件数量 + if (start, end) not in time_counts: + time_counts[(start, end)] = 1 + else: + time_counts[(start, end)] += 1 + + # 遍历时间数量字典,找到重叠时间段并添加到重叠时间列表中 + for time, count in time_counts.items(): + if count >= 1: + overlap_times.append({"start": time[0], "end": time[1], "count": count}) + return overlap_times + def mix_live_song_by_parts(self, music_id: int, *charas: t.List[int], volume: float): - charas = charas[:7] + # charas = charas[:7] save_file_names = [self.get_charas_singing_data(music_id, i) for i in charas] singing_data = self.get_parts(music_id) singing_data_keys = list(singing_data.keys()) @@ -236,12 +270,22 @@ def mix_live_song_by_parts(self, music_id: int, *charas: t.List[int], volume: fl save_name_p = f"{file_name}_sl.wav" target_files.append(save_name_p) self.SilenceWavPartsByActivePos(file_name, save_name_p, ftimes) + + silence_mixed_temp_name = f"temp/live/{music_id}/mix_by_parts_no_bgm.wav" + silence_mixed_save_name = f"{self.save_path}/music/{music_id}/mix_by_parts_no_bgm.wav" + self.mix_wavs(target_files, silence_mixed_temp_name, -1) + overlap_times = self.get_overlap_times(file_on_times) + for n, overlap in enumerate(overlap_times): + overlap_times[n]["db"] = -10 * math.log10(overlap["count"]) + self.AdjustVolume(silence_mixed_temp_name, overlap_times, silence_mixed_save_name) + os.remove(silence_mixed_temp_name) + save_names = [] for oke in ["01", "02"]: music_bgm = self.extract_live_music_bgm(music_id, oke_index=oke, raise_notfound_error=False) if music_bgm: save_name = f"{self.save_path}/music/{music_id}/mix_by_parts_oke_{oke}.wav" - self.mix_wavs([music_bgm] + target_files, save_name, volume) + self.mix_wavs([music_bgm, silence_mixed_save_name], save_name, volume) save_names.append(save_name) for i in target_files: os.remove(i) diff --git a/voiceex/resource.py b/voiceex/resource.py index 25a0054..8493fd8 100644 --- a/voiceex/resource.py +++ b/voiceex/resource.py @@ -15,7 +15,8 @@ # clr.FindAssembly("voice_extractor.dll") clr.AddReference("./voice extractor/voice extractor/bin/Release/net6.0/voice extractor") from System.Collections.Generic import List as CsList -from System import UInt64, String +from System.Collections.Generic import Dictionary as CsDict +from System import UInt64, String, Object from System.IO import InvalidDataException import voice_extractor @@ -82,6 +83,13 @@ def cut_wav_batch(file_name: str, save_name_prefix: str, time_ms_list: List[List @staticmethod def mix_wavs(files: List[str], save_name: str, volume: float): + """ + mix wav files + :param files: file list + :param save_name: save name + :param volume: volume, 1.0 is full. -1: dont' change volume. -2: automatic balance of loudness + :return: None + """ lst_param = CsList[String]() for i in files: lst_param.Add(i) @@ -106,3 +114,13 @@ def SilenceWavPartsByActivePos(file_name: str, save_name: str, active_ms: List[L add_p.Add(j) lst_param.Add(add_p) voice_extractor.UmaVoiceEx.SilenceWavPartsByActivePos(file_name, save_name, lst_param) + + @staticmethod + def AdjustVolume(file_name: str, volume_changes: List[dict], output_path): + lst_param = CsList[CsDict[String, Object]]() + for i in volume_changes: + add_p = CsDict[String, Object]() + for k in i: + add_p.Add(k, i[k]) + lst_param.Add(add_p) + return voice_extractor.UmaVoiceEx.AdjustVolume(file_name, lst_param, output_path)