Daily Tips - How to crash your browser? 🤔

Hi there,

It is said that where there is a screen, there must be a bad apple. Where there is a Dash, there must be one, too!

dash_bad_apple

from dash import Dash, html, dcc, Input, Output, State
import requests

frames = requests.get(
    "https://raw.githubusercontent.com/IcToxi/datasets/main/bad_apple_frames.json"
).json()

app = Dash(__name__)

app.layout = html.Div(
    [
        html.Pre(id="bad-apple-x-show"),
        dcc.Store(data=frames, id="bad-apple-x-frame"),
        dcc.Interval(id="bad-apple-x-interval", interval=1000 / 15, n_intervals=0),
        html.Audio(src="/assets/bad_apple.m4a", autoPlay=True, loop=True),
    ]
)

app.clientside_callback(
    "((n, frames) => n % Object.keys(frames).length && frames[n % Object.keys(frames).length])",
    Output("bad-apple-x-show", "children"),
    Input("bad-apple-x-interval", "n_intervals"),
    State("bad-apple-x-frame", "data"),
)


if __name__ == "__main__":
    app.run(debug=True)

I supposed to put an online resource, but cross-origin is too troublesome.

ffmpeg -i bad_apple.mp4 -map 0:a -c copy bad_apple.m4a

The method to extract the frames is as below:

  1. First, you must have a video file, and then extract its frames and save it as pictures. You can adjust the frame rate and picture quality.
ffmpeg -i bad_apple.mp4 -f image2 -r 15 -qscale:v 2 ./img%05d.jpg
  1. Convert these pictures to characters.
from PIL import Image
import os
import json
from tqdm import tqdm

ascii_char = list(
    "$@B%8&WM#*oahkbdpqwmZO0QLCJUYXzcvunxrjft/\|()1{}[]?-_+~<>i!lI;:,\"^`'.  "
)

WIDTH = 144
HEIGHT = 48


def get_char_from_pixel(r, g, b, alpha=256):
    if alpha == 0:
        return " "
    length = len(ascii_char)
    gray = int(0.2126 * r + 0.7152 * g + 0.0722 * b)

    unit = (256.0 + 1) / length
    return ascii_char[int(gray / unit)]


def ascii_pic_from_pil(path):
    text = ""

    im = Image.open(path)
    im = im.resize((WIDTH, HEIGHT), Image.Resampling.NEAREST)

    for h in range(im.size[1]):
        for w in range(im.size[0]):
            text += get_char_from_pixel(*im.getpixel((w, h)))
        text += "\n"

    return text


frame = {}
for root, dirs, files in os.walk("./bad_apple"):
    for f in tqdm(files):
        if f.endswith(".jpg"):
            frame |= {
                (int(f.replace("img", "").replace(".jpg", ""))): ascii_pic_from_pil(
                    os.path.join(root, f)
                )
            }

with open("frames.json", "w") as f:
    f.write(json.dumps(frame, indent=2, sort_keys=True))





Hope you like this. XD

Keywords: Bad Apple, dcc.Store, Cross Origin, FFmpeg, Pillow

Other Daily Tips series:
Daily Tips - If I have a Bunch of Triggers
Daily Tips - Share the Function
Daily Tips - How many Ways to share Dash in a company?
Daily Tips - Give your Component a Name
Daily Tips - Share Dash to Social Media
Daily Tips - Double-click to open Dash
Daily Tips - What rows of data have I modified?
Daily Tips - Write the Simplest Client-side Callback
Daily Tips - Some simple Expressions
Daily Tips - IoT? Real Real-time Data and Live Update
Daily Tips - Which formatter is your favorite?
Daily Tips - Convert a React Component to Dash
Daily Tips - Real-time Logs on Dash

2 Likes

Very informative. Thanks for sharing @stu. I ran this app on my computer and watched the whole movie/frames. Amazing what can be done with clientside callback also.

1 Like