|
import gradio as gr |
|
import os |
|
import sys |
|
|
|
|
|
os.system('pip install ipython') |
|
EC2_INSTANCE = False |
|
if EC2_INSTANCE : os.system('cd scripts && sh install.sh') |
|
os.system('python installation.py') |
|
TTS_PATH = "TTS/" |
|
|
|
sys.path.append(TTS_PATH) |
|
VOICE_PATH = "utils/" |
|
|
|
sys.path.append(VOICE_PATH) |
|
from utils.voice import * |
|
|
|
from IPython.display import HTML, Audio |
|
from base64 import b64decode |
|
import numpy as np |
|
from scipy.io.wavfile import read as wav_read |
|
import io |
|
import ffmpeg |
|
from pytube import YouTube |
|
import random |
|
from subprocess import call |
|
from datetime import datetime |
|
|
|
Sagemaker = False |
|
if Sagemaker : |
|
env='source activate python3 && conda activate VideoMessage &&' |
|
else: |
|
env='' |
|
|
|
def time_between(t1, t2): |
|
FMT = '%H:%M:%S' |
|
t1 = datetime.strptime(t1, FMT) |
|
t2 = datetime.strptime(t2, FMT) |
|
delta = t2 - t1 |
|
return str(delta) |
|
|
|
def download_video(url): |
|
|
|
print("Downloading...") |
|
local_file = ( |
|
YouTube(url) |
|
.streams.filter(progressive=True, file_extension="mp4") |
|
.first() |
|
.download(filename="youtube{}.mp4".format(random.randint(0, 10000))) |
|
) |
|
print("Downloaded") |
|
return local_file |
|
|
|
|
|
|
|
def download_youtube(url): |
|
|
|
|
|
from urllib import parse as urlparse |
|
url_data = urlparse.urlparse(url) |
|
query = urlparse.parse_qs(url_data.query) |
|
YOUTUBE_ID = query["v"][0] |
|
url_download ="https://www.youtube.com/watch?v={}".format(YOUTUBE_ID) |
|
|
|
os.system("{} youtube-dl -f mp4 --output youtube.mp4 '{}'".format(env,url_download)) |
|
return "youtube.mp4" |
|
|
|
|
|
|
|
def cleanup(): |
|
import pathlib |
|
import glob |
|
types = ('*.mp4','*.mp3', '*.wav') |
|
|
|
junks = [] |
|
for files in types: |
|
junks.extend(glob.glob(files)) |
|
try: |
|
|
|
for junk in junks: |
|
print("Deleting",junk) |
|
|
|
file = pathlib.Path(junk) |
|
|
|
file.unlink() |
|
except Exception: |
|
print("I cannot delete the file because it is being used by another process") |
|
|
|
|
|
def clean_data(): |
|
|
|
import sys, os |
|
|
|
home_dir = os.getcwd() |
|
|
|
fd = 'sample_data/' |
|
|
|
path_to_clean=os.path.join(home_dir,fd) |
|
print("Path to clean:",path_to_clean) |
|
|
|
try: |
|
os.chdir(path_to_clean) |
|
print("Inside to clean", os.getcwd()) |
|
cleanup() |
|
|
|
except: |
|
print("Something wrong with specified\ |
|
directory. Exception- ", sys.exc_info()) |
|
|
|
finally: |
|
print("Restoring the path") |
|
os.chdir(home_dir) |
|
print("Current directory is-", os.getcwd()) |
|
|
|
def youtube_trim(url,start,end): |
|
|
|
cleanup() |
|
|
|
|
|
input_videos=download_video(url) |
|
|
|
parent_dir = os.getcwd() |
|
|
|
start = start |
|
end = end |
|
|
|
|
|
interval = time_between(start, end) |
|
|
|
|
|
trimmed_video= parent_dir+'/sample_data/input_video.mp4' |
|
trimmed_audio= parent_dir+'/sample_data/input_audio.mp3' |
|
|
|
clean_data() |
|
|
|
call(["ffmpeg","-y","-i",input_videos,"-ss", start,"-t",interval,"-async","1",trimmed_video]) |
|
|
|
|
|
call(["ffmpeg","-i",trimmed_video, "-q:a", "0", "-map","a",trimmed_audio]) |
|
|
|
|
|
print("Trimmed Video+Audio") |
|
return trimmed_video, trimmed_audio |
|
|
|
def create_video(Text,Voicetoclone): |
|
out_audio=greet(Text,Voicetoclone) |
|
current_dir=os.getcwd() |
|
clonned_audio = os.path.join(current_dir, out_audio) |
|
|
|
|
|
|
|
pad_top = 0 |
|
pad_bottom = 10 |
|
pad_left = 0 |
|
pad_right = 0 |
|
rescaleFactor = 1 |
|
nosmooth = False |
|
|
|
out_name ="result_voice.mp4" |
|
out_file="../"+out_name |
|
|
|
if nosmooth == False: |
|
is_command_ok = os.system('{} cd Wav2Lip && python inference.py --checkpoint_path checkpoints/wav2lip_gan.pth --face "../sample_data/input_video.mp4" --audio "../out/clonned_audio.wav" --outfile {} --pads {} {} {} {} --resize_factor {}'.format(env,out_file,pad_top ,pad_bottom ,pad_left ,pad_right ,rescaleFactor)) |
|
else: |
|
is_command_ok = os.system('{} cd Wav2Lip && python inference.py --checkpoint_path checkpoints/wav2lip_gan.pth --face "../sample_data/input_video.mp4" --audio "../out/clonned_audio.wav" --outfile {} --pads {} {} {} {} --resize_factor {} --nosmooth'.format(env,out_file,pad_top ,pad_bottom ,pad_left ,pad_right ,rescaleFactor)) |
|
|
|
if is_command_ok > 0: |
|
print("Error : Ensure the video contains a face in all the frames.") |
|
out_file="./demo/tryagain1.mp4" |
|
return out_file |
|
else: |
|
print("OK") |
|
|
|
print("Creation of video done!") |
|
return out_name |
|
|
|
|
|
def time_format_check(input1): |
|
timeformat = "%H:%M:%S" |
|
|
|
try: |
|
validtime = datetime.strptime(input1, timeformat) |
|
print("The time format is valid", input1) |
|
|
|
return False |
|
except ValueError: |
|
print("The time {} has not valid format hh:mm:ss".format(input1)) |
|
return True |
|
|
|
|
|
def to_seconds(datetime_obj): |
|
from datetime import datetime |
|
time =datetime_obj |
|
date_time = datetime.strptime(time, "%H:%M:%S") |
|
a_timedelta = date_time - datetime(1900, 1, 1) |
|
seconds = a_timedelta.total_seconds() |
|
return seconds |
|
|
|
|
|
def validate_youtube(url): |
|
|
|
try: |
|
yt = YouTube(url) |
|
except Exception: |
|
print("Hi there URL seems invalid") |
|
return True, 0 |
|
|
|
video_length = yt.length |
|
if video_length > 600: |
|
print("Your video is larger than 10 minutes") |
|
return True, video_length |
|
else: |
|
print("Your video is less than 10 minutes") |
|
return False, video_length |
|
|
|
|
|
def video_generator(text_to_say,url,initial_time,final_time): |
|
print('Checking the url',url) |
|
check1, video_length = validate_youtube(url) |
|
if check1 is True: return "./demo/tryagain2.mp4" |
|
check2 = validate_time(initial_time,final_time, video_length) |
|
if check2 is True: return "./demo/tryagain0.mp4" |
|
trimmed_video, trimmed_audio=youtube_trim(url,initial_time,final_time) |
|
voicetoclone=trimmed_audio |
|
print(voicetoclone) |
|
outvideo=create_video(text_to_say,voicetoclone) |
|
|
|
print("Final Video Preview") |
|
final_video= parent_dir+'/'+outvideo |
|
print("DONE") |
|
|
|
return final_video |
|
|
|
|
|
def validate_time(initial_time,final_time,video_length): |
|
is_wrong1=time_format_check(initial_time) |
|
is_wrong2=time_format_check(final_time) |
|
|
|
if is_wrong1 is False and is_wrong2 is False: |
|
delta=time_between(initial_time,final_time) |
|
if len(str(delta)) > 8: |
|
print("Final Time is Smaller than Initial Time: t1>t2") |
|
is_wrong = True |
|
return is_wrong |
|
else: |
|
print("OK") |
|
is_wrong=False |
|
if int(to_seconds(delta)) > 300 : |
|
print("The trim is larger than 5 minutes") |
|
is_wrong = True |
|
return is_wrong |
|
|
|
elif int(to_seconds(delta)) > video_length : |
|
print("The trim is larger than video lenght") |
|
is_wrong = True |
|
return is_wrong |
|
else: |
|
return is_wrong |
|
|
|
else: |
|
print("Your time format is invalid") |
|
is_wrong = True |
|
return is_wrong |
|
|
|
|
|
|
|
text_to_say=gr.inputs.Textbox(label='What would you like the voice to say? (max. 2000 characters per request)') |
|
url =gr.inputs.Textbox(label = "Enter the YouTube URL below:") |
|
initial_time = gr.inputs.Textbox(label='Initial time of trim? (format: hh:mm:ss)') |
|
final_time= gr.inputs.Textbox(label='Final time to trim? (format: hh:mm:ss)') |
|
gr.Interface(fn = video_generator, |
|
inputs = [text_to_say,url,initial_time,final_time], |
|
outputs = 'video', |
|
verbose = True, |
|
title = 'Video Speech Generator from Youtube Videos', |
|
description = 'A simple application that replaces the original speech of the video by your text. Wait one minute to process.', |
|
article = |
|
'''<div> |
|
<p style="text-align: center"> |
|
All you need to do is to paste the Youtube link and |
|
set the initial time and final time of the real speach. |
|
(The limit of the trim is 5 minutes and not larger than video length) |
|
hit submit, then wait for compiling. |
|
After that click on Play/Pause for listing to the video. |
|
The video is saved in an mp4 format. |
|
For more information visit <a href="https://ruslanmv.com/">ruslanmv.com</a> |
|
</p> |
|
</div>''', |
|
enable_queue=True, |
|
examples = [['I am clonning your voice. Charles!. Machine intelligence is the last invention that humanity will ever need to make.', |
|
"https://www.youtube.com/watch?v=xw5dvItD5zY", |
|
"00:00:01","00:00:10"], |
|
['I am clonning your voice. Jim Carrey!. Machine intelligence is the last invention that humanity will ever need to make.', |
|
"https://www.youtube.com/watch?v=uIaY0l5qV0c", |
|
"00:00:29", "00:01:05"], |
|
['I am clonning your voice. Mark Zuckerberg!. Machine intelligence is the last invention that humanity will ever need to make.', |
|
"https://www.youtube.com/watch?v=AYjDIFrY9rc", |
|
"00:00:11", "00:00:44"], |
|
['I am clonning your voice. Ronald Reagan!. Machine intelligence is the last invention that humanity will ever need to make.', |
|
"https://www.youtube.com/watch?v=iuoRDY9c5SQ", |
|
"00:01:03", "00:01:22"], |
|
['I am clonning your voice. Elon Musk!. Machine intelligence is the last invention that humanity will ever need to make.', |
|
"https://www.youtube.com/watch?v=IZ8JQ_1gytg", |
|
"00:00:10", "00:00:43"], |
|
['I am clonning your voice. Hitler!. Machine intelligence is the last invention that humanity will ever need to make.', |
|
"https://www.youtube.com/watch?v=F08wrLyH5cs", |
|
"00:00:15", "00:00:40"], |
|
['I am clonning your voice. Alexandria!. Machine intelligence is the last invention that humanity will ever need to make.', |
|
"https://www.youtube.com/watch?v=Eht6oIkzkew", |
|
"00:00:02", "00:00:30"], |
|
], |
|
allow_flagging=False |
|
).launch() |
|
|
|
|