def compress_video_file(filename, ffmpeg_settings): ffmpeg_settings = ffmpeg_settings or {} key = generate_key("COMPRESSED", filename, settings=ffmpeg_settings, default=" (default compression)") if not config.UPDATE and FILECACHE.get(key): return FILECACHE.get(key).decode('utf-8') config.LOGGER.info("\t--- Compressing {}".format(filename)) tempf = tempfile.NamedTemporaryFile(suffix=".{}".format(file_formats.MP4), delete=False) tempf.close() # Need to close so pressure cooker can write to file compress_video(config.get_storage_path(filename), tempf.name, overwrite=True, **ffmpeg_settings) filename = "{}.{}".format(get_hash(tempf.name), file_formats.MP4) copy_file_to_storage(filename, tempf.name) os.unlink(tempf.name) FILECACHE.set(key, bytes(filename, "utf-8")) return filename
def test_convert_mov_works(self, high_res_mov_video): with TempFile(suffix=".mp4") as vout: videos.compress_video(high_res_mov_video.name, vout.name, overwrite=True) width, height = get_resolution(vout.name) assert height == 480, 'should convert .ogv to .mp4 and set 480 v res'
def test_compression_works(self, high_res_video): with TempFile(suffix=".mp4") as vout: videos.compress_video(high_res_video.name, vout.name, overwrite=True) width, height = get_resolution(vout.name) assert height == 480, 'should compress to 480 v resolution by defualt'
def compress_video_file(filename, ffmpeg_settings): """ Calls the pressurecooker function `compress_video` to compress filename (source) stored in storage. Returns the filename of the compressed file. """ ffmpeg_settings = ffmpeg_settings or {} key = generate_key("COMPRESSED", filename, settings=ffmpeg_settings, default=" (default compression)") cache_file = get_cache_filename(key) if not config.UPDATE and cache_file: return cache_file config.LOGGER.info("\t--- Compressing {}".format(filename)) tempf = tempfile.NamedTemporaryFile(suffix=".{}".format(file_formats.MP4), delete=False) tempf.close() # Need to close so pressure cooker can write to file compress_video(config.get_storage_path(filename), tempf.name, overwrite=True, **ffmpeg_settings) compressedfilename = "{}.{}".format(get_hash(tempf.name), file_formats.MP4) copy_file_to_storage(compressedfilename, tempf.name) os.unlink(tempf.name) FILECACHE.set(key, bytes(compressedfilename, "utf-8")) return compressedfilename
def test_convert_and_resize_ogv_works(self, low_res_ogv_video): with TempFile(suffix=".mp4") as vout: videos.compress_video(low_res_ogv_video.name, vout.name, overwrite=True, max_height=200) width, height = get_resolution(vout.name) assert height == 200, 'should convert .ogv to .mp4 and set 200 v res'
def test_compression_max_height(self, high_res_video): with TempFile(suffix=".mp4") as vout: videos.compress_video(high_res_video.name, vout.name, overwrite=True, max_height=140) width, height = get_resolution(vout.name) assert height == 140, 'should be 140 v resolution since max_height set'
def test_compression_max_width_odd(self, high_res_video): """ regression test for: https://github.com/learningequality/pressurecooker/issues/11 """ with TempFile(suffix=".mp4") as vout: videos.compress_video(high_res_video.name, vout.name, overwrite=True, max_width=121) width, height = get_resolution(vout.name) assert width == 120, 'should round down to 120 h resolution when max_width=121 set'
def download_and_convert_video(path, default_ext=file_formats.MP4, ffmpeg_settings=None): """ download: downloads file Args: None Returns: filename """ ffmpeg_settings = ffmpeg_settings or {} key = "DOWNLOAD:{}".format(path) if not config.UPDATE and FILECACHE.get(key): return FILECACHE.get(key).decode('utf-8') config.LOGGER.info("\tDownloading {}".format(path)) # Get extension of file or default if none found extension = os.path.splitext(path)[1][1:].lower() converted_path = None # Convert video to temporary file with tempfile.NamedTemporaryFile(suffix=".{}".format(extension), delete=False) as tempf: # Write unsupported video to temporary file write_and_get_hash(path, tempf) tempf.seek(0) # Compress video into mp4 file path, _ext = os.path.splitext(tempf.name) converted_path = "{}.{}".format(path, file_formats.MP4) tempf.close() compress_video(tempf.name, converted_path, overwrite=True, **ffmpeg_settings) os.unlink(tempf.name) # Write file to temporary file with tempfile.TemporaryFile() as tempf: hash = write_and_get_hash(converted_path, tempf) tempf.seek(0) filename = '{0}.{ext}'.format(hash.hexdigest(), ext=file_formats.MP4) copy_file_to_storage(filename, tempf) os.unlink(converted_path) FILECACHE.set(key, bytes(filename, "utf-8")) return filename
def compress_video_wrapper(file_object): with tempfile.NamedTemporaryFile(suffix=".{}".format(file_formats.MP4)) as tempf: tempf.close() compress_video(str(file_object.file_on_disk), tempf.name, overwrite=True) filename = write_file_to_storage(open(tempf.name, 'rb'), name=tempf.name) checksum, ext = os.path.splitext(filename) file_location = generate_file_on_disk_name(checksum, filename) low_res_object = File( file_on_disk=DjFile(open(file_location, 'rb')), file_format_id=file_formats.MP4, original_filename=file_object.original_filename, contentnode=file_object.contentnode, file_size=os.path.getsize(file_location), preset_id=format_presets.VIDEO_LOW_RES, ) low_res_object.save() return low_res_object
def compress_video_wrapper(file_object): with tempfile.NamedTemporaryFile(suffix=".{}".format(file_formats.MP4)) as tempf: tempf.close() compress_video(str(file_object.file_on_disk), tempf.name, overwrite=True) filename = write_file_to_storage(open(tempf.name, 'rb'), name=tempf.name) checksum, ext = os.path.splitext(filename) file_location = generate_file_on_disk_name(checksum, filename) low_res_object = File( file_on_disk=DjFile(open(file_location, 'rb')), file_format_id=file_formats.MP4, original_filename = file_object.original_filename, contentnode=file_object.contentnode, file_size=os.path.getsize(file_location), preset_id=format_presets.VIDEO_LOW_RES, ) low_res_object.save() return low_res_object
def download_and_convert_video(path, default_ext=file_formats.MP4, ffmpeg_settings=None): """ Auto-converting variant of download function that handles all video formats. """ ffmpeg_settings = ffmpeg_settings or {} key = "DOWNLOAD:{}".format(path) cache_file = get_cache_filename(key) if is_valid_url(path) and not config.UPDATE and cache_file: return cache_file config.LOGGER.info("\tDownloading {}".format(path)) # Get extension of convertible video file ext = extract_path_ext(path) converted_path = None # Convert video to temporary file with tempfile.NamedTemporaryFile(suffix=".{}".format(ext), delete=False) as tempf: # Write unsupported video to temporary file write_and_get_hash(path, tempf) tempf.seek(0) # Compress video into mp4 file path, _ext = os.path.splitext(tempf.name) converted_path = "{}.{}".format(path, file_formats.MP4) tempf.close() compress_video(tempf.name, converted_path, overwrite=True, **ffmpeg_settings) os.unlink(tempf.name) # Write converted file to another temporary file with tempfile.TemporaryFile() as tempf2: hash = write_and_get_hash(converted_path, tempf2) tempf2.seek(0) filename = '{0}.{ext}'.format(hash.hexdigest(), ext=file_formats.MP4) copy_file_to_storage(filename, tempf2) os.unlink(converted_path) FILECACHE.set(key, bytes(filename, "utf-8")) return filename
def test_raises_for_bad_file(self, bad_video): with TempFile(suffix=".mp4") as vout: with pytest.raises(videos.VideoCompressionError): videos.compress_video(bad_video.name, vout.name, overwrite=True)