Skip to content

Instantly share code, notes, and snippets.

@CrashedBboy
Last active October 26, 2023 13:58
Show Gist options
  • Save CrashedBboy/79ae45a323bd4a211f9706b77e3aabe5 to your computer and use it in GitHub Desktop.
Save CrashedBboy/79ae45a323bd4a211f9706b77e3aabe5 to your computer and use it in GitHub Desktop.
FFMPEG Compression Commands
import json, sys, os, subprocess
def isNumber(i):
if type(i) == int or type(i) == float:
return True
else:
return False
def isVideo(filename):
chunks = filename.split(".")
ext = chunks[-1].upper()
if ext == "MP4" or ext == "MOV":
return True
else:
return False
if len(sys.argv) != 2:
print("Incorrect path for config file")
exit()
config_path = sys.argv[1]
print("Reading configuration:" + config_path)
config_file = open(config_path)
configs = json.load(config_file)
source_dir = configs['source']
if not os.path.exists(source_dir):
print("source path not found: " + source_dir)
exit()
dest_dir = configs['destination']
if dest_dir == "":
dest_dir = os.path.join(source_dir, "austin_exported")
crf = configs['crf']
if crf == "" or not isNumber(crf):
print("Illegal CRF: ", crf)
exit()
# CRF should be somewhere between 1-51
crf = int(crf)
if crf > 51 or crf < 1:
print("Illegal CRF: ", crf, ", reset to 28")
crf = 28
print("* Source directory:\t\t\t", source_dir)
print("* Destination directory: \t\t", dest_dir)
print("* HEVC CRF:\t", crf)
input("\n\nPress Enter to continue...")
# create export directory
os.makedirs(dest_dir, exist_ok=True)
source_videos = []
for entry in os.listdir(source_dir):
if os.path.isfile(os.path.join(source_dir, entry)):
if (isVideo(entry)):
source_videos.append(entry)
verbose_prefix = "[//]"
print(verbose_prefix, "Total videos: ", len(source_videos))
for idx, video in enumerate(source_videos):
src_video_path = os.path.join(source_dir, video)
dest_video_path = os.path.join(dest_dir, video)
subprocess.run(["ffmpeg.exe", "-i", src_video_path, "-map_metadata", "0", "-c:v", "libx265", "-tag:v", "hvc1", "-crf", str(crf), dest_video_path])
# ffmpeg.exe -i input_video -map_metadata 0 -c:v libx265 -tag:v hvc1 -crf 20 output.MP4
source_size = os.stat(src_video_path).st_size
dest_size = os.stat(dest_video_path).st_size
if dest_size > source_size:
# remove the bigger dest video
os.remove(dest_video_path)
print(f'[{idx+1}/{len(source_videos)}] {video}')
import json, sys, os, subprocess, math
from datetime import datetime
def isNumber(i):
if type(i) == int or type(i) == float:
return True
else:
return False
def isVideo(filename):
chunks = filename.split(".")
ext = chunks[-1].upper()
if ext == "MP4" or ext == "MOV":
return True
else:
return False
def appendToFile(filename, s):
with open(filename, "a", encoding='utf-8') as f:
f.write(f"{str(s)}\n")
DRY_RUN = False
if len(sys.argv) != 2:
print("Incorrect path for config file")
exit()
# Config reading
config_path = sys.argv[1]
print("Reading configuration:" + config_path)
config_file = open(config_path)
configs = json.load(config_file)
root_dir = configs['recursive']['root_dir']
if not os.path.exists(root_dir):
print("root path not found: " + root_dir)
exit()
# Create log file
datetime_str = datetime.now().strftime("%Y%m%d_%H%M%S")
log_path = os.path.join(root_dir, f"video_convert_{datetime_str}.log")
# Reading CRF
crf = configs['crf']
if crf == "" or not isNumber(crf):
print(f"Illegal CRF: {crf}")
appendToFile(log_path, f"Illegal CRF: {crf}")
exit()
# CRF should be somewhere between 1-51
crf = int(crf)
if crf > 51 or crf < 1:
print(f"Illegal CRF: {crf}, it should be somewhere between 1 and 51")
appendToFile(log_path, f"Illegal CRF: {crf}, it should be somewhere between 1 and 51")
exit()
else:
appendToFile(log_path, f"CRF: {crf}")
print(f"* Root directory:\t\t\t: {root_dir}")
print(f"* Conversion log:\t\t\t: {log_path}")
print(f"* HEVC CRF:\t\t\t\t: {crf}")
input("\n\nPress Enter to continue...")
for current_dir, under_dirs, under_files in os.walk(root_dir):
appendToFile(log_path, f"Processing directory: {current_dir}")
source_videos = []
for entry in under_files:
if (isVideo(entry)):
source_videos.append(entry)
if len(source_videos) == 0:
continue
# create export directory
export_dir = os.path.join(current_dir, f"austin_export")
if not DRY_RUN:
os.makedirs(export_dir, exist_ok=True)
appendToFile(log_path, f"\tTotal videos: {len(source_videos)}")
for idx, video in enumerate(source_videos):
src_video_path = os.path.join(current_dir, video)
dest_video_path = os.path.join(export_dir, video).replace(".mov", ".MP4").replace(".MOV", ".MP4")
appendToFile(log_path, f"\t[{idx+1}/{len(source_videos)}] {video}, converting to {dest_video_path}")
if not DRY_RUN:
subprocess.run(["ffmpeg.exe", "-i", src_video_path, "-map_metadata", "0", "-c:v", "libx265", "-tag:v", "hvc1", "-crf", str(crf), dest_video_path])
# ffmpeg.exe -i input_video -map_metadata 0 -c:v libx265 -tag:v hvc1 -crf 20 output.MP4
source_size = os.stat(src_video_path).st_size # in bytes
dest_size = os.stat(dest_video_path).st_size
if dest_size > source_size:
# remove the bigger dest video
os.remove(dest_video_path)
appendToFile(log_path, f"\t[{idx+1}/{len(source_videos)}] {video}, from {math.floor(source_size/(1024*1024))}MB to {math.floor(dest_size/(1024*1024))}MB")
{
"source": "F:\\Picture\\2017_05_USA",
"destination": "",
"crf": 24,
"recursive": {
"root_dir": "C:\\Users\\CrashedBboy\\CODING\\video-convert\\recursive_test"
}
}
CRF: 24
Processing directory: C:\Users\CrashedBboy\CODING\video-convert\recursive_test
Total videos: 0
Processing directory: C:\Users\CrashedBboy\CODING\video-convert\recursive_test\trip1
Total videos: 1
[1/1] GOPR2185.MP4, converting to C:\Users\CrashedBboy\CODING\video-convert\recursive_test\trip1\austin_export\GOPR2185.MP4
[1/1] GOPR2185.MP4, from 13MB to 11MB
Processing directory: C:\Users\CrashedBboy\CODING\video-convert\recursive_test\trip2
Total videos: 2
[1/2] GOPR2080.MP4, converting to C:\Users\CrashedBboy\CODING\video-convert\recursive_test\trip2\austin_export\GOPR2080.MP4
[1/2] GOPR2080.MP4, from 19MB to 5MB
[2/2] GOPR2183.MP4, converting to C:\Users\CrashedBboy\CODING\video-convert\recursive_test\trip2\austin_export\GOPR2183.MP4
[2/2] GOPR2183.MP4, from 11MB to 2MB
# -map_metadata 0: copy metadata
# -c:v libx265: use H265 encoding
# -tag:v hvc1: make your file compatible with Apple "industry standard" H.265
# -filter:v fps=30: set fps to 30
ffmpeg -i input_video -map_metadata 0 -c:v libx265 -tag:v hvc1 -filter:v fps=30 output.MP4
# H265 parameter
# The higher CRF value is, the worse video quality we get
ffmpeg.exe -i input_video -map_metadata 0 -c:v libx265 -tag:v hvc1 -crf 20 -preset slow output.MP4
# TRIM VIDEO (ENCODE BY H.265)
ffmpeg -i input_video -ss 00:00:00 -to 00:00:05 -c:v libx265 -tag:v hvc1 -c:a copy -map_metadata 0 trim.MP4
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment