Skip to content

Instantly share code, notes, and snippets.

@Xalior
Last active February 9, 2024 12:06
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Xalior/b642431733b7f090c5e307491e1ddf81 to your computer and use it in GitHub Desktop.
Save Xalior/b642431733b7f090c5e307491e1ddf81 to your computer and use it in GitHub Desktop.
NON COMMERCIAL example of a video convert tool for the .playvid tool
#!/usr/bin/env python3
# NON COMMERCIAL example of a video convert tool for the .playvid tool
#
# Version: 4
# Changelog
# V1 first public release
# V2 Correct RGB 332 colourspace forced
# V3 Handle off-by-one errors when audio is one frame longer than video length
# V4 Delete's the BMP files as it goes, added changelog
import os
import sys
import math
file_name = sys.argv[1]
print (f"Conerting {file_name}")
print(" AUDIO")
# Step #1: Generate audio
os.system("ffmpeg -y -i "+file_name+".mp4 -f u8 -ar 15550 "+file_name+".pcm")
print(" FRAMES")
# Step #2 Generate BMPs, crunched to the next palette
os.system("ffmpeg -y -i "+file_name+".mp4 -vsync cfr -r 16.666666 -vf \"transpose=2,scale=w=240:h=320:sws_dither=auto\" -pix_fmt bgr8 \""+file_name+"_%d.bmp\"")
file_stats = os.stat(file_name+".pcm")
print(f'File Size in Bytes is {file_stats.st_size}')
file_frames = math.floor(file_stats.st_size / (933 * 2))
print(f'Total Framecount is {file_frames}')
video_file = open(file_name+".bin","wb")
audio_file = open(file_name+".pcm","rb")
# Pad audio samples to a round 2k
audio_padding = bytearray([68, 68, 82, 83, 127, 50,50] * 26)
# Encode each frame individually, packing the pixels down to the default next palette. Other colour-formats exist in the player, but this encoder targets the "default" palette only
for file_number in range(1,file_frames+1):
print(f"Frame {file_number}")
# Open preprocessed bitmap, generated by #2 above
bmp = open(file_name+"_"+str(file_number)+".bmp", 'rb')
# Read one frame of audio, x2 for left and right
audio_data = audio_file.read(933*2)
# output samples, and pad them to 2k
video_file.write(audio_data)
video_file.write(audio_padding)
bmp_header = bmp.read(54)
bmp_palette = bmp.read(1024)
bmp_frame = bmp.read(76800)
video_frame = bytearray([0]*76800)
for bmp_pixel in range(76800):
palette_index = (bmp_frame[bmp_pixel])*4
red = ((bmp_palette[palette_index+2]) >>5)<<5
green = ((bmp_palette[palette_index+1]) >>5)<<2
blue = ((bmp_palette[palette_index]) >>6)
video_frame[bmp_pixel] = red+green+blue
video_file.write(video_frame)
bmp.close()
# Delete the encoded BMP file from the disk
os.unlink(file_name+"_"+str(file_number)+".bmp")
audio_file.close()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment