{ "nbformat": 4, "nbformat_minor": 0, "metadata": { "colab": { "name": "Wav2Lip.ipynb", "provenance": [], "collapsed_sections": [] }, "kernelspec": { "name": "python3", "display_name": "Python 3" }, "language_info": { "name": "python" }, "accelerator": "GPU", "gpuClass": "standard" }, "cells": [ { "cell_type": "code", "source": [ "!git clone https://github.com/ajay-sainy/Wav2Lip-GFPGAN.git\n", "basePath = \"/content/Wav2Lip-GFPGAN\"\n", "%cd {basePath}" ], "metadata": { "id": "YhFe3CJGAIiV" }, "execution_count": null, "outputs": [] }, { "cell_type": "code", "source": [ "wav2lipFolderName = 'Wav2Lip-master'\n", "gfpganFolderName = 'GFPGAN-master'\n", "wav2lipPath = basePath + '/' + wav2lipFolderName\n", "gfpganPath = basePath + '/' + gfpganFolderName\n", "\n", "!wget 'https://www.adrianbulat.com/downloads/python-fan/s3fd-619a316812.pth' -O {wav2lipPath}'/face_detection/detection/sfd/s3fd.pth'\n", "!gdown https://drive.google.com/uc?id=1fQtBSYEyuai9MjBOF8j7zZ4oQ9W2N64q --output {wav2lipPath}'/checkpoints/'" ], "metadata": { "id": "mH7A_OaFUs8U" }, "execution_count": null, "outputs": [] }, { "cell_type": "code", "source": [ "!pip install -r requirements.txt" ], "metadata": { "id": "CAJqWQS17Qk1" }, "execution_count": null, "outputs": [] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "EqX_2YtkUjRI" }, "outputs": [], "source": [ "import os\n", "outputPath = basePath+'/outputs'\n", "inputAudioPath = basePath + '/inputs/kim_audio.mp3'\n", "inputVideoPath = basePath + '/inputs/kimk_7s_raw.mp4'\n", "lipSyncedOutputPath = basePath + '/outputs/result.mp4'\n", "\n", "if not os.path.exists(outputPath):\n", " os.makedirs(outputPath)\n", "\n", "!cd $wav2lipFolderName && python inference.py \\\n", "--checkpoint_path checkpoints/wav2lip.pth \\\n", "--face {inputVideoPath} \\\n", "--audio {inputAudioPath} \\\n", "--outfile {lipSyncedOutputPath}" ] }, { "cell_type": "code", "source": [ "!cd $gfpganFolderName && python setup.py develop\n", "!wget https://github.com/TencentARC/GFPGAN/releases/download/v1.3.0/GFPGANv1.3.pth -P {gfpganFolderName}'/experiments/pretrained_models'" ], "metadata": { "id": "PPBew5FGGvP9" }, "execution_count": null, "outputs": [] }, { "cell_type": "code", "source": [ "import cv2\n", "from tqdm import tqdm\n", "from os import path\n", "\n", "import os\n", "\n", "inputVideoPath = outputPath+'/result.mp4'\n", "unProcessedFramesFolderPath = outputPath+'/frames'\n", "\n", "if not os.path.exists(unProcessedFramesFolderPath):\n", " os.makedirs(unProcessedFramesFolderPath)\n", "\n", "vidcap = cv2.VideoCapture(inputVideoPath)\n", "numberOfFrames = int(vidcap.get(cv2.CAP_PROP_FRAME_COUNT))\n", "fps = vidcap.get(cv2.CAP_PROP_FPS)\n", "print(\"FPS: \", fps, \"Frames: \", numberOfFrames)\n", "\n", "for frameNumber in tqdm(range(numberOfFrames)):\n", " _,image = vidcap.read()\n", " cv2.imwrite(path.join(unProcessedFramesFolderPath, str(frameNumber).zfill(4)+'.jpg'), image)\n" ], "metadata": { "id": "X_RNegAcISU2" }, "execution_count": null, "outputs": [] }, { "cell_type": "code", "source": [ "!cd $gfpganFolderName && \\\n", " python inference_gfpgan.py -i $unProcessedFramesFolderPath -o $outputPath -v 1.3 -s 2 --only_center_face --bg_upsampler None" ], "metadata": { "id": "k6krjfxTJYlu" }, "execution_count": null, "outputs": [] }, { "cell_type": "code", "source": [ "import os\n", "restoredFramesPath = outputPath + '/restored_imgs/'\n", "processedVideoOutputPath = outputPath\n", "\n", "dir_list = os.listdir(restoredFramesPath)\n", "dir_list.sort()\n", "\n", "import cv2\n", "import numpy as np\n", "\n", "batch = 0\n", "batchSize = 300\n", "from tqdm import tqdm\n", "for i in tqdm(range(0, len(dir_list), batchSize)):\n", " img_array = []\n", " start, end = i, i+batchSize\n", " print(\"processing \", start, end)\n", " for filename in tqdm(dir_list[start:end]):\n", " filename = restoredFramesPath+filename;\n", " img = cv2.imread(filename)\n", " if img is None:\n", " continue\n", " height, width, layers = img.shape\n", " size = (width,height)\n", " img_array.append(img)\n", "\n", "\n", " out = cv2.VideoWriter(processedVideoOutputPath+'/batch_'+str(batch).zfill(4)+'.avi',cv2.VideoWriter_fourcc(*'DIVX'), 30, size)\n", " batch = batch + 1\n", " \n", " for i in range(len(img_array)):\n", " out.write(img_array[i])\n", " out.release()\n" ], "metadata": { "id": "XibzGPIVJfvP" }, "execution_count": null, "outputs": [] }, { "cell_type": "code", "source": [ "concatTextFilePath = outputPath + \"/concat.txt\"\n", "concatTextFile=open(concatTextFilePath,\"w\")\n", "for ips in range(batch):\n", " concatTextFile.write(\"file batch_\" + str(ips).zfill(4) + \".avi\\n\")\n", "concatTextFile.close()\n", "\n", "concatedVideoOutputPath = outputPath + \"/concated_output.avi\"\n", "!ffmpeg -y -f concat -i {concatTextFilePath} -c copy {concatedVideoOutputPath} \n", "\n", "finalProcessedOuputVideo = processedVideoOutputPath+'/final_with_audio.avi'\n", "!ffmpeg -y -i {concatedVideoOutputPath} -i {inputAudioPath} -map 0 -map 1:a -c:v copy -shortest {finalProcessedOuputVideo}\n", "\n", "from google.colab import files\n", "files.download(finalProcessedOuputVideo)" ], "metadata": { "id": "jtde28qwpDd6" }, "execution_count": null, "outputs": [] } ] }