You are browsing as a guest. Sign up (or log in) to start making projects!

rad apple

  • 1 Devlogs
  • 2 Total hours

im just building bad apple in the terminal with rust

Open comments for this post

1h 47m 7s logged

probably gonna be the only devlog

I made bad apple run in terminal using the cascii rust crate to convert the video to frames, and then drew those frames while clearing the terminal. This is just a joke project so I’m not gonna ship it or anything.


Here’s the code, but it’s pretty bad. I’m by no means the greatest programmer. There’s also a lot of warnings, but I’m too lazy to fix them.

use cascii::{AsciiConverter, VideoOptions, ConversionOptions};
use std::path: :Path;
use std::fs::{self, File};
use std::io::Read;
use terminal_size::{Width, Height, terminal_size};
use crossterm::{
    cursor::{Hide, Show, MoveTo},
    execute,
    terminal::{Clear, ClearType},
};
use std::io::{self, stdout};
use std::thread;
use std::time::Duration;

fn main() -> std::io::Result<()> {    

    if !Path::new("output_frames").is_dir() {
        get_frames();
    }
    let mut frames: Vec<String> = read_files()?;

    play_animation(frames)?;
    // println!("{}", frames[0]);
    Ok(())
}

fn get_frames() -> Result<(), Box<dyn std::error: :Error>> {
    let converter = AsciiConverter::new();
    
    let size = terminal_size();
    let mut width: u32 = 80;
    let mut height = 0;
    if let Some((Width(w), Height(h))) = size {
        width = u32::from(w);
    } else {
        println!("unable to get terminal size");
    }

    let video_options = VideoOptions {
        fps: 30,
        start: Some("0".to_string()),
        end: Some("10".to_string()),
        columns: width,
        extract_audio: false,
        preprocess_filter: None,
    };

    let conversion_options = ConversionOptions::default().with_font_ratio(0.2).with_luminance(20).with_columns(width);

    converter.convert_video(Path::new("assets/apple.mp4"), Path::new("output_frames"), &video_options, &conversion_options, false)?;

    Ok(())
}

fn read_files() -> std::io::Result<Vec<String>> {
    let mut files  = Vec::new();

    for file in fs::read_dir("output_frames/").unwrap() {
        files.push(file.unwrap().path().display().to_string());
    }

    files.sort();

    let mut frames: Vec<String> = Vec::new();
    for file in files {
        let content = fs::read_to_string(file);
        let frame = match content {
            Ok(val) => val,
            Err(err) => format!("error: {}", err),
        };

        frames.push(frame);
    }
    Ok(frames)
}

fn play_animation(frames: Vec<String>) -> io::Result<()> {
    let frame = 0;
    let mut stdout = stdout();
    
    for frame in &frames {
        execute!(stdout, Hide, Clear(ClearType::All))?;    
        execute!(stdout, MoveTo(0, 0));
        println!("{}", frame);
        thread::sleep(Duration::from_millis(33));
    }

    execute!(stdout, Show)?;
    Ok(())
}
0
0
7

Delete project?

Are you sure you want to permanently delete this project? This action cannot be undone.

All devlogs, followers, and associated data will be removed.

Followers

Loading…