From c1fb718a148860645bfc7755d47a69b64683a99a Mon Sep 17 00:00:00 2001 From: Jaykingamez Date: Tue, 28 Jun 2022 10:50:15 +0800 Subject: [PATCH 1/2] Update readme with ffmpeg requirement --- README.md | 40 ++++++++++++++++++++++------------------ 1 file changed, 22 insertions(+), 18 deletions(-) diff --git a/README.md b/README.md index f852362..55f8d41 100644 --- a/README.md +++ b/README.md @@ -1,55 +1,59 @@ # Ren-Py-15.ai-Dubber + A python script that uses wafflecomposite/15.ai-Python-API to dub your Ren'Py game. # Requirements -* csv -* re -* [wafflecomposite's 15.ai-Python-API](https://github.com/wafflecomposite/15.ai-Python-API) +- csv +- re +- [ffmpeg](https://www.wikihow.com/Install-FFmpeg-on-Windows) +- [wafflecomposite's 15.ai-Python-API](https://github.com/wafflecomposite/15.ai-Python-API) # Installation + Open your project in the Ren'Py launcher. Click on "Extract Dialogue", then on "Tab-delimited Spreadsheet (dialogue.tab)", then on Continue. Still on the launcher, click on "base". The root folder of your project will open. Inside the "game" folder, create a new folder named "voice" Move the "dialogue.tab" file, located at the root of your game, into the "voice" folder you just created. -Back to the launcher, open your "options.rpy" file. Find the "init python:" header, and in it type ``config.auto_voice = "voice/{id}.ogg"``, like so: +Back to the launcher, open your "options.rpy" file. Find the "init python:" header, and in it type `config.auto_voice = "voice/{id}.ogg"`, like so: + +**`options.rpy`** -**``options.rpy``** ```py init python: - #Enables automatic voice + #Enables automatic voice config.auto_voice = "voice/{id}.ogg" - - + + ## The following functions take file patterns. File patterns are case- ## insensitive, and matched against the path relative to the base directory, ## with and without a leading /. If multiple patterns match, the first is ## used. ``` -Download both the ``VoiceMaker.py`` script from this repo, and [wafflecomposite's 15.ai-Python-API](https://github.com/wafflecomposite/15.ai-Python-API) ``fifteen_api.py`` +Download both the `VoiceMaker.py` script from this repo, and [wafflecomposite's 15.ai-Python-API](https://github.com/wafflecomposite/15.ai-Python-API) `fifteen_api.py` Place them both on the "voice" folder. -Open ``VoiceMaker.py`` and edit the "characters" list to the character call and the voice you want them to have. For example, I have a character who's identifier is "a", and nother who's identifier is "b". I want a to have Twilight's voice, and I want b to have Rise's. So I edit it like so: ``characters = [['a','Twilight Sparkle'],['b','Rise Kujikawa']]``. You can add as meny as you want. +Open `VoiceMaker.py` and edit the "characters" list to the character call and the voice you want them to have. For example, I have a character who's identifier is "a", and nother who's identifier is "b". I want a to have Twilight's voice, and I want b to have Rise's. So I edit it like so: `characters = [['a','Twilight Sparkle'],['b','Rise Kujikawa']]`. You can add as meny as you want. -Save and run ``VoiceMaker.py``. It will take a while. Like, a LONG while. +Save and run `VoiceMaker.py`. It will take a while. Like, a LONG while. Once the script ends, launch your game and enjoy! # To-Do's -If you wanna help out, look no further! - -* Once all the voices have been created, it'd be nice to have some sort of check to make sure that all voices are there, since 15.ai's servers like to return a 502 error from time to time +If you wanna help out, look no further! +- Once all the voices have been created, it'd be nice to have some sort of check to make sure that all voices are there, since 15.ai's servers like to return a 502 error from time to time # Extra Notes: -This code can also be used with [My vo.codes API](https://github.com/TheSmallBlue/Vo.codes-Python-API) just change the following lines in ``VoiceMaker.py``: -* ``from fifteen_api import FifteenAPI`` to ``from vocodes_api import VocodesAPI`` -* ``tts_api = FifteenAPI()`` to ``tts_api = VocodesAPI()`` -* ``tts_api.save_to_file(final_character,"Neutral",final_text,line[0] + '.wav')`` to ``tts_api.save_to_file(final_character,final_text,line[0] + '.wav')`` +This code can also be used with [My vo.codes API](https://github.com/TheSmallBlue/Vo.codes-Python-API) just change the following lines in `VoiceMaker.py`: + +- `from fifteen_api import FifteenAPI` to `from vocodes_api import VocodesAPI` +- `tts_api = FifteenAPI()` to `tts_api = VocodesAPI()` +- `tts_api.save_to_file(final_character,"Neutral",final_text,line[0] + '.wav')` to `tts_api.save_to_file(final_character,final_text,line[0] + '.wav')` From 14bb4dbd5f03976b2765f01facd85d467cef338c Mon Sep 17 00:00:00 2001 From: Jaykingamez Date: Tue, 28 Jun 2022 10:58:15 +0800 Subject: [PATCH 2/2] Generalize the code, minor optomization --- VoiceMaker.py | 107 +++++++++++++++++++++++++++----------------------- 1 file changed, 57 insertions(+), 50 deletions(-) diff --git a/VoiceMaker.py b/VoiceMaker.py index 14246ab..86b9e45 100644 --- a/VoiceMaker.py +++ b/VoiceMaker.py @@ -1,67 +1,74 @@ -import os +import subprocess from fifteen_api import FifteenAPI import csv import re tts_api = FifteenAPI() -characters = [['c','Twilight Sparkle'],['i','Daring Do'],['a','Adagio Dazzle'],['h','Lyra'],['n','Maud Pie']] +characters = [['c', 'Twilight Sparkle'], ['i', 'Daring Do'], + ['a', 'Adagio Dazzle'], ['h', 'Lyra'], ['n', 'Maud Pie']] previous_character = '' -def ChooseCharacter(char): - global previous_character - if char == 'extend': - return previous_character - else: - for character in characters: - if char[0] == character[0]: - current_character = character[1] - previous_character = current_character - break - - return current_character - -def TextCorrector(txt): - result = txt.replace("{w}","...") - result = result.replace("{i}","") - result = re.sub(r"\s*{.*}\s*", " ", result) - result = re.sub(r"\s*\[.*\]\s*", " ", result) - print(result) - return result - -with open('dialogue.tab', newline='') as dialogue: - dialogue_reader = csv.reader(dialogue, delimiter='\t') - - firstline = True - i = 0 - - for line in dialogue_reader: - if firstline: - firstline = False - continue - - #Get the character - if line[1] != 'centered' and line[1] != '': - - final_character = ChooseCharacter(line[1]) - else: +def ChooseCharacter(char): + global previous_character + if char == 'extend': + return previous_character + else: + for character in characters: + if char == character[0]: + current_character = character[1] + previous_character = current_character + break - continue + return current_character - #Correct the text - if re.search('[a-zA-Z]',line[2]): +def TextCorrector(txt): + result = txt.replace("{w}", "...") + result = result.replace("{i}", "") + result = re.sub(r"\s*{.*}\s*", " ", result) + result = re.sub(r"\s*\[.*\]\s*", " ", result) + print(result) + return result - final_text = TextCorrector(line[2]) - else: - continue +firstline = True +i = 0 +full_length = 0 - tts_api.save_to_file(final_character,"Neutral",final_text,line[0] + '.wav') +with open('dialogue.tab', newline='') as dialogue: + full_length = len(dialogue.readlines()) - os.system("ffmpeg -i " + line[0] + ".wav " + line[0] + ".ogg") - os.remove(line[0] + ".wav") - i = i + 1 - print(str(i) + '/' + str(3252)) \ No newline at end of file +with open('dialogue.tab', newline='') as dialogue: + dialogue_reader = csv.reader(dialogue, delimiter='\t') + for line in dialogue_reader: + id = line[0] + speaker = line[1] + dialogue = line[2] + + if firstline: + firstline = False + continue + + # Get the character + if speaker != '': + final_character = ChooseCharacter(speaker) + else: + continue + + # Correct the text + if re.search('[a-zA-Z]', dialogue): + final_text = TextCorrector(dialogue) + else: + continue + + tts_api.save_to_file(final_character, + final_text, f"{id}.wav") + + subprocess.call( + f"ffmpeg -i {id}.wav -acodec libvorbis {id}.ogg", shell=True) + subprocess.call(f"del {id}.wav", shell=True) + i = i + 1 + print(f"{i} / {full_length}")