import subprocess import argparse from os import path, makedirs parser = argparse.ArgumentParser() parser.add_argument("day", help="Day of the year. From 1 to 366") parser.add_argument("--directory", help="Output directory for the images") parser.add_argument("--size", help="Image size to download, defaults to 1808x1808. Available options: 339x339, 678x678, 1808x1808, 5424x5424, 10848x10848, 21696x21696") parser.add_argument("--animate", help="Animate the download images. Available options: fullsize, compressed, fullsize+compressed, ad-fullsize, ad-compressed, ad-fullsize+compressed") parser.add_argument("--framerate", help="Framerate of the animation from the downloaded images, in frames per second, defaults to 8") parser.add_argument("--compress-size", help="Resolution of the compressed video, defaults to 540x540") parser.add_argument("--codec", help="Defines the ffmpeg codec to be used. Defaults to libx264. To see available codecs for ffmpeg run \"ffmpeg -codecs\"") args = parser.parse_args() day = args.day animateAction = args.animate # Argument handling directory= "." if args.directory is not None: directory = args.directory if not path.isdir(directory): makedirs(directory) picsize = "1808x1808" if args.size is not None: picsize = args.size framerate = 8 if args.framerate is not None: if animateAction is not None: framerate = args.framerate else: print("'--framerate' requires '--animate' to be set, see '-h' for help and details.") exit() compress_size= "540x540" if args.compress_size is not None: if animateAction is not None: compress_size = args.compress_size else: print("'--compress-size' requires '--animate' to be set, see '-h' for help and details.") exit() codec = "libx264" if args.codec is not None: if animateAction is not None: codec = args.codec else: print("'--codec' requires '--animate' to be set, see '-h' for help and details.") exit() # Global counters pic_count = 1 total_expected_pics = 144 def padding(count: int): global total_expected_pics digits = len(str(count)) count = str(count) padded_string = "" while len(count) < len(str(total_expected_pics)): count = "0"+count return count def daygroup(day: str): global total_expected_pics if day.__contains__("-"): ranges = day.split("-") total_expected_pics = 144*len(range(int(ranges[0]), int(ranges[1])+1)) print(f"EXPECTED NUMBER OF IMAGES: {total_expected_pics}") for d in range(int(ranges[0]), int(ranges[1])+1): hourgroup(d) else: hourgroup(int(day)) def hourgroup(day: int): for hour in range(0, 24): if hour < 10: hour = "0" + str(hour) minutegroup(day, hour) def minutegroup(day: int, hour: str): global pic_count global directory global animateAction global picsize str_pic_count = "" for minutes in range(0, 60, 10): if minutes == 0: minutes = "00" minutes = str(minutes) day = str(day) str_pic_count = padding(pic_count) fulldir = directory+"/"+str_pic_count+".jpg" print(f"DOWNLOADING PICNUM={str_pic_count}, DAY={day}, HOUR={hour}, MINUTES={minutes}") print(f"LINK: https://cdn.star.nesdis.noaa.gov/GOES16/ABI/FD/GEOCOLOR/2024{day}{hour}{minutes}_GOES16-ABI-FD-GEOCOLOR-{picsize}.jpg") subprocess.run(["sh", "-c", f"curl -o {fulldir} https://cdn.star.nesdis.noaa.gov/GOES16/ABI/FD/GEOCOLOR/2024{day}{hour}{minutes}_GOES16-ABI-FD-GEOCOLOR-{picsize}.jpg &>/dev/null"]) print("CHECKING FILE") filetest = subprocess.run(["file", fulldir], capture_output=True) filetest = filetest.stdout.decode("utf-8") if filetest.__contains__("JPEG"): print(f"FILE {fulldir} OK") else: print(f"FILE {fulldir} NOT OK, DELETING") subprocess.run(["rm", fulldir]) pic_count += 1 if animateAction is not None: if animateAction == "ad-fullsize": print(f"CREATING FULL-SIZED ANIMATION {directory}/fullsize.mp4") subprocess.run(["sh", "-c", f"ffmpeg -framerate {framerate} -pattern_type glob -i '{directory}/*.jpg' -c:v {codec} {directory}/fullsize.mp4"]) exit() elif animateAction == "ad-compressed": print(f"CREATING 540x540 COMPRESSED ANIMATION {directory}/compressed.mp4") subprocess.run(["sh", "-c", f"ffmpeg -framerate {framerate} -pattern_type glob -i '{directory}/*.jpg' -c:v {codec} -crf 25 -s {compress_size} {directory}/compressed.mp4"]) exit() elif animateAction == "ad-fullsize+compressed": print(f"CREATING FULL-SIZED ANIMATION {directory}/fullsize.mp4") subprocess.run(["sh", "-c", f"ffmpeg -framerate {framerate} -pattern_type glob -i '{directory}/*.jpg' -c:v {codec} {directory}/fullsize.mp4"]) print(f"CREATING 540x540 COMPRESSED VERSION FROM FULL-SIZED ANIMATION") subprocess.run(["sh", "-c", f"ffmpeg -i {directory}/fullsize.mp4 -crf 25 -s {compress_size} {directory}/compressed.mp4"]) exit() daygroup(day) if animateAction is not None: if animateAction == "fullsize": print(f"CREATING FULL-SIZED ANIMATION {directory}/fullsize.mp4") subprocess.run(["sh", "-c", f"ffmpeg -framerate {framerate} -pattern_type glob -i '{directory}/*.jpg' -c:v {codec} {directory}/fullsize.mp4"]) exit() elif animateAction == "compressed": print(f"CREATING 540x540 COMPRESSED ANIMATION {directory}/compressed.mp4") subprocess.run(["sh", "-c", f"ffmpeg -framerate {framerate} -pattern_type glob -i '{directory}/*.jpg' -c:v {codec} -crf 25 -s {compress_size} {directory}/compressed.mp4"]) exit() elif animateAction == "fullsize+compressed": print(f"CREATING FULL-SIZED ANIMATION {directory}/fullsize.mp4") subprocess.run(["sh", "-c", f"ffmpeg -framerate {framerate} -pattern_type glob -i '{directory}/*.jpg' -c:v {codec} {directory}/fullsize.mp4"]) print(f"CREATING 540x540 COMPRESSED VERSION FROM FULL-SIZED ANIMATION") subprocess.run(["sh", "-c", f"ffmpeg -i {directory}/fullsize.mp4 -crf 25 -s {compress_size} {directory}/compressed.mp4"]) exit() exit()