Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
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