Frankiezafe (Talk | contribs) |
Frankiezafe (Talk | contribs) |
||
Line 3: | Line 3: | ||
Automatised post-processing of video using image compression algorithm glitches. | Automatised post-processing of video using image compression algorithm glitches. | ||
− | == | + | == video == |
<html><iframe src="https://player.vimeo.com/video/272100688?title=0&byline=0&portrait=0" width="640" height="360" frameborder="0" webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe></html> | <html><iframe src="https://player.vimeo.com/video/272100688?title=0&byline=0&portrait=0" width="640" height="360" frameborder="0" webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe></html> | ||
Line 9: | Line 9: | ||
<html><iframe src="https://player.vimeo.com/video/272102866?title=0&byline=0&portrait=0" width="640" height="338" frameborder="0" webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe></html> | <html><iframe src="https://player.vimeo.com/video/272102866?title=0&byline=0&portrait=0" width="640" height="338" frameborder="0" webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe></html> | ||
− | == process == | + | === process === |
For '''jpg''' codec, the process is recompressing each frame with 1% less quality than previous compression. In the videos above, we start at 40% and gradually decrease the quality to 1%. | For '''jpg''' codec, the process is recompressing each frame with 1% less quality than previous compression. In the videos above, we start at 40% and gradually decrease the quality to 1%. | ||
Line 149: | Line 149: | ||
subprocess.call(['ffmpeg', '-f', 'image2', '-framerate', str(fps), '-r', str(fps), '-i', im_path, '-an', '-vcodec', 'mjpeg', '-q:v', '1', folder_compressed + '/' + movie_path ]) | subprocess.call(['ffmpeg', '-f', 'image2', '-framerate', str(fps), '-r', str(fps), '-i', im_path, '-an', '-vcodec', 'mjpeg', '-q:v', '1', folder_compressed + '/' + movie_path ]) | ||
+ | |||
+ | == sound == | ||
+ | |||
+ | First attempt using [http://lame.sourceforge.net/ lame]. | ||
+ | |||
+ | <html><iframe width="100%" height="166" scrolling="no" frameborder="no" allow="autoplay" src="https://w.soundcloud.com/player/?url=https%3A//api.soundcloud.com/tracks/450288369&color=%23ff5500&auto_play=false&hide_related=false&show_comments=true&show_user=true&show_reposts=false&show_teaser=true"></iframe></html> | ||
[[category:glitch]] | [[category:glitch]] |
Automatised post-processing of video using image compression algorithm glitches.
For jpg codec, the process is recompressing each frame with 1% less quality than previous compression. In the videos above, we start at 40% and gradually decrease the quality to 1%.
For gif codec, it is much more straight-forward, as we do the process in one pass, specifying the number of colors in the palette.
Python script
try: from cStringIO import StringIO as BytesIO except ImportError: from io import BytesIO from PIL import Image import os import shutil import subprocess ------------- GLOBAL ------------- # set to true if the source video has not been extracted already regenarate_video_frames = False recompress_video_frames = True regenarate_output_video = True # source video path video = 'source.mv' # folder path to export source video frames folder_frames = 'frames' # folder path to store compressed video frames folder_compressed = 'compressed' # type of compressor - JPG or GIF compressor = 'JPG' # jpg compressor settings jpg_from = 40 jpg_to = 1 jpg_steps = 1 # gif compressor settings gif_colors = 4 # output frames limits limit_from = 1800 limit_to = 3125 # output frame rate fps = 25 fprefix = 'output_' ------------- FUNCTIONS ------------- def create_folder(p): if not os.path.exists(p): os.makedirs(p) else: clear_folder(p) def clear_folder(p): for root, dirs, files in os.walk( p ): for f in files: os.unlink(os.path.join( root, f )) for d in dirs: shutil.rmtree(os.path.join( root, d )) def jpg_compress( src_path, dst_path ): jpg_q = jpg_from while jpg_q >= jpg_to: src = Image.open( src_path ) buffer = BytesIO() src.save( buffer, "JPEG", quality = jpg_q, optimize=True, progressive=True ) jpg_q -= jpg_steps buffer.seek(0) with open( dst_path, "w") as handle: handle.write(buffer.read()) src_path = dst_path def gif_compress( src_path, dst_path ): src = Image.open( src_path ) buffer = BytesIO() src = src.convert('P', palette=Image.ADAPTIVE, colors=gif_colors) src.save( buffer, "PNG" ) buffer.seek(0) with open( dst_path, "w") as handle: handle.write(buffer.read()) ------------- PROCESS ------------- if regenarate_video_frames == True: create_folder( folder_frames ) subprocess.call(['ffmpeg', '-i', video, '-vcodec', 'png', folder_frames + '/' + fprefix + '%05d.png' ]) if recompress_video_frames == True: create_folder( folder_compressed ) ext = '.jpg' if compressor == 'GIF': ext = '.png' for root, dirs, files in os.walk( folder_frames ): files.sort() i = 0 outi = 0 for f in files: if limit_from > -1 and i >= limit_from and i < limit_to: outf = folder_compressed + '/' + fprefix if outi < 10: outf += '0000' elif outi < 100: outf += '000' elif outi < 1000: outf += '00' elif outi < 10000: outf += '0' outf += str(outi) + ext outi += 1 if compressor == 'JPG': jpg_compress( folder_frames + '/' + f, outf ) elif compressor == 'GIF': gif_compress( folder_frames + '/' + f, outf ) print( str( outi ) + '/' + str( ( limit_to - limit_from ) ) + ' frame (' + ext + ')' ) i += 1 if regenarate_output_video == True: movie_path = 'movie_' + fps + 'fps_' + limit_from + '-' + limit_to im_path = folder_compressed + '/' + fprefix + '%5d' if compressor == 'JPG': movie_path += '_' + jpg_from + '-' + jpg_to + '-' + jpg_steps + 'jpg' im_path += '.jpg' elif compressor == 'GIF': movie_path += '_' + gif_colors + 'gif' im_path += '.png' else: pass movie_path += '.mkv' subprocess.call(['ffmpeg', '-f', 'image2', '-framerate', str(fps), '-r', str(fps), '-i', im_path, '-an', '-vcodec', 'mjpeg', '-q:v', '1', folder_compressed + '/' + movie_path ])
First attempt using lame.
online identity ∋ [ social ∋ [mastodon♥, twitter®, facebook®, diaspora, linkedin®]
∥ repos ∋ [github®, gitlab♥, bitbucket®, sourceforge] ∥ media ∋ [itch.io®, vimeo®, peertube♥, twitch.tv®, tumblr®] ∥ communities ∋ [godotengine♥, openprocessing, stackoverflow, threejs]]