| |
| """ |
| Script para executar lip sync com MuseTalk V1.5. |
| Uso: python run_lipsync.py --video input.mp4 --audio audio.wav --output output.mp4 |
| """ |
|
|
| import argparse |
| import os |
| import subprocess |
| import tempfile |
| import yaml |
|
|
|
|
| def create_config(video_path: str, audio_path: str, bbox_shift: int = 5) -> str: |
| """Cria arquivo de configuracao temporario para o MuseTalk.""" |
|
|
| config = { |
| 'task_0': { |
| 'video_path': os.path.abspath(video_path), |
| 'audio_path': os.path.abspath(audio_path), |
| 'bbox_shift': bbox_shift |
| } |
| } |
|
|
| |
| config_file = tempfile.NamedTemporaryFile( |
| mode='w', |
| suffix='.yaml', |
| delete=False |
| ) |
| yaml.dump(config, config_file) |
| config_file.close() |
|
|
| return config_file.name |
|
|
|
|
| def run_lipsync(video_path: str, audio_path: str, output_dir: str, bbox_shift: int = 5): |
| """Executa lip sync usando MuseTalk.""" |
|
|
| |
| if not os.path.exists(video_path): |
| raise FileNotFoundError(f"Video nao encontrado: {video_path}") |
| if not os.path.exists(audio_path): |
| raise FileNotFoundError(f"Audio nao encontrado: {audio_path}") |
|
|
| |
| config_path = create_config(video_path, audio_path, bbox_shift) |
| print(f"Config criado: {config_path}") |
|
|
| |
| os.makedirs(output_dir, exist_ok=True) |
|
|
| |
| musetalk_dir = os.environ.get('MUSETALK_DIR', '/root/musetalk-space') |
|
|
| |
| cmd = [ |
| 'python3', '-m', 'scripts.inference', |
| '--inference_config', config_path, |
| '--result_dir', output_dir |
| ] |
|
|
| print(f"Executando: {' '.join(cmd)}") |
| print(f"Diretorio: {musetalk_dir}") |
|
|
| result = subprocess.run( |
| cmd, |
| cwd=musetalk_dir, |
| capture_output=False |
| ) |
|
|
| |
| os.unlink(config_path) |
|
|
| if result.returncode != 0: |
| raise RuntimeError(f"MuseTalk falhou com codigo {result.returncode}") |
|
|
| |
| video_name = os.path.splitext(os.path.basename(video_path))[0] |
| audio_name = os.path.splitext(os.path.basename(audio_path))[0] |
| expected_output = os.path.join(output_dir, 'v15', f'{video_name}_{audio_name}.mp4') |
|
|
| if os.path.exists(expected_output): |
| print(f"Video gerado: {expected_output}") |
| return expected_output |
| else: |
| |
| for f in os.listdir(os.path.join(output_dir, 'v15')): |
| if f.endswith('.mp4'): |
| return os.path.join(output_dir, 'v15', f) |
|
|
| return None |
|
|
|
|
| def main(): |
| parser = argparse.ArgumentParser(description='Executar lip sync com MuseTalk') |
| parser.add_argument('--video', '-v', required=True, help='Video de entrada') |
| parser.add_argument('--audio', '-a', required=True, help='Audio para sincronizar') |
| parser.add_argument('--output', '-o', default='./lipsync_output', help='Diretorio de saida') |
| parser.add_argument('--bbox-shift', '-b', type=int, default=5, help='Ajuste do bounding box') |
|
|
| args = parser.parse_args() |
|
|
| output = run_lipsync( |
| video_path=args.video, |
| audio_path=args.audio, |
| output_dir=args.output, |
| bbox_shift=args.bbox_shift |
| ) |
|
|
| if output: |
| print(f"\nSucesso! Video salvo em: {output}") |
| else: |
| print("\nErro: Nenhum video foi gerado") |
|
|
|
|
| if __name__ == '__main__': |
| main() |
|
|