Created
October 3, 2026 10:43
-
-
Save bryanseah234/fe1fd62b9b56e7bfe0b6d049895df4cf to your computer and use it in GitHub Desktop.
removeaudio-code (Python utility for removing audio tracks from media files)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/usr/bin/env python3"""⚠️ DEPRECATED - DO NOT USE ⚠️This script has critical security vulnerabilities:- Command Injection (CVSS 9.8)- Path Traversal- Poor Error HandlingPlease use noaudio_secure.py instead.This file is kept for reference only."""import sysprint("=" * 70)print("⚠️ SECURITY WARNING ⚠️")print("=" * 70)print()print("This script (noaudio.py) has CRITICAL security vulnerabilities:")print(" - Command Injection (CVSS 9.8)")print(" - Path Traversal")print(" - Poor Error Handling")print()print("Please use noaudio_secure.py instead:")print(" python noaudio_secure.py")print()print("=" * 70)sys.exit(1) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| from os import errorimport subprocessimport osPOSSIBLE_EXTENSIONS = ["avi", "mp4", "mov"]#MAKE SURE DIRECTORY DOES NOT HAVE SPACESdirectory = input("Give directory path containing video footage: ")directory = directory.replace("\\", "/")print(f"Searching in {directory}")if os.path.exists(directory): try: for files in os.walk(directory): for l in files: for filename in l: if '.' in filename: ext = filename.split('.')[1] print(ext) if ext.lower() in POSSIBLE_EXTENSIONS: noaudio = "noaudio_" + filename oldpath = os.path.join(directory, filename) newpath = path = os.path.join(directory, noaudio) command = 'ffmpeg -i ' + oldpath + ' -c copy -an ' + newpath subprocess.call(command, shell=True) print('Removed audio') print('Done, exiting') except Exception as e: print(error, e) print('Error, exiting')else: print("No video footage found, try again with another directory path.") |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/usr/bin/env python3"""Secure video audio removal toolFixes: Command injection, path traversal, error handling"""import subprocessimport osimport sysfrom pathlib import Pathimport tempfilePOSSIBLE_EXTENSIONS = ["avi", "mp4", "mov"]def validate_directory(directory_path): """Validate and sanitize directory path""" try: # Convert to absolute path and resolve symlinks path = Path(directory_path).resolve() # Check if directory exists if not path.exists(): print(f"❌ Error: Directory does not exist: {path}") return None # Check if it's actually a directory if not path.is_dir(): print(f"❌ Error: Path is not a directory: {path}") return None # Check read permissions if not os.access(path, os.R_OK): print(f"❌ Error: No read permission for directory: {path}") return None return path except Exception as e: print(f"❌ Error validating directory: {e}") return Nonedef check_ffmpeg(): """Check if ffmpeg is installed and accessible""" try: result = subprocess.run( ["ffmpeg", "-version"], capture_output=True, text=True, timeout=5 ) if result.returncode == 0: return True else: print("❌ Error: ffmpeg is installed but not working correctly") return False except FileNotFoundError: print("❌ Error: ffmpeg is not installed or not in PATH") print("Please install ffmpeg:") print(" Windows: choco install ffmpeg") print(" macOS: brew install ffmpeg") print(" Linux: sudo apt-get install ffmpeg") return False except Exception as e: print(f"❌ Error checking ffmpeg: {e}") return Falsedef remove_audio_from_video(input_path, output_path): """ Remove audio from video file using ffmpeg Uses secure subprocess call with list arguments """ temporary_path = None try: input_path = Path(input_path) output_path = Path(output_path) if not input_path.is_file(): return False, "Input is not a readable video file" if output_path.exists() or output_path.is_symlink(): return False, "Output already exists; it was preserved" # Stage beside the destination so publication stays on one filesystem. descriptor, name = tempfile.mkstemp( prefix='.noaudio-', suffix=output_path.suffix, dir=output_path.parent ) os.close(descriptor) temporary_path = Path(name) # Build command as list (prevents command injection) command = [ "ffmpeg", "-nostdin", "-i", str(input_path), "-c", "copy", "-an", str(temporary_path), "-y" # Only overwrite this invocation's newly created staging file ] # Execute with shell=False (secure) result = subprocess.run( command, capture_output=True, text=True, encoding="utf-8", errors="replace", timeout=300 # 5 minute timeout ) if result.returncode == 0: if not temporary_path.is_file() or temporary_path.stat().st_size == 0: return False, "FFmpeg did not produce a non-empty video" # Both operations fail if another writer created the destination. # POSIX rename would overwrite it, so use an atomic hard link there. if os.name == 'nt': os.rename(temporary_path, output_path) else: os.link(temporary_path, output_path) return True, "Success" else: return False, f"ffmpeg error: {result.stderr}" except subprocess.TimeoutExpired: return False, "Timeout: Video processing took too long" except Exception as e: return False, f"Error: {str(e)}" finally: if temporary_path is not None: try: temporary_path.unlink(missing_ok=True) except OSError: print(f"⚠️ Could not remove temporary output: {temporary_path}")def process_directory(directory): """Process all video files in directory""" processed = 0 failed = 0 skipped = 0 print(f"🔍 Searching for video files in: {directory}") print(f"📹 Looking for extensions: {', '.join(POSSIBLE_EXTENSIONS)}") print() # Walk through directory for root, dirs, files in os.walk(directory): for filename in files: # Check if file has valid extension if '.' not in filename: continue ext = filename.rsplit('.', 1)[-1].lower() if ext not in POSSIBLE_EXTENSIONS: continue # Skip files that already have "noaudio_" prefix if filename.startswith(("noaudio_", ".noaudio-")): skipped += 1 continue # Build paths input_path = Path(root) / filename output_filename = f"noaudio_{filename}" output_path = Path(root) / output_filename # Check if output file already exists if output_path.exists(): print(f"⏭️ Skipping (output exists): {filename}") skipped += 1 continue print(f"🎬 Processing: {filename}") # Remove audio success, message = remove_audio_from_video(input_path, output_path) if success: print(f"✅ Success: {output_filename}") processed += 1 else: print(f"❌ Failed: {filename} - {message}") failed += 1 print() # Summary print("=" * 60) print("📊 PROCESSING SUMMARY") print("=" * 60) print(f"✅ Processed successfully: {processed}") print(f"❌ Failed: {failed}") print(f"⏭️ Skipped: {skipped}") print(f"📁 Total files: {processed + failed + skipped}") print() return {"processed": processed, "failed": failed, "skipped": skipped}def main(): """Main execution flow""" print("=" * 60) print("🎬 VIDEO AUDIO REMOVAL TOOL") print("=" * 60) print() # Check ffmpeg print("🔧 Checking dependencies...") if not check_ffmpeg(): sys.exit(1) print("✅ ffmpeg is installed and working") print() # Get directory from user directory_input = input("📁 Enter directory path containing video files: ").strip() # Validate directory directory = validate_directory(directory_input) if directory is None: sys.exit(1) print(f"✅ Directory validated: {directory}") print() # Confirm before processing response = input("⚠️ This will create new files with 'noaudio_' prefix. Continue? (yes/no): ") if response.lower() != "yes": print("❌ Operation cancelled by user") sys.exit(0) print() # Process directory try: counts = process_directory(directory) if counts["failed"]: print("❌ Some videos failed; completed outputs were preserved.") sys.exit(1) print("✅ Done!") except KeyboardInterrupt: print("\n\n⚠️ Operation interrupted by user") sys.exit(1) except Exception as e: print(f"\n\n❌ Unexpected error: {e}") sys.exit(1)if __name__ == "__main__": main() |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| """Exercise conversion failures with synthetic files and a fake FFmpeg process."""import contextlibimport iofrom pathlib import Pathimport subprocessfrom tempfile import TemporaryDirectoryimport unittestfrom unittest.mock import patchimport noaudio_secure as audioclass AudioOutputTests(unittest.TestCase): def setUp(self): self.temporary = TemporaryDirectory() self.addCleanup(self.temporary.cleanup) self.root = Path(self.temporary.name) self.source = self.root / 'synthetic input.mp4' self.source.write_bytes(b'synthetic original video') self.output = self.root / 'noaudio_synthetic input.mp4' self.console = io.StringIO() def convert(self, fake): with patch.object(audio.subprocess, 'run', side_effect=fake) as process: result = audio.remove_audio_from_video(self.source, self.output) self.assertEqual(self.source.read_bytes(), b'synthetic original video') return result, process def test_success_publishes_finished_file_and_cleans_staging(self): def success(command, **kwargs): self.assertEqual(kwargs['timeout'], 300) self.assertIn('-nostdin', command) target = Path(command[-2]) self.assertNotEqual(target, self.output) self.assertFalse(self.output.exists()) target.write_bytes(b'complete muted video') return subprocess.CompletedProcess(command, 0, '', '') result, _ = self.convert(success) self.assertEqual(result, (True, 'Success')) self.assertEqual(self.output.read_bytes(), b'complete muted video') self.assertEqual(set(self.root.iterdir()), {self.source, self.output}) def test_failed_conversion_leaves_no_completed_output(self): def failure(command, **kwargs): Path(command[-2]).write_bytes(b'incomplete video') return subprocess.CompletedProcess(command, 1, '', 'synthetic conversion error') result, _ = self.convert(failure) self.assertFalse(result[0]) self.assertFalse(self.output.exists()) self.assertEqual(list(self.root.iterdir()), [self.source]) def test_timeout_removes_only_its_temporary_file(self): def timeout(command, **kwargs): Path(command[-2]).write_bytes(b'incomplete video') raise subprocess.TimeoutExpired(command, kwargs['timeout']) result, _ = self.convert(timeout) self.assertFalse(result[0]) self.assertFalse(self.output.exists()) self.assertEqual(list(self.root.iterdir()), [self.source]) def test_existing_output_is_preserved_without_starting_ffmpeg(self): self.output.write_bytes(b'existing user output') result, process = self.convert(AssertionError('Must not start FFmpeg')) self.assertFalse(result[0]) process.assert_not_called() self.assertEqual(self.output.read_bytes(), b'existing user output') def test_empty_success_is_not_published(self): result, _ = self.convert(lambda command, **kwargs: subprocess.CompletedProcess(command, 0, '', '')) self.assertFalse(result[0]) self.assertEqual(list(self.root.iterdir()), [self.source]) def test_interrupt_cleans_staging_and_propagates(self): def interrupt(command, **kwargs): Path(command[-2]).write_bytes(b'incomplete video') raise KeyboardInterrupt with self.assertRaises(KeyboardInterrupt): self.convert(interrupt) self.assertEqual(list(self.root.iterdir()), [self.source]) self.assertEqual(self.source.read_bytes(), b'synthetic original video') def test_output_created_during_conversion_is_not_overwritten(self): def race(command, **kwargs): Path(command[-2]).write_bytes(b'new muted video') self.output.write_bytes(b'concurrent user output') return subprocess.CompletedProcess(command, 0, '', '') result, _ = self.convert(race) self.assertFalse(result[0]) self.assertEqual(self.output.read_bytes(), b'concurrent user output') self.assertEqual(set(self.root.iterdir()), {self.source, self.output}) def test_directory_reports_failures_and_preserves_existing_outputs(self): other = self.root / 'other.MOV' other.write_bytes(b'synthetic other') self.output.write_bytes(b'existing output') (self.root / '.noaudio-interrupted.mp4').write_bytes(b'old incomplete temporary video') with patch.object(audio, 'remove_audio_from_video', return_value=(False, 'synthetic error')) as convert: with contextlib.redirect_stdout(self.console): counts = audio.process_directory(self.root) self.assertEqual(counts, {'processed': 0, 'failed': 1, 'skipped': 3}) convert.assert_called_once_with(other, self.root / 'noaudio_other.MOV') def test_cli_reports_failed_batch_with_nonzero_exit(self): with patch.object(audio, 'check_ffmpeg', return_value=True), \ patch.object(audio, 'validate_directory', return_value=self.root), \ patch.object(audio, 'process_directory', return_value={'processed': 0, 'failed': 1, 'skipped': 0}), \ patch('builtins.input', side_effect=[str(self.root), 'yes']), \ contextlib.redirect_stdout(self.console): with self.assertRaises(SystemExit) as raised: audio.main() self.assertEqual(raised.exception.code, 1) self.assertNotIn('Done!', self.console.getvalue())if __name__ == '__main__': unittest.main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment