Skip to content

Instantly share code, notes, and snippets.

@giuliano-macedo
Last active September 24, 2022 04:08
Show Gist options
  • Save giuliano-macedo/fc0b5e62f6e3edf11d8526eec0795253 to your computer and use it in GitHub Desktop.
Save giuliano-macedo/fc0b5e62f6e3edf11d8526eec0795253 to your computer and use it in GitHub Desktop.
Split video using ffmpeg to fit WhatsApp status
from subprocess import getstatusoutput as shell
from subprocess import Popen,PIPE,STDOUT
import shlex
import re
import argparse
import os
from tqdm import tqdm
from math import ceil,log10
def get_video_length(fname):
code,ffprobe_out=shell(f"ffprobe -v error -show_entries format=duration -of default=noprint_wrappers=1:nokey=1 {fname}")
assert(code==0)
return float(ffprobe_out)
def iterate_ffmpeg_ouput(cmd):
process = Popen(shlex.split(cmd), stdout=PIPE,stderr=STDOUT,universal_newlines=True)
regex=re.compile(r"time=([\d:.]+)")
for line in process.stdout:
match=next(regex.finditer(line),None)
if match==None:continue
time_str=match.group(1)
hours,minutes,seconds=(float(n) for n in time_str.split(":"))
yield (hours*3600)+(minutes*60)+seconds
def chunk_it(fname,out_file,offset):
return iterate_ffmpeg_ouput(
f"ffmpeg -y -i {fname} -ss {offset*30} -t {30} {out_file}"
)
parser=argparse.ArgumentParser()
parser.add_argument("video",help="video file to split")
args=parser.parse_args()
root_dir=os.path.split(args.video)[0]
output_dir=os.path.splitext(args.video)[0]+"_splitted"
if not os.path.exists(output_dir):
os.mkdir(output_dir)
elif not os.path.isdir(output_dir):
raise RuntimeError(f"'{output_dir}' is not a directory")
video_length=get_video_length(args.video)
total_chunks=ceil(video_length/30)
the_log=ceil(log10(total_chunks))
pbar=tqdm(total=video_length)
for offset in range(total_chunks):
out_file=os.path.join(
output_dir,
"{n:0{t}}.mp4".format(n=offset,t=the_log)
)
old_n=pbar.n
for progress in chunk_it(args.video,out_file,offset):
pbar.n=round(old_n+progress,2)
pbar.refresh()
pbar.close()
print("DONE!")
print("outputs saved to",os.path.join(output_dir,"*.mp4"))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment