mirror of
https://github.com/KrisKennaway/ii-vision.git
synced 2024-12-30 15:29:26 +00:00
c00300147e
- Introduce a new Movie() class that multiplexes audio and video. - Every N audio frames we grab a new video frame and begin pulling opcodes from the audio and video streams - Grab frames from the input video using bmp2dhr if the .BIN file does not already exist. Run bmp2dhr in a background thread to not block encoding - move the output byte streaming from Video to Movie - For now, manually clip updates to pages > 56 since the client doesn't support them yet The way we encode video is now: - iterate in descending order over update_priority - begin a new (page, content) opcode - for all of the other offset bytes in that page, compute the error between the candidate content byte and the target content byte - iterate over offsets in order of increasing error and decreasing update_priority to fill out the remaining opcode
74 lines
1.8 KiB
Python
74 lines
1.8 KiB
Python
import os
|
|
import threading
|
|
import queue
|
|
import subprocess
|
|
from typing import Iterable
|
|
|
|
from PIL import Image
|
|
import skvideo.io
|
|
import numpy as np
|
|
|
|
import screen
|
|
|
|
|
|
def frame_grabber(filename: str) -> Iterable[np.array]:
|
|
"""Yields a sequence of Image frames in original resolution."""
|
|
for frame_array in skvideo.io.vreader(filename):
|
|
yield Image.fromarray(frame_array)
|
|
|
|
|
|
def hgr140_frame_grabber(filename: str) -> Iterable[screen.MemoryMap]:
|
|
bm_cls = screen.HGR140Bitmap
|
|
for frame in frame_grabber(filename):
|
|
frame = frame.resize((bm_cls.XMAX, bm_cls.YMAX))
|
|
frame = frame.convert("1")
|
|
frame = np.array(frame)
|
|
|
|
yield bm_cls(frame).to_bytemap().to_memory_map(screen_page=1)
|
|
|
|
|
|
def bmp2dhr_frame_grabber(filename: str) -> Iterable[screen.MemoryMap]:
|
|
"""Encode frame to HGR using bmp2dhr"""
|
|
|
|
frame_dir = filename.split(".")[0]
|
|
try:
|
|
os.mkdir(frame_dir)
|
|
except FileExistsError:
|
|
pass
|
|
|
|
q = queue.Queue(maxsize=10)
|
|
|
|
def worker():
|
|
for idx, frame in enumerate(frame_grabber(filename)):
|
|
outfile = "%s/%08dC.BIN" % (frame_dir, idx)
|
|
bmpfile = "%s/%08d.bmp" % (frame_dir, idx)
|
|
|
|
try:
|
|
os.stat(outfile)
|
|
except FileNotFoundError:
|
|
frame = frame.resize((280, 192))
|
|
frame.save(bmpfile)
|
|
|
|
subprocess.call(
|
|
["/usr/local/bin/bmp2dhr", bmpfile, "hgr", "D9"])
|
|
|
|
os.remove(bmpfile)
|
|
|
|
frame = np.fromfile(outfile, dtype=np.uint8)
|
|
q.put(frame)
|
|
|
|
q.put(None)
|
|
|
|
t = threading.Thread(target=worker)
|
|
t.start()
|
|
|
|
while True:
|
|
frame = q.get()
|
|
|
|
if frame is None:
|
|
break
|
|
|
|
yield screen.FlatMemoryMap(screen_page=1, data=frame).to_memory_map()
|
|
q.task_done()
|
|
|
|
t.join() |