def create_optimized_gif(in_file, out_file, size, fps): print(t.green("Converting video to GIF...")) tmp_pal_file = get_new_temp_file_path("png") gifsicle_path = which("gifsicle") if gifsicle_path is not None: convert_output_path = get_new_temp_file_path("gif") else: convert_output_path = out_file FFMPEG_FILTERS = "fps={fps},scale=w='if(gt(iw,ih),-1,{size})':h='if(gt(iw,ih),{size},-1)':flags=lanczos".format(fps=fps, size=size) FFMPEG_PALLETE = ["ffmpeg", "-v", "warning", "-i", in_file, "-vf", FFMPEG_FILTERS + ",palettegen", "-y", tmp_pal_file] FFMPEG_CONVERT = ["ffmpeg", "-v", "warning", "-i", in_file, "-i", tmp_pal_file, "-lavfi", FFMPEG_FILTERS + "[x];[x][1:v]paletteuse=dither=floyd_steinberg", "-y", "-f", "gif", convert_output_path] GIFSICLE_OPTIMIZE = ["gifsicle", "-O3", convert_output_path, "-o", out_file] try: subprocess.check_call(FFMPEG_PALLETE) subprocess.check_call(FFMPEG_CONVERT) if gifsicle_path is not None: subprocess.check_call(GIFSICLE_OPTIMIZE) print(t.green("Done!")) except: print(t.red("Could not convert downloaded recording to GIF!")) raise finally: try: os.remove(tmp_pal_file) if gifsicle_path is not None: os.remove(convert_output_path) except: pass print(t.yellow("Created " + out_file))
def run(filename=None, size=None, fps=None, video_quality=None): """ Records Android device screen to an optimized GIF or MP4 file. The type of the output is chosen depending on the file extension. """ print("RoboGif Recorder v%s" % (VERSION,)) check_requirements() output_video_mode = False if not (filename.lower().endswith(".mp4") or filename.lower().endswith(".gif")): print("Usage: %s [output filename].[mp4|gif]" % (sys.argv[0],)) print( t.red("Filename must either end with"), t.green("mp4"), t.red("for video or"), t.green("gif"), t.red("for a GIF."), ) print sys.exit(-4) if filename.lower().endswith(".mp4"): output_video_mode = True if fps is None: if output_video_mode: fps = 60 else: fps = 15 # Show device chooser if more than one device is selected device_id = None devices = get_devices() if len(devices) == 0: print(t.red("No adb devices found, connect one.")) sys.exit(-3) elif len(devices) == 1: device_id = list(devices.keys())[0] else: device_id = get_chosen_device(devices) print(t.green("Starting recording on %s..." % (device_id,))) print(t.yellow("Press Ctrl+C to stop recording.")) recorder = subprocess.Popen( ["adb", "-s", device_id, "shell", "screenrecord", "--bit-rate", "8000000", "/sdcard/tmp_record.mp4"] ) try: while recorder.poll() is None: time.sleep(0.2) except KeyboardInterrupt: pass try: recorder.send_signal(signal.SIGTERM) recorder.wait() except OSError: print print(t.red("Recording has failed, it's possible that your device does not support recording.")) print(t.normal + "Recording is supported on devices running KitKat (4.4) or newer.") print(t.normal + "Genymotion and stock emulator do not support it.") print sys.exit(-3) # We need to wait for MOOV item to be written time.sleep(2) print(t.green("Recording done, downloading file....")) tmp_video_file = get_new_temp_file_path("mp4") # Download file and cleanup try: subprocess.check_call(["adb", "-s", device_id, "pull", "/sdcard/tmp_record.mp4", tmp_video_file]) subprocess.check_call(["adb", "-s", device_id, "shell", "rm", "/sdcard/tmp_record.mp4"]) if output_video_mode: create_optimized_video(tmp_video_file, filename, size, fps, video_quality) else: create_optimized_gif(tmp_video_file, filename, size, fps) except subprocess.CalledProcessError: print(t.red("Could not download recording from the device.")) sys.exit(-1) finally: os.remove(tmp_video_file)
def run(filename=None, size=None, fps=None, video_quality=None): """ Records Android device screen to an optimized GIF or MP4 file. The type of the output is chosen depending on the file extension. """ print("RoboGif Recorder v%s" % (VERSION,)) check_requirements() output_video_mode = False if not (filename.lower().endswith(".mp4") or filename.lower().endswith(".gif")): print("Usage: %s [output filename].[mp4|gif]" % (sys.argv[0], )) print(t.red("Filename must either end with"), t.green("mp4"), t.red("for video or"), t.green("gif"), t.red("for a GIF.")) print sys.exit(-4) if filename.lower().endswith(".mp4"): output_video_mode = True if fps is None: if output_video_mode: fps = 60 else: fps = 15 # Show device chooser if more than one device is selected device_id = None devices = get_devices() if len(devices) == 0: print(t.red("No adb devices found, connect one.")) sys.exit(-3) elif len(devices) == 1: device_id = list(devices.keys())[0] else: device_id = get_chosen_device(devices) print(t.green("Starting recording on %s..." % (device_id, ))) print(t.yellow("Press Ctrl+C to stop recording.")) recorder = subprocess.Popen(["adb", "-s", device_id, "shell", "screenrecord", "--bit-rate", "8000000", "/sdcard/tmp_record.mp4"]) try: while recorder.poll() is None: time.sleep(0.2) except KeyboardInterrupt: pass try: recorder.send_signal(signal.SIGTERM) recorder.wait() except OSError: print print(t.red("Recording has failed, it's possible that your device does not support recording.")) print(t.normal + "Recording is supported on devices running KitKat (4.4) or newer.") print(t.normal + "Genymotion and stock emulator do not support it.") print sys.exit(-3) # We need to wait for MOOV item to be written time.sleep(2) print(t.green("Recording done, downloading file....")) tmp_video_file = get_new_temp_file_path("mp4") # Download file and cleanup try: subprocess.check_call(["adb", "-s", device_id, "pull", "/sdcard/tmp_record.mp4", tmp_video_file]) subprocess.check_call(["adb", "-s", device_id, "shell", "rm", "/sdcard/tmp_record.mp4"]) if output_video_mode: create_optimized_video(tmp_video_file, filename, size, fps, video_quality) else: create_optimized_gif(tmp_video_file, filename, size, fps) except subprocess.CalledProcessError: print(t.red("Could not download recording from the device.")) sys.exit(-1) finally: os.remove(tmp_video_file)