style: Changed prettierc

This commit is contained in:
Boofdev 2025-05-04 17:00:34 +02:00
parent 5438fd02ee
commit 1c00d31527
4 changed files with 130 additions and 127 deletions

View File

@ -1,5 +1,5 @@
{
"useTabs": true,
"useTabs": false,
"singleQuote": true,
"trailingComma": "none",
"printWidth": 100,

View File

@ -1,7 +1,7 @@
import type { StdlibType, TextVideo } from "./types";
import * as Tone from "tone";
import axios, { type AxiosResponse } from "axios";
import Pako from "pako";
import type { StdlibType, TextVideo } from './types';
import * as Tone from 'tone';
import axios, { type AxiosResponse } from 'axios';
import Pako from 'pako';
type PlayOptions = {
speed?: number;
@ -11,8 +11,8 @@ type PlayOptions = {
const defaultOptions: PlayOptions = {
speed: 1,
delayToSkip: 100,
}
delayToSkip: 100
};
export async function play(
stdlib: StdlibType,
@ -20,14 +20,13 @@ export async function play(
audioUrl: string,
options: PlayOptions
) {
options = { ...defaultOptions, ...options };
stdlib.print("Loading, please wait...");
stdlib.print('Loading, please wait...');
let player = new Tone.Player();
if (audioUrl !== "") {
if (audioUrl !== '') {
// Load audio
player = new Tone.Player(audioUrl).toDestination();
}
@ -42,34 +41,32 @@ export async function play(
});
if (video.format_version !== 3) {
stdlib.print(
"Unsupported format version, expected 3, got " + video.format_version
);
stdlib.print('Unsupported format version, expected 3, got ' + video.format_version);
return;
}
if (video.encoding !== "" || video.compression !== "") {
if (video.encoding !== '' || video.compression !== '') {
// Decode the encoded frames
stdlib.print("Decoding frames...");
let decodedFrames = "";
stdlib.print('Decoding frames...');
let decodedFrames = '';
switch (video.encoding) {
case "base64":
case 'base64':
decodedFrames = atob(video.encodedFrames);
break;
}
if (!decodedFrames) {
stdlib.print("Error: Decoded frames are undefined.");
stdlib.print('Error: Decoded frames are undefined.');
return;
}
// Decompress the frames
stdlib.print("Decompressing frames...");
stdlib.print('Decompressing frames...');
let decompressedFrames;
switch (video.compression) {
case "gzip":
case 'gzip':
// Convert binary string to character-number array
let charData = decodedFrames.split("").map(function (x) {
let charData = decodedFrames.split('').map(function (x) {
return x.charCodeAt(0);
});
// Turn number array into byte-array
@ -77,28 +74,26 @@ export async function play(
// Pako
let data = Pako.inflate(binData);
// Convert gunzipped byteArray back to ascii string:
decompressedFrames = new TextDecoder("utf-8").decode(data);
decompressedFrames = new TextDecoder('utf-8').decode(data);
break;
}
video.frames = JSON.parse(decompressedFrames);
}
if (!video.width) {
stdlib.print(
"Video width is undefined, guessing from 100th frame. This may be inaccurate."
);
stdlib.print('Video width is undefined, guessing from 100th frame. This may be inaccurate.');
// Split newlines
try {
video.width = video.frames[99].text.split("\n")[0].length;
video.width = video.frames[99].text.split('\n')[0].length;
} catch (e) {
// Fallback to trying the first frame
try {
video.width = video.frames[0].text.split("\n")[0].length;
video.width = video.frames[0].text.split('\n')[0].length;
} catch (e2) {
console.error(
"An error occured while guessing the video width, when trying to get the width of the 100th frame this exception occurred:",
'An error occured while guessing the video width, when trying to get the width of the 100th frame this exception occurred:',
e,
"and when trying to get the width of the first frame this exception occurred:",
'and when trying to get the width of the first frame this exception occurred:',
e2
);
}
@ -108,12 +103,12 @@ export async function play(
// Calculate the scale
scaleFactor = 100 / video.width;
stdlib.print("Scale Factor: " + scaleFactor);
stdlib.print("Fps: " + video.fps);
stdlib.print("Width: " + video.width);
stdlib.print('Scale Factor: ' + scaleFactor);
stdlib.print('Fps: ' + video.fps);
stdlib.print('Width: ' + video.width);
stdlib.print(
"Your video will start in 5 seconds, if the video looks weird then you might need to zoom out."
'Your video will start in 5 seconds, if the video looks weird then you might need to zoom out.'
);
await new Promise((resolve) => setTimeout(resolve, 5000));
@ -142,28 +137,31 @@ export async function play(
// Print one frame every options.speed milliseconds
let i = 0;
const framesLength = video.frames.length; // Store the length of the frames array
let startTime = Date.now()
let skippedInARow: number = 0
let startTime = Date.now();
let skippedInARow: number = 0;
setInterval(() => {
// Check if i is within the bounds of the frames array
if (i < framesLength) {
let sinceStart = Date.now() - startTime
let sinceStart = Date.now() - startTime;
let frame = timeToFrame(video.fps, sinceStart);
let delayMs = Math.abs(frameToTime(video.fps, i).ms - frameToTime(video.fps, frame).ms);
if (delayMs > options.delayToSkip) {
console.log(delayMs, "out of sync. Skipping to", frame)
console.log(delayMs, 'out of sync. Skipping to', frame);
// Skip to the correct frame
i = Math.round(frame)
i = Math.round(frame);
if (skippedInARow >= 5) {
console.log("We seem to be stuck in a loop, setting max delay to:", options.delayToSkip + 10)
options.delayToSkip = options.delayToSkip + 10
skippedInARow = 0
console.log(
'We seem to be stuck in a loop, setting max delay to:',
options.delayToSkip + 10
);
options.delayToSkip = options.delayToSkip + 10;
skippedInARow = 0;
} else {
skippedInARow++
skippedInARow++;
}
return;
} else {
skippedInARow = 0
skippedInARow = 0;
}
// Print the frame
stdlib.setLineData([]);
@ -185,7 +183,7 @@ function frameToTime(fps: number, frame: number) {
return {
ms: ms,
sec: seconds,
sec: seconds
};
}

View File

@ -1,21 +1,21 @@
import type { StdlibType, TextVideo2, Video2WorkerResponse, Video2WorkerMessage } from "./types";
import * as Tone from "tone";
import type { StdlibType, TextVideo2, Video2WorkerResponse, Video2WorkerMessage } from './types';
import * as Tone from 'tone';
import { unpack, pack } from 'msgpackr';
import video2Worker from "./video2.worker?worker";
import video2Worker from './video2.worker?worker';
type PlayOptions = {
speed?: number;
// Maximum delay between audio and video before skipping
delayToSkip?: number;
// Fully monochrome
oneBit?: boolean
oneBit?: boolean;
};
const defaultOptions: PlayOptions = {
speed: 1,
delayToSkip: 100,
oneBit: false
}
};
export async function play(
stdlib: StdlibType,
@ -23,14 +23,13 @@ export async function play(
audioUrl: string,
options: PlayOptions
) {
options = { ...defaultOptions, ...options };
stdlib.print("Loading, please wait...");
stdlib.print('Loading, please wait...');
let player = new Tone.Player();
if (audioUrl !== "") {
if (audioUrl !== '') {
// Load audio
player = new Tone.Player(audioUrl).toDestination();
}
@ -40,21 +39,19 @@ export async function play(
let video: TextVideo2;
// Download video
const response = await fetch(videoUrl)
const response = await fetch(videoUrl);
const arrayBuffer = await response.arrayBuffer();
const uint8Array = new Uint8Array(arrayBuffer);
video = unpack(uint8Array)
video = unpack(uint8Array);
if (video.format_version !== 1 && video.format_version !== 2) {
stdlib.print(
"Unsupported format version, expected 1 or 2, got " + video.format_version
);
stdlib.print('Unsupported format version, expected 1 or 2, got ' + video.format_version);
return;
}
// Create pixel-to-char lookup table (LUT)
const chars = options.oneBit ? " #" : " .,-:;=+*#%$@";
const chars = options.oneBit ? ' #' : ' .,-:;=+*#%$@';
const lut = new Array(256);
for (let i = 0; i < 256; i++) {
const index = Math.floor((i / 255) * (chars.length - 1));
@ -64,10 +61,10 @@ export async function play(
// Calculate the scale
scaleFactor = 100 / video.video_info.width;
stdlib.print("Scale Factor: " + scaleFactor);
stdlib.print("Fps: " + video.video_info.fps);
stdlib.print("Width: " + video.video_info.width);
stdlib.print("Height: " + video.video_info.height);
stdlib.print('Scale Factor: ' + scaleFactor);
stdlib.print('Fps: ' + video.video_info.fps);
stdlib.print('Width: ' + video.video_info.width);
stdlib.print('Height: ' + video.video_info.height);
// Create the web worker (make sure the worker file is named "videoWorker.js")
const worker = new video2Worker();
@ -77,26 +74,26 @@ export async function play(
const data = e.data as Video2WorkerResponse;
switch (data.type) {
case "frame":
case 'frame':
const frame = data.text;
const lines = frame.split("\n");
const lines = frame.split('\n');
stdlib.setLineData([]);
for (let i = 0; i < lines.length; i++) {
stdlib.print(lines[i]);
}
break;
case "stats":
case 'stats':
console.log(`Received stats from worker: ${data.stats}`);
break;
}
};
// Send the video data and oneBit option to the worker for decoding.
worker.postMessage({ type: "init", video, oneBit: options.oneBit} as Video2WorkerMessage);
worker.postMessage({ type: 'init', video, oneBit: options.oneBit } as Video2WorkerMessage);
stdlib.print(
"Your video will start in 5 seconds, if the video looks weird then you might need to zoom out."
'Your video will start in 5 seconds, if the video looks weird then you might need to zoom out.'
);
await new Promise((resolve) => setTimeout(resolve, 5000));
@ -126,31 +123,36 @@ export async function play(
// Print one frame every options.speed milliseconds
let i = 0;
const framesLength = video.frames.length; // Store the length of the frames array
let startTime = Date.now()
let skippedInARow: number = 0
let startTime = Date.now();
let skippedInARow: number = 0;
setInterval(() => {
// Check if i is within the bounds of the frames array
if (i < framesLength) {
let sinceStart = Date.now() - startTime
let sinceStart = Date.now() - startTime;
let frame = timeToFrame(video.video_info.fps, sinceStart);
let delayMs = Math.abs(frameToTime(video.video_info.fps, i).ms - frameToTime(video.video_info.fps, frame).ms);
let delayMs = Math.abs(
frameToTime(video.video_info.fps, i).ms - frameToTime(video.video_info.fps, frame).ms
);
if (delayMs > options.delayToSkip) {
console.log(delayMs, "out of sync. Skipping to", frame)
console.log(delayMs, 'out of sync. Skipping to', frame);
// Skip to the correct frame
i = Math.round(frame)
i = Math.round(frame);
if (skippedInARow >= 5) {
console.log("We seem to be stuck in a loop, setting max delay to:", options.delayToSkip + 10)
options.delayToSkip = options.delayToSkip + 10
skippedInARow = 0
console.log(
'We seem to be stuck in a loop, setting max delay to:',
options.delayToSkip + 10
);
options.delayToSkip = options.delayToSkip + 10;
skippedInARow = 0;
} else {
skippedInARow++
skippedInARow++;
}
return;
} else {
skippedInARow = 0
skippedInARow = 0;
}
// Print the frame
worker.postMessage({ type: "requestFrame", index: i } as Video2WorkerMessage);
worker.postMessage({ type: 'requestFrame', index: i } as Video2WorkerMessage);
i++;
} else {
stdlib.showStuff;
@ -167,7 +169,7 @@ function frameToTime(fps: number, frame: number) {
return {
ms: ms,
sec: seconds,
sec: seconds
};
}
@ -193,4 +195,4 @@ function pixelsToChars(pixels: Uint8Array, width: number, height: number, lut: s
lines.push(line.join(''));
}
return lines.join('\n');
}
}

View File

@ -9,80 +9,83 @@ const zstdDecoder = new ZSTDDecoder();
// Build the pixel-to-char lookup table (LUT)
function createLUT(oneBit: boolean): string[] {
const chars = oneBit ? ' #' : ' .,-:;=+*#%$@';
const lut = new Array(256);
for (let i = 0; i < 256; i++) {
const index = Math.floor((i / 255) * (chars.length - 1));
lut[i] = chars[index];
}
return lut;
const chars = oneBit ? ' #' : ' .,-:;=+*#%$@';
const lut = new Array(256);
for (let i = 0; i < 256; i++) {
const index = Math.floor((i / 255) * (chars.length - 1));
lut[i] = chars[index];
}
return lut;
}
// Convert the raw pixel data to a text frame.
function pixelsToChars(pixels: Uint8Array, width: number, height: number, lut: string[]): string {
const lines: string[] = [];
for (let y = 0; y < height; y++) {
let line = '';
for (let x = 0; x < width; x++) {
line += lut[pixels[y * width + x]];
}
lines.push(line);
}
return lines.join('\n');
const lines: string[] = [];
for (let y = 0; y < height; y++) {
let line = '';
for (let x = 0; x < width; x++) {
line += lut[pixels[y * width + x]];
}
lines.push(line);
}
return lines.join('\n');
}
function addFrameToBuffer(index: number, options: { addEvenIfpresent?: boolean } = {}) {
if (!options.addEvenIfpresent && frameBuffer[index]) {
return
return;
}
const lut = createLUT(oneBit);
const frame = video.frames[index];
let frameData: Uint8Array;
const lut = createLUT(oneBit);
const frame = video.frames[index];
let frameData: Uint8Array;
switch (video.video_info.compression) {
case "gzip":
case 'gzip':
frameData = Pako.inflate(frame.data);
break;
case "zstd":
case 'zstd':
frameData = zstdDecoder.decode(frame.data, video.video_info.width * video.video_info.height);
break;
default:
frameData = frame.data;
}
const textFrame = pixelsToChars(frameData, video.video_info.width, video.video_info.height, lut);
frameBuffer[index] = textFrame;
default:
frameData = frame.data;
}
const textFrame = pixelsToChars(frameData, video.video_info.width, video.video_info.height, lut);
frameBuffer[index] = textFrame;
}
function add5sOfFramesToBuffer(index: number) {
const totalFrames = video.frames.length;
for (let i = index; i < totalFrames && i < index + 5 * video.video_info.fps; i++) {
addFrameToBuffer(i);
}
const totalFrames = video.frames.length;
for (let i = index; i < totalFrames && i < index + 5 * video.video_info.fps; i++) {
addFrameToBuffer(i);
}
}
self.onmessage = async function (e) {
let data = e.data as Video2WorkerMessage;
switch (data.type) {
case 'init':
video = data.video;
oneBit = data.oneBit || false;
if (data.video.video_info.compression === "zstd") {
let data = e.data as Video2WorkerMessage;
switch (data.type) {
case 'init':
video = data.video;
oneBit = data.oneBit || false;
if (data.video.video_info.compression === 'zstd') {
await zstdDecoder.init();
}
add5sOfFramesToBuffer(0);
break;
add5sOfFramesToBuffer(0);
break;
case 'requestFrame':
case 'requestFrame':
if (!frameBuffer[data.index]) {
addFrameToBuffer(data.index);
}
let frame = frameBuffer[data.index];
let frame = frameBuffer[data.index];
postMessage({ type: 'frame', index: data.index, text: frame });
add5sOfFramesToBuffer(data.index+1);
break;
add5sOfFramesToBuffer(data.index + 1);
break;
case 'stats':
postMessage({ type: 'stats', stats: { buffer: { size: frameBuffer.length, max: video.frames.length }}} as Video2WorkerResponse);
}
postMessage({
type: 'stats',
stats: { buffer: { size: frameBuffer.length, max: video.frames.length } }
} as Video2WorkerResponse);
}
};
export {};