無尽蔵のストレージを実装する方法【Python】

zipファイルを無限にクラウド上に保管する方法を紹介します。
少し前に話題になっていたzipファイルをmp4ファイルへ変換しそれをYouTubeに限定公開でアップすることで無尽蔵のストレージを使用する方法。
今回はこれをPythonで実装できるプログラムを公開しようと思います。

ソースコード

とても汚いコードですが動作はします。

from PIL import Image
import math
import os
from moviepy.editor import ImageSequenceClip
import imageio
import numpy as np
from PIL import Image
import io
from tqdm import tqdm


def zip_to_mp4(zip_input=""):
    file_size = os.path.getsize(zip_input)
    binary_string = ""
    with open(zip_input, "rb") as f:
        for chunk in tqdm(iterable=iter(lambda: f.read(1024), b""), total=math.ceil(file_size/1024), unit="KB"):
            binary_string += "".join(f"{byte:08b}" for byte in chunk)
    width=1920
    height=1080
    pixel_size=4
    fps=24
    num_pixels = len(binary_string)
    pixels_per_image = (width // pixel_size) * (height // pixel_size)
    num_images = math.ceil(num_pixels / pixels_per_image)
    frames = []
    for i in tqdm(range(num_images)):
        start_index = i * pixels_per_image
        end_index = min(start_index + pixels_per_image, num_pixels)
        binary_digits = binary_string[start_index:end_index]
        img = Image.new('RGB', (width, height), color='white')
        for row_index in range(height // pixel_size):
            start_index = row_index * (width // pixel_size)
            end_index = start_index + (width // pixel_size)
            row = binary_digits[start_index:end_index]
            for col_index, digit in enumerate(row):
                if digit == '1':
                    color = (0, 0, 0)
                else:
                    color = (255, 255, 255) 
                x1 = col_index * pixel_size
                y1 = row_index * pixel_size
                x2 = x1 + pixel_size
                y2 = y1 + pixel_size
                img.paste(color, (x1, y1, x2, y2))
        with io.BytesIO() as f:
            img.save(f, format='PNG')
            frame = np.array(Image.open(f))
        frames.append(frame)
    clip = ImageSequenceClip(frames, fps=fps)
    clip.write_videofile(zip_input.replace(".zip","") + '.mp4', fps=fps)

def mp4_to_zip(files = ""):
    am = []
    vid = imageio.get_reader(files, 'ffmpeg')
    fps = vid.get_meta_data()['fps']
    num_frames = vid.get_length()
    with tqdm(total=num_frames) as pbar:
        for i, frame in enumerate(vid):
            am.append(frame)
            pbar.update(1)
    threshold = 128
    binary_digits = ''
    for frame in tqdm(am, desc="Processing frames"):
        gray_frame = np.mean(frame, axis=2).astype(np.uint8)
        pixel_size = 4
        for y in range(0, gray_frame.shape[0], pixel_size):
            for x in range(0, gray_frame.shape[1], pixel_size):
                color = gray_frame[y:y+pixel_size, x:x+pixel_size]
                if color.mean() < threshold:
                    binary_digits += '1'
                else:
                    binary_digits += '0'
    binary_data = bytes(int(binary_digits[i:i+8], 2)
                        for i in range(0, len(binary_digits), 8))
    with open(files.replace(".mp4","") + "_restored.zip", "wb") as f:
        with tqdm(total=len(binary_data), unit='B', unit_scale=True, desc="Writing binary data") as pbar:
            for chunk in range(0, len(binary_data), 1024):
                f.write(binary_data[chunk:chunk+1024])
                pbar.update(1024)

動作確認

zip_to_mp4(“”)#ここにzipからmp4に変換したいファイルのパスを追加

mp4_to_zip(“”)#変換済みmp4をzipファイルへ戻すためのファイルのパスを追加

mp4になった状態をYouTubeにアップし、ストレージを実装できました。

いいなと思ったら応援しよう!