| 1 | import re |
| 2 | import os |
| 3 | import requests |
| 4 | import random |
| 5 | from FilmAgent_root.FilmAgent.util import * |
| 6 | from tqdm import tqdm |
| 7 | from FilmAgent_root.FilmAgent.LLMCaller import GPTTTS |
| 8 | # TO DO |
| 9 | Script_path = f"/path/to/script.json" |
| 10 | actos_path = f"/path/to/actors_profile.json" |
| 11 | Audio_path = f"The path to the folder where the audio files are stored." |
| 12 | # TO DO |
| 13 | if not os.path.exists(Audio_path): |
| 14 | os.makedirs(Audio_path) |
| 15 | |
| 16 | |
| 17 | # ChatTTS |
| 18 | url = "http://xxx.xxx.xxx.xxx:xxxx/" # The API path where the chattts service is deployed |
| 19 | Chat_Speaker_female = [0, 1, 2, 3, 4] |
| 20 | Chat_Speaker_male = [0, 1, 2, 3, 4] |
| 21 | random.shuffle(Chat_Speaker_female) |
| 22 | random.shuffle(Chat_Speaker_male) |
| 23 | invalid_characters_map = { |
| 24 | "!": ".", |
| 25 | "?": ".", |
| 26 | "'": ",", |
| 27 | ':': ',', |
| 28 | ';': ',', |
| 29 | '!': '.', |
| 30 | '(': ',', |
| 31 | ')': ',', |
| 32 | '[': ',', |
| 33 | ']': ',', |
| 34 | '>': ',', |
| 35 | '<': ',', |
| 36 | '-': ',' |
| 37 | } |
| 38 | # OpenAI TTS |
| 39 | GPT_Speaker_female = ["alloy", "fable", "nova", "shimmer"] |
| 40 | GPT_Speaker_male = ["echo","onyx" ] |
| 41 | random.shuffle(GPT_Speaker_female) |
| 42 | random.shuffle(GPT_Speaker_male) |
| 43 | |
| 44 | |
| 45 | # Clear all audio generated last time |
| 46 | for filename in os.listdir(Audio_path): |
| 47 | file_path = os.path.join(Audio_path, filename) |
| 48 | os.remove(file_path) |
| 49 | |
| 50 | |
| 51 | # GPT: Assign a voice to each character |
| 52 | # name2gptspeaker = {} |
| 53 | # roles = read_json(actos_path) |
| 54 | # for role in roles: |
| 55 | # if role['gender'].lower() == "male": |
| 56 | # name2gptspeaker[role['name']] = GPT_Speaker_male[0] |
| 57 | # GPT_Speaker_male.pop(0) |
| 58 | # else: |
| 59 | # name2gptspeaker[role['name']] = GPT_Speaker_female[0] |
| 60 | # GPT_Speaker_female.pop(0) |
| 61 | |
| 62 | |
| 63 | # ChatTTS: Assign a voice to each character |
| 64 | name2chatspeaker = {} |
| 65 | roles = read_json(actos_path) |
| 66 | for role in roles: |
| 67 | name2chatspeaker[role['name']] = {} |
| 68 | if role['gender'].lower() == "male": |
| 69 | name2chatspeaker[role['name']]['id'] = Chat_Speaker_male[0] |
| 70 | name2chatspeaker[role['name']]['gender'] = "male" |
| 71 | Chat_Speaker_male.pop(0) |
| 72 | else: |
| 73 | name2chatspeaker[role['name']]['id'] = Chat_Speaker_female[0] |
| 74 | name2chatspeaker[role['name']]['gender'] = "female" |
| 75 | Chat_Speaker_female.pop(0) |
| 76 | |
| 77 | |
| 78 | |
| 79 | script = read_json(Script_path) |
| 80 | lines = [] |
| 81 | for scene in script: |
| 82 | for event in scene['scene']: |
| 83 | if "content" in event.keys(): |
| 84 | l = event["content"] |
| 85 | if contains_digit(l): |
| 86 | l = translate_digit(l) |
| 87 | lines.append({"speaker": event["speaker"], "content": prompt_format(l, invalid_characters_map)+"[uv_break]"}) |
| 88 | |
| 89 | |
| 90 | Flag = "ChatTTS" # GPT or ChatTTS |
| 91 | |
| 92 | params_infer_code = {'prompt':'[speed_3]', 'temperature':0.3,'top_P':0.9, 'top_K':1} |
| 93 | params_refine_text = {'prompt':'[oral_2][laugh_4][break_6]'} |
| 94 | print(name2chatspeaker) |
| 95 | |
| 96 | for line in tqdm(lines): |
| 97 | # if Flag == "GPT": |
| 98 | # response = GPTTTS(line['content'], name2gptspeaker[line['speaker']]) |
| 99 | # response.stream_to_file(cretae_new_path(Audio_path, "mp3")) |
| 100 | |
| 101 | if Flag == "ChatTTS": |
| 102 | response = requests.post(url, json={"gender": name2chatspeaker[line['speaker']]['gender'], "text": line['content'], "id": name2chatspeaker[line['speaker']]['id'], "params_infer_code": params_infer_code, "params_refine_text": params_refine_text}) |
| 103 | # response = requests.post(url, json={"gender": line['gender'], "text": line['text'], "id": line['id'], "params_infer_code": params_infer_code, "params_refine_text": params_refine_text}) |
| 104 | if response.status_code == 200: |
| 105 | content_disposition = response.headers.get("Content-Disposition") |
| 106 | filename = re.findall("filename=\"(.+)\"", content_disposition) |
| 107 | filename = filename[0] |
| 108 | with open(os.path.join(Audio_path, filename), "wb") as f: |
| 109 | f.write(response.content) |
| 110 | else: |
| 111 | print(f"Failed to create item. Status code: {response.status_code}") |