├── .gitignore ├── update_libs.bat ├── exec_videos_converter.bat ├── requirements.txt ├── __pycache__ └── utils.cpython-310.pyc ├── utils.py ├── README.md └── main.py /.gitignore: -------------------------------------------------------------------------------- 1 | .env 2 | .venv 3 | __pycache__ -------------------------------------------------------------------------------- /update_libs.bat: -------------------------------------------------------------------------------- 1 | pip install -r requirements.txt. 2 | pause -------------------------------------------------------------------------------- /exec_videos_converter.bat: -------------------------------------------------------------------------------- 1 | python main.py 2 | cmd /k 3 | pause -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | colorama 2 | pyfiglet 3 | rich 4 | tqdm 5 | halo -------------------------------------------------------------------------------- /__pycache__/utils.cpython-310.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/viniped/vidconverter/HEAD/__pycache__/utils.cpython-310.pyc -------------------------------------------------------------------------------- /utils.py: -------------------------------------------------------------------------------- 1 | import os 2 | import subprocess 3 | from pathlib import Path 4 | 5 | video_extensions = [ 6 | '.mp4', '.ts', '.mpg', '.mpeg', '.avi', '.mkv', '.flv', '.3gp', 7 | '.rmvb', '.webm', '.vob', '.ogv', '.rrc', '.gifv', '.mng', 8 | '.mov', '.qt', '.wmv', '.yuv', '.rm', '.asf', '.amv', '.m4p', 9 | '.m4v', '.mp2', '.mpe', '.mpv', '.m4v', '.svi', '.3g2', 10 | '.mxf', '.roq', '.nsv', '.f4v', '.f4p', '.f4a', '.f4b' 11 | ] 12 | 13 | def has_duration(file_path): 14 | result = subprocess.run(['ffprobe', '-v', 'error', '-show_entries', 'format=duration', '-of', 'default=noprint_wrappers=1:nokey=1', str(file_path)], capture_output=True, text=True) 15 | duration = result.stdout.strip() 16 | return duration!= '' 17 | 18 | def file_is_corrupted(file_path): 19 | try: 20 | subprocess.run(['ffprobe', '-v', 'error', '-i', str(file_path)], check=False, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) 21 | except subprocess.CalledProcessError as e: 22 | if 'moov atom not found' in str(e): 23 | return True 24 | return False 25 | 26 | def delete_videos_without_duration(folder_path): 27 | folder_path = Path(folder_path) 28 | for path in folder_path.rglob('*'): 29 | if path.is_file() and path.suffix.lower() in video_extensions and (not has_duration(path) or file_is_corrupted(path)): 30 | print(f'Deleting {path}') 31 | os.remove(str(path)) 32 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | VidConverter 2 | 3 | Introdução 4 | O script VidConverter é um script em Python que permite ao usuário converter arquivos de vídeo em uma pasta de entrada especificada para o formato MP4 usando a biblioteca FFmpeg. 5 | 6 | Requisitos 7 | Antes de usar o script VidConverter, você precisa ter o seguinte instalado: 8 | 9 | Python 3.7.x 10 | 11 | FFmpeg: Certifique-se de que o executável do FFmpeg esteja disponível no PATH do sistema. 12 | Bibliotecas Utilizadas 13 | 14 | 15 | Funcionamento: 16 | 17 | Solicita ao usuário para inserir o caminho da pasta de entrada contendo os arquivos de vídeo a ser convertido. 18 | Define o caminho da pasta de saída como um subdiretório chamado "output" dentro do diretório do script. 19 | Itera por todas as subpastas e arquivos na pasta de entrada 20 | Verifica se cada arquivo é um arquivo de vídeo com extensões válidas. 21 | Converte cada arquivo de vídeo para o formato MP4 usando o FFmpeg e o salva na pasta de saída. 22 | Remove o arquivo de vídeo original após a conversão. 23 | 24 | 25 | Observação: A ferramenta de linha de comando ffmpeg é usada para a conversão de vídeo, portanto, certifique-se de que ela está corretamente instalada e acessível no PATH do sistema. 26 | 27 | 28 | Como Usar 29 | Certifique-se de ter o Python 3.x e o FFmpeg instalados em seu sistema. 30 | Instale as bibliotecas Python necessárias executando: pip install tqdm colorama pyfiglet ou use o arquivo update_libs.bat . 31 | Copie o script VidConverter para um diretório onde deseja converter arquivos de vídeo. 32 | Execute o script usando: python vid_converter.py. 33 | 34 | 35 | O script exibirá um banner colorido e solicitará que você insira o caminho da pasta de entrada. 36 | Após fornecer o caminho da pasta, o script converterá todos os arquivos de vídeo na pasta de entrada para o formato MP4 e os salvará no subdiretório "output". 37 | Importante: Certifique-se sempre de fazer backup de seus arquivos de vídeo antes de executar o script, pois ele removerá os arquivos originais após a conversão. 38 | 39 | Aviso Legal: 40 | 41 | O script VidConverter é fornecido "como está" e sem garantias. É sua responsabilidade garantir que você tenha os direitos e permissões necessários para realizar conversões de vídeo nos arquivos da pasta de entrada especificada. O autor do script não assume nenhuma responsabilidade por qualquer uso indevido ou danos causados pelo uso deste script. 42 | -------------------------------------------------------------------------------- /main.py: -------------------------------------------------------------------------------- 1 | import os 2 | import subprocess 3 | from halo import Halo 4 | from pathlib import Path 5 | from colorama import Fore 6 | import pyfiglet 7 | import random 8 | from tqdm import tqdm 9 | from utils import * 10 | 11 | spinner = Halo(text='Verificando vídeos para conversão...', spinner='dots') 12 | 13 | 14 | class Banner: 15 | def __init__(self, banner): 16 | self.banner = banner 17 | self.lg = Fore.LIGHTGREEN_EX 18 | self.w = Fore.WHITE 19 | self.cy = Fore.CYAN 20 | self.ye = Fore.YELLOW 21 | self.r = Fore.RED 22 | self.n = Fore.RESET 23 | 24 | def print_banner(self): 25 | colors = [self.lg, self.r, self.w, self.cy, self.ye] 26 | f = pyfiglet.Figlet(font='slant') 27 | banner = f.renderText(self.banner) 28 | print(f'{random.choice(colors)}{banner}{self.n}') 29 | print(f'{self.r} Version: v0.0.3 https://github.com/viniped/vidconverter \n{self.n}') 30 | 31 | 32 | def get_codec(file_path, stream_type): 33 | cmd = [ 34 | 'ffprobe', 35 | '-v', 'error', 36 | '-select_streams', f'{stream_type}:0', 37 | '-show_entries', 'stream=codec_name', 38 | '-of', 'default=noprint_wrappers=1:nokey=1', 39 | file_path 40 | ] 41 | codec = subprocess.check_output(cmd).decode('utf-8').strip() 42 | return codec 43 | 44 | 45 | def convert_file(file_path): 46 | video_codec = get_codec(file_path, 'v') 47 | audio_codec = get_codec(file_path, 'a') 48 | 49 | if video_codec == "h264" and audio_codec == "aac" and file_path.lower().endswith(".mp4"): 50 | return 51 | 52 | file_name, file_extension = os.path.splitext(file_path) 53 | output_file = f"{file_name}.mp4" 54 | 55 | cmd = [ 56 | 'ffmpeg', 57 | '-v', 'quiet', 58 | '-stats', 59 | '-y', 60 | '-i', file_path, 61 | '-b:a', '128k', 62 | '-hide_banner' 63 | ] 64 | 65 | if video_codec == "h264" and audio_codec == "aac": 66 | cmd.extend(['-c:v', 'copy', '-c:a', 'copy']) 67 | 68 | elif video_codec != "h264" and audio_codec == "aac": 69 | cmd.extend(['-c:v', 'libx264', '-preset', 'ultrafast', '-threads', '2', '-c:a', 'copy', '-crf', '23', '-maxrate', '4M']) 70 | 71 | elif video_codec == "h264" and audio_codec != "aac": 72 | cmd.extend(['-c:v', 'copy', '-c:a', 'aac', '-preset', 'ultrafast', '-threads', '2', '-crf', '23', '-maxrate', '4M']) 73 | 74 | elif video_codec != "h264" and audio_codec != "aac": 75 | cmd.extend(['-c:v', 'h264', '-c:a', 'aac', '-preset', 'ultrafast', '-threads', '2', '-crf', '23', '-maxrate', '4M']) 76 | 77 | else: 78 | cmd.extend(['-c:v', 'h264', '-c:a', 'aac', '-preset', 'ultrafast', '-threads', '2', '-crf', '23', '-maxrate', '4M']) 79 | 80 | cmd.append(output_file) 81 | 82 | subprocess.run(cmd) 83 | os.remove(file_path) 84 | 85 | 86 | def convert_videos_in_folder(folder_path): 87 | delete_videos_without_duration(folder_path) 88 | 89 | spinner.start() 90 | 91 | videos_to_convert = [] 92 | 93 | for subdir, _, files in os.walk(folder_path): 94 | for file in files: 95 | if file.lower().endswith(tuple(video_extensions)): 96 | file_path = os.path.join(subdir, file) 97 | video_codec = get_codec(file_path, 'v') 98 | audio_codec = get_codec(file_path, 'a') 99 | 100 | if not (video_codec == "h264" and audio_codec == "aac" and file_path.lower().endswith(".mp4")): 101 | videos_to_convert.append(file_path) 102 | 103 | spinner.stop() 104 | 105 | total_videos = len(videos_to_convert) 106 | 107 | if total_videos == 0: 108 | spinner.succeed("Todos os vídeos já estão no formato correto.") 109 | return 110 | else: 111 | spinner.info(f"{total_videos} vídeos precisam ser convertidos.") 112 | 113 | with tqdm(total=total_videos, desc="Convertendo vídeos") as pbar: 114 | for index, video_path in enumerate(videos_to_convert): 115 | convert_file(video_path) 116 | pbar.update(1) 117 | 118 | spinner.succeed("A conversão dos vídeos foi concluída.") 119 | 120 | 121 | def main(): 122 | try: 123 | banner = Banner('VidConverter') 124 | banner.print_banner() 125 | folder_path = input("Digite o caminho da pasta onde estão os vídeos: ") 126 | delete_videos_without_duration(folder_path) 127 | convert_videos_in_folder(folder_path) 128 | except KeyboardInterrupt: 129 | spinner.fail('Operação Interrompida pelo usuário') 130 | 131 | if __name__ == '__main__': 132 | main() 133 | --------------------------------------------------------------------------------