Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F5021462
svc_online.py
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
9 KB
Subscribers
None
svc_online.py
View Options
# -*- coding: UTF-8 -*-
"""
SVC的核心处理逻辑
"""
import
os
import
time
import
socket
import
shutil
import
hashlib
from
AIMeiSheng.meisheng_svc_final
import
load_model
,
process_svc_online
from
AIMeiSheng.cos_similar_ui_zoom
import
cos_similar
from
AIMeiSheng.meisheng_env_preparex
import
meisheng_env_prepare
,
demucs_env_prepare
from
AIMeiSheng.voice_classification.online.voice_class_online_fang
import
VoiceClass
,
download_volume_balanced
from
AIMeiSheng.docker_demo.common
import
*
# from AIMeiSheng.demucs_process_one import demucs_process_one
from
AIMeiSheng.separate_demucs
import
main_seperator
import
logging
hostname
=
socket
.
gethostname
()
log_file_name
=
f
"{os.path.dirname(os.path.abspath(__file__))}/av_meisheng_{hostname}.log"
# 设置logger
svc_offline_logger
=
logging
.
getLogger
(
"svc_offline"
)
file_handler
=
logging
.
FileHandler
(
log_file_name
)
file_handler
.
setLevel
(
logging
.
INFO
)
formatter
=
logging
.
Formatter
(
'
%(asctime)s
%(levelname)s
%(message)s
'
,
datefmt
=
'%Y-%m-
%d
%I:%M:%S'
)
file_handler
.
setFormatter
(
formatter
)
# if gs_prod:
# svc_offline_logger.addHandler(file_handler)
if
os
.
path
.
exists
(
gs_tmp_dir
):
shutil
.
rmtree
(
gs_tmp_dir
)
os
.
makedirs
(
gs_model_dir
,
exist_ok
=
True
)
os
.
makedirs
(
gs_resource_cache_dir
,
exist_ok
=
True
)
# 预设参数
gs_gender_models_url
=
"https://av-audit-sync-sg-1256122840.cos.ap-singapore.myqcloud.com/hub/voice_classification/models.zip"
gs_volume_bin_url
=
"https://av-audit-sync-sg-1256122840.cos.ap-singapore.myqcloud.com/dataset/AIMeiSheng/ebur128_tool/v1/ebur128_tool"
class
GSWorkerAttr
:
def
__init__
(
self
,
input_data
):
# 取出输入资源
vocal_url
=
input_data
[
"record_song_url"
]
target_url
=
input_data
[
"target_url"
]
start
=
input_data
[
"start"
]
# 单位是ms
end
=
input_data
[
"end"
]
# 单位是ms
vocal_loudness
=
input_data
[
"vocal_loudness"
]
female_recording_url
=
input_data
[
"female_recording_url"
]
male_recording_url
=
input_data
[
"male_recording_url"
]
self
.
distinct_id
=
hashlib
.
md5
(
vocal_url
.
encode
())
.
hexdigest
()
self
.
tmp_dir
=
os
.
path
.
join
(
gs_tmp_dir
,
self
.
distinct_id
)
if
os
.
path
.
exists
(
self
.
tmp_dir
):
shutil
.
rmtree
(
self
.
tmp_dir
)
os
.
makedirs
(
self
.
tmp_dir
)
self
.
vocal_url
=
vocal_url
self
.
target_url
=
target_url
ext
=
vocal_url
.
split
(
"."
)[
-
1
]
self
.
vocal_path
=
os
.
path
.
join
(
self
.
tmp_dir
,
self
.
distinct_id
+
f
"_in.{ext}"
)
self
.
vocal_demucs_path
=
os
.
path
.
join
(
self
.
tmp_dir
,
self
.
distinct_id
+
f
"_in_demucs.wav"
)
self
.
demucs_flg
=
False
self
.
target_wav_path
=
os
.
path
.
join
(
self
.
tmp_dir
,
self
.
distinct_id
+
"_out.wav"
)
self
.
target_wav_ad_path
=
os
.
path
.
join
(
self
.
tmp_dir
,
self
.
distinct_id
+
"_out_ad.wav"
)
self
.
target_path
=
os
.
path
.
join
(
self
.
tmp_dir
,
self
.
distinct_id
+
"_out.m4a"
)
self
.
female_svc_source_url
=
female_recording_url
self
.
male_svc_source_url
=
male_recording_url
ext
=
female_recording_url
.
split
(
"."
)[
-
1
]
self
.
female_svc_source_path
=
os
.
path
.
join
(
self
.
tmp_dir
,
self
.
distinct_id
+
f
"_female.{ext}"
)
ext
=
male_recording_url
.
split
(
"."
)[
-
1
]
self
.
male_svc_source_path
=
os
.
path
.
join
(
self
.
tmp_dir
,
self
.
distinct_id
+
f
"_male.{ext}"
)
# self.female_svc_source_path = os.path.join(gs_resource_cache_dir,
# hashlib.md5(female_recording_url.encode()).hexdigest() + "." + ext)
# ext = male_recording_url.split(".")[-1]
# self.male_svc_source_path = os.path.join(gs_resource_cache_dir,
# hashlib.md5(male_recording_url.encode()).hexdigest() + "." + ext)
self
.
st_tm
=
start
self
.
ed_tm
=
end
self
.
target_loudness
=
vocal_loudness
def
log_info_name
(
self
):
return
f
"d_id={self.distinct_id}, vocal_url={self.vocal_url}"
def
rm_cache
(
self
):
if
os
.
path
.
exists
(
self
.
tmp_dir
):
shutil
.
rmtree
(
self
.
tmp_dir
)
def
init_gender_model
():
"""
下载模型
:return:
"""
dst_model_dir
=
os
.
path
.
join
(
gs_model_dir
,
"voice_classification"
)
if
not
os
.
path
.
exists
(
dst_model_dir
):
dst_zip_path
=
os
.
path
.
join
(
gs_model_dir
,
"models.zip"
)
if
not
download2disk
(
gs_gender_models_url
,
dst_zip_path
):
svc_offline_logger
.
fatal
(
f
"download gender_model err={gs_gender_models_url}"
)
cmd
=
f
"cd {gs_model_dir}; unzip {dst_zip_path}; mv models voice_classification; rm -f {dst_zip_path}"
os
.
system
(
cmd
)
if
not
os
.
path
.
exists
(
dst_model_dir
):
svc_offline_logger
.
fatal
(
f
"unzip {dst_zip_path} err"
)
music_voice_pure_model
=
os
.
path
.
join
(
dst_model_dir
,
"voice_005_rec_v5.pth"
)
music_voice_no_pure_model
=
os
.
path
.
join
(
dst_model_dir
,
"voice_10_v5.pth"
)
gender_pure_model
=
os
.
path
.
join
(
dst_model_dir
,
"gender_8k_ratev5_v6_adam.pth"
)
gender_no_pure_model
=
os
.
path
.
join
(
dst_model_dir
,
"gender_8k_v6_adam.pth"
)
vc
=
VoiceClass
(
music_voice_pure_model
,
music_voice_no_pure_model
,
gender_pure_model
,
gender_no_pure_model
)
return
vc
def
init_demucs_seperator
():
demucs_env_prepare
(
logging
,
gs_demucs_model_path
)
seperator
=
main_seperator
()
return
seperator
def
init_svc_model
():
meisheng_env_prepare
(
logging
,
gs_model_dir
)
embed_model
,
hubert_model
=
load_model
()
cs_sim
=
cos_similar
()
return
embed_model
,
hubert_model
,
cs_sim
def
download_volume_adjustment
():
"""
下载音量调整工具
:return:
"""
volume_bin_path
=
os
.
path
.
join
(
gs_model_dir
,
"ebur128_tool"
)
if
not
os
.
path
.
exists
(
volume_bin_path
):
if
not
download2disk
(
gs_volume_bin_url
,
volume_bin_path
):
svc_offline_logger
.
fatal
(
f
"download volume_bin err={gs_volume_bin_url}"
)
os
.
system
(
f
"chmod +x {volume_bin_path}"
)
def
volume_adjustment
(
wav_path
,
target_loudness
,
out_path
):
"""
音量调整
:param wav_path:
:param target_loudness:
:param out_path:
:return:
"""
volume_bin_path
=
os
.
path
.
join
(
gs_model_dir
,
"ebur128_tool"
)
cmd
=
f
"{volume_bin_path} {wav_path} {target_loudness} {out_path}"
os
.
system
(
cmd
)
class
SVCOnline
:
def
__init__
(
self
):
st
=
time
.
time
()
self
.
gender_model
=
init_gender_model
()
self
.
embed_model
,
self
.
hubert_model
,
self
.
cs_sim
=
init_svc_model
()
self
.
demucs_seprator
=
init_demucs_seperator
()
download_volume_adjustment
()
download_volume_balanced
()
svc_offline_logger
.
info
(
f
"svc init finished, sp = {time.time() - st}"
)
def
gender_process
(
self
,
worker_attr
):
st
=
time
.
time
()
gender
,
female_rate
,
is_pure
=
self
.
gender_model
.
process
(
worker_attr
.
vocal_path
)
svc_offline_logger
.
info
(
f
"{worker_attr.vocal_url}, gender={gender}, female_rate={female_rate}, is_pure={is_pure}, "
f
"gender_process sp = {time.time() - st}"
)
if
gender
==
0
:
gender
=
'female'
elif
gender
==
1
:
gender
=
'male'
elif
female_rate
==
None
:
gender
=
'male'
return
gender
,
gs_err_code_gender_classify
elif
female_rate
>
0.5
:
gender
=
'female'
else
:
gender
=
'male'
self
.
demucs_flg
=
False
if
gender
==
'female'
:
if
self
.
gender_model
.
vocal_ratio
<=
1.0
:
#0.5:
print
(
f
"@@@ vocal_ratio: {self.gender_model.vocal_ratio}, gender : {gender}, gs_err_code_vocal_ratio : {gs_err_code_vocal_ratio}"
)
# if not demucs_process_one(worker_attr.vocal_path, worker_attr.vocal_demucs_path):
self
.
demucs_flg
=
True
if
not
self
.
demucs_seprator
.
process_one
(
worker_attr
.
vocal_path
,
worker_attr
.
vocal_demucs_path
):
self
.
demucs_flg
=
False
# return gender, gs_err_code_vocal_ratio
svc_offline_logger
.
info
(
f
" demucs fail and gender={gender}"
)
else
:
if
self
.
gender_model
.
vocal_ratio
<=
1.0
:
#0.6:
print
(
f
"@@@ vocal_ratio: {self.gender_model.vocal_ratio}, gender : {gender}, gs_err_code_vocal_ratio : {gs_err_code_vocal_ratio}"
)
# if not demucs_process_one(worker_attr.vocal_path, worker_attr.vocal_demucs_path):
self
.
demucs_flg
=
True
if
not
self
.
demucs_seprator
.
process_one
(
worker_attr
.
vocal_path
,
worker_attr
.
vocal_demucs_path
):
self
.
demucs_flg
=
False
# return gender, gs_err_code_vocal_ratio
svc_offline_logger
.
info
(
f
" demucs fail and gender={gender}"
)
svc_offline_logger
.
info
(
f
"{worker_attr.vocal_url}, modified gender={gender}"
)
# err = gs_err_code_success
# if female_rate == -1:
# err = gs_err_code_target_silence
return
gender
,
gs_err_code_success
def
process
(
self
,
worker_attr
):
gender
,
err
=
self
.
gender_process
(
worker_attr
)
if
err
!=
gs_err_code_success
:
return
gender
,
err
song_path
=
worker_attr
.
female_svc_source_path
if
gender
==
"male"
:
song_path
=
worker_attr
.
male_svc_source_path
params
=
{
'gender'
:
gender
,
'tst'
:
worker_attr
.
st_tm
,
"tnd"
:
worker_attr
.
ed_tm
,
'delay'
:
0
,
'song_path'
:
None
}
st
=
time
.
time
()
if
os
.
path
.
exists
(
worker_attr
.
vocal_demucs_path
)
and
worker_attr
.
demucs_flg
:
vocal_tmp_path
=
worker_attr
.
vocal_demucs_path
else
:
vocal_tmp_path
=
worker_attr
.
vocal_path
err_code
=
process_svc_online
(
song_path
,
vocal_tmp_path
,
worker_attr
.
target_wav_path
,
self
.
embed_model
,
self
.
hubert_model
,
self
.
cs_sim
,
params
)
svc_offline_logger
.
info
(
f
"{worker_attr.vocal_url}, err_code={err_code} process svc sp = {time.time() - st}"
)
return
gender
,
err_code
File Metadata
Details
Attached
Mime Type
text/x-python
Expires
Mon, May 19, 02:30 (1 d, 59 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1433513
Default Alt Text
svc_online.py (9 KB)
Attached To
R350 av_svc
Event Timeline
Log In to Comment