Plays videos using Prometheus and Grafana, e.g. Bad Apple.

prometheus_video_renderer

Plays videos using Prometheus and Grafana, e.g. Bad Apple.

grafana

Modes

Currently 3 different modes are supported.

Bitmap

The bitmap mode either creates a sample or does not, depending on the brightness of the source image. It is the only mode compatible with the Prometheus UI.

bitmap-preview

Example: https://www.youtube.com/watch?v=ApJxFprSTqA

Grayscale

The RGB mode creates a metric and sets a brightness label matching an override for each unique brightness.

This is made with 256 unique overrides.

Example coming soon.

RGB

The RGB mode creates offset metrics for red, green, and blue, and sets a brightness label matching an override for each unique color/brightness.

This is 22-bit color, made with 640 unique overrides.

Example: https://www.youtube.com/watch?v=aLvh0oId3Go

Inspiration

A while back I thought this blog post and the corresponding source code were kind of fun. After seeing some of kevinjycui's bad apple videos I thought combining these two ideas could be an interesting (and hilariously terrible) idea.

How to use

  • Download a video e.g. bad_apple.mkv
  • Figure out the output resolution, you should scale 1:1 with height being the number of time series you want.
  • Get a png sequence ffmpeg -i bad_apple.mkv -vf "scale=180:135" -vsync 0 frames\out%06d.png
  • If you would like to make sure that the y axis doesn't change, you can add 1px white bars to each frame. e.g.
    • ffmpeg -i frames\out%06d.png -vf "crop=in_w:in_h-1:0:1,pad=iw+0:ih+1:0:1:#FFFFFF@1,format=rgb24" -y frames\out%06d.png
    • ffmpeg -i frames\out%06d.png -vf "crop=in_w:in_h-1:0:-1,pad=iw+0:ih+1:0:-1:#FFFFFF@1,format=rgb24" -y frames\out%06d.png
  • go run main.go --project="bad_apple" (use --help to see all arguments)
  • Loop over the files and send them to promtool tsdb create-blocks-from openmetrics
  • docker compose up
  • Wait for Prometheus to compact etc. so it doesn't take 20 years to render.
  • Run a script to record all the frames from the UI. (Mediocre examples are in the scripts directory.)
  • cd to wherever you stored your screenshots.
  • Generate the video file ffmpeg -framerate 30 -i '%06d.png' -c:v libx264 -pix_fmt yuv420p out.mp4
Comments
  • Add sh script using promtool pinned by bingo

    Add sh script using promtool pinned by bingo

    Hey there,

    This adds a shell script, for folks that would prefer using bash or zsh instead of powershell. Also uses promtool package pinned by bingo.

    Let me know if this PR needs any modifications.

  • Fix: allow overlapping blocks

    Fix: allow overlapping blocks

    Hey there,

    Not sure if you're open to contributions nor if this is the right way to do it...

    But while trying out the project with a simple video (this one to be exact), I faced the following error when running promtool tsdb create-blocks-from openmetrics [...]:

    prometheus_1  | level=error ts=2021-08-12T03:12:17.882Z caller=db.go:766 component=tsdb msg=reloadBlocks err="invalid block sequence: block time ranges overlap: [mint: 1628676000000, maxt: 1628676299001, range: 4m59s, blocks: 2]: <ulid: 01FCW4B0D0C46EF2YZDG3YWJ0J, mint: 1628676000000, maxt: 1628676299001, range: 4m59s>, <ulid: 01FCW52YXKKZ8HPXZY2QY5R5FS, mint: 1628676000000, maxt: 1628676299001, range: 4m59s>\n[mint: 1628640000000, maxt: 1628647199001, range: 1h59m59s, blocks: 2]: <ulid: 01FCW521C9JHXC2S7MMEWN72AQ, mint: 1628640000000, maxt: 1628647199001, range: 1h59m59s>, <ulid: 01FCW514MC9DAVTAJBBSTDR5P7, mint: 1628640000000, maxt: 1628661599001, range: 5h59m59s>\n[mint: 1628647200000, maxt: 1628654399001, range: 1h59m59s, blocks: 2]: <ulid: 01FCW514MC9DAVTAJBBSTDR5P7, mint: 1628640000000, maxt: 1628661599001, range: 5h59m59s>, <ulid: 01FCW527GHM1V3BTMGWJXSZ3JC, mint: 1628647200000, maxt: 1628654399001, range: 1h59m59s>\n[mint: 1628654400000, maxt: 1628661599001, range: 1h59m59s, blocks: 2]: <ulid: 01FCW514MC9DAVTAJBBSTDR5P7, mint: 1628640000000, maxt: 1628661599001, range: 5h59m59s>, <ulid: 01FCW52DHMMZCKX6PPTAEVVM9A, mint: 1628654400000, maxt: 1628661599001, range: 1h59m59s>\n[mint: 1628661600000, maxt: 1628668799001, range: 1h59m59s, blocks: 2]: <ulid: 01FCW52KK7F98KR9N1G9D4VPYG, mint: 1628661600000, maxt: 1628668799001, range: 1h59m59s>, <ulid: 01FCW5153RF2BMBBGXMCAW5916, mint: 1628661600000, maxt: 1628668799001, range: 1h59m59s>\n[mint: 1628668800000, maxt: 1628675999001, range: 1h59m59s, blocks: 2]: <ulid: 01FCW52ST0Q92GDK8DC85CYFNS, mint: 1628668800000, maxt: 1628675999001, range: 1h59m59s>, <ulid: 01FCW4AV94BCM4ZD6RHK1Z3M37, mint: 1628668800000, maxt: 1628675999001, range: 1h59m59s>"
    prometheus_1  | level=info ts=2021-08-12T03:12:50.308Z caller=compact.go:692 component=tsdb msg="Found overlapping blocks during compaction" ulid=01FCW5J83D5PWCKMJ5P9FD4H3X
    prometheus_1  | level=info ts=2021-08-12T03:12:50.454Z caller=compact.go:454 component=tsdb msg="compact blocks" count=4 mint=1628640000000 maxt=1628661599001 ulid=01FCW5J83D5PWCKMJ5P9FD4H3X sources="[01FCW514MC9DAVTAJBBSTDR5P7 01FCW521C9JHXC2S7MMEWN72AQ 01FCW527GHM1V3BTMGWJXSZ3JC 01FCW52DHMMZCKX6PPTAEVVM9A]" duration=245.7086ms
    prometheus_1  | level=error ts=2021-08-12T03:12:52.058Z caller=db.go:780 component=tsdb msg="compaction failed" err="reloadBlocks blocks: invalid block sequence: block time ranges overlap: [mint: 1628661600000, maxt: 1628668799001, range: 1h59m59s, blocks: 2]: <ulid: 01FCW5153RF2BMBBGXMCAW5916, mint: 1628661600000, maxt: 1628668799001, range: 1h59m59s>, <ulid: 01FCW52KK7F98KR9N1G9D4VPYG, mint: 1628661600000, maxt: 1628668799001, range: 1h59m59s>\n[mint: 1628668800000, maxt: 1628675999001, range: 1h59m59s, blocks: 2]: <ulid: 01FCW4AV94BCM4ZD6RHK1Z3M37, mint: 1628668800000, maxt: 1628675999001, range: 1h59m59s>, <ulid: 01FCW52ST0Q92GDK8DC85CYFNS, mint: 1628668800000, maxt: 1628675999001, range: 1h59m59s>\n[mint: 1628676000000, maxt: 1628676299001, range: 4m59s, blocks: 2]: <ulid: 01FCW52YXKKZ8HPXZY2QY5R5FS, mint: 1628676000000, maxt: 1628676299001, range: 4m59s>, <ulid: 01FCW4B0D0C46EF2YZDG3YWJ0J, mint: 1628676000000, maxt: 1628676299001, range: 4m59s>"
    prometheus_1  | level=error ts=2021-08-12T03:14:53.812Z caller=db.go:766 component=tsdb msg=reloadBlocks err="invalid block sequence: block time ranges overlap: [mint: 1628676000000, maxt: 1628676299001, range: 4m59s, blocks: 2]: <ulid: 01FCW4B0D0C46EF2YZDG3YWJ0J, mint: 1628676000000, maxt: 1628676299001, range: 4m59s>, <ulid: 01FCW52YXKKZ8HPXZY2QY5R5FS, mint: 1628676000000, maxt: 1628676299001, range: 4m59s>\n[mint: 1628640000000, maxt: 1628647199001, range: 1h59m59s, blocks: 2]: <ulid: 01FCW521C9JHXC2S7MMEWN72AQ, mint: 1628640000000, maxt: 1628647199001, range: 1h59m59s>, <ulid: 01FCW514MC9DAVTAJBBSTDR5P7, mint: 1628640000000, maxt: 1628661599001, range: 5h59m59s>\n[mint: 1628647200000, maxt: 1628654399001, range: 1h59m59s, blocks: 2]: <ulid: 01FCW514MC9DAVTAJBBSTDR5P7, mint: 1628640000000, maxt: 1628661599001, range: 5h59m59s>, <ulid: 01FCW527GHM1V3BTMGWJXSZ3JC, mint: 1628647200000, maxt: 1628654399001, range: 1h59m59s>\n[mint: 1628654400000, maxt: 1628661599001, range: 1h59m59s, blocks: 2]: <ulid: 01FCW514MC9DAVTAJBBSTDR5P7, mint: 1628640000000, maxt: 1628661599001, range: 5h59m59s>, <ulid: 01FCW52DHMMZCKX6PPTAEVVM9A, mint: 1628654400000, maxt: 1628661599001, range: 1h59m59s>\n[mint: 1628661600000, maxt: 1628668799001, range: 1h59m59s, blocks: 2]: <ulid: 01FCW52KK7F98KR9N1G9D4VPYG, mint: 1628661600000, maxt: 1628668799001, range: 1h59m59s>, <ulid: 01FCW5153RF2BMBBGXMCAW5916, mint: 1628661600000, maxt: 1628668799001, range: 1h59m59s>\n[mint: 1628668800000, maxt: 1628675999001, range: 1h59m59s, blocks: 2]: <ulid: 01FCW4AV94BCM4ZD6RHK1Z3M37, mint: 1628668800000, maxt: 1628675999001, range: 1h59m59s>, <ulid: 01FCW52ST0Q92GDK8DC85CYFNS, mint: 1628668800000, maxt: 1628675999001, range: 1h59m59s>"
    [...]
    

    It went away simply enabling the storage.tsdb.allow-overlapping-blocks as described in the docs: https://prometheus.io/docs/prometheus/latest/storage/#usage

    A simple warning is shown now and backfill proceeds as expected

    prometheus_1  | level=info ts=2021-08-12T03:36:56.469Z caller=compact.go:692 component=tsdb msg="Found overlapping blocks during compaction" ulid=01FCW6YCC5TREHFSPCD8F6KD6J
    prometheus_1  | level=info ts=2021-08-12T03:36:57.462Z caller=compact.go:454 component=tsdb msg="compact blocks" count=8 mint=1629266400000 maxt=1629331199001 ulid=01FCW6YCC5TREHFSPCD8F6KD6J sources="[01FCW6WGGW3GGZ1F6X9KYBBDKK 01FCW6WQ6K2BFBKDDKR45QAAAQ 01FCW6WY7CPTAJFEVT6NBRCZK9 01FCW6X5393PBK8C3CEFX1WRDX 01FCW6XC0MR7CKVTMTZK2B1P12 01FCW6XK4MTGEY093JD5A78Q85 01FCW6XRPE4C8C53MPNB5J50M0 01FCW6Y5NZZRMHFQ1TXHR88JVT]" duration=1.0261382s
    prometheus_1  | level=warn ts=2021-08-12T03:36:57.597Z caller=db.go:1084 component=tsdb msg="Overlapping blocks found during reloadBlocks" detail="[mint: 1629331200000, maxt: 1629338399001, range: 1h59m59s, blocks: 2]: <ulid: 01FCW6YCDRTMSPCZQWM05FXQ2J, mint: 1629331200000, maxt: 1629338399001, range: 1h59m59s>, <ulid: 01FCW64189DDKV7ACDJG5V0RV9, mint: 1629331200000, maxt: 1629352799001, range: 5h59m59s>"
    prometheus_1  | level=info ts=2021-08-12T03:36:57.617Z caller=db.go:1239 component=tsdb msg="Deleting obsolete block" block=01FCW6WGGW3GGZ1F6X9KYBBDKK
    prometheus_1  | level=info ts=2021-08-12T03:36:57.638Z caller=db.go:1239 component=tsdb msg="Deleting obsolete block" block=01FCW6WY7CPTAJFEVT6NBRCZK9
    [...]
    

    Let me know if this PR needs any modifications.

  • Fix / simplify mode descriptions in readme

    Fix / simplify mode descriptions in readme

    Fixes use of "rgb" where "grayscale" should have been used.

    Also removing specific numbers around overrides since the total number has changed at various points / in different videos. Later I may add support for adjustable bit depth per channel.

  • Update docs

    Update docs

    • Adds preview image/gif for every mode.
    • Updates docs for latest version of grafana-image-renderer-cli.
    • Moves usage/installation docs to the docs folder.
    • Makes renderer usage docs a lot easier to read.
    • Other misc improvements.
  • Switch to Grafana 8.0

    Switch to Grafana 8.0

    This PR switches to Grafana 8 and Image Renderer 3.

    I've kept the old dashboard, which behaves almost the same as before. It takes about 5-10% less time to render each frame versus Grafana 7.

    I've also added a new dashboard which uses the new Time Series panel (pvr-dash-8), which takes about 50-60% less time to render each frame versus the old Graph panel. The downside is that it looks (in my opinion) slightly worse, as the horizontal gaps between pixels are slightly easier to see.

    For the new dashboard, I just wrote jsonnet for the overrides since I couldn't find anything in the grafana libraries for the Time Series panel. You have to manually paste the output in the grafana-created dashboard json.

Parse and generate m3u8 playlists for Apple HTTP Live Streaming (HLS) in Golang (ported from gem https://github.com/sethdeckard/m3u8)

go-m3u8 Golang package for m3u8 (ported m3u8 gem https://github.com/sethdeckard/m3u8) go-m3u8 provides easy generation and parsing of m3u8 playlists d

Nov 19, 2022
Parser and generator of M3U8-playlists for Apple HLS. Library for Go language. :cinema:

M3U8 This is the most complete opensource library for parsing and generating of M3U8 playlists used in HTTP Live Streaming (Apple HLS) for internet vi

Dec 20, 2022
Desktop application to download videos and playlists from youtube by simply copying its url.
Desktop application to download videos and playlists from youtube by simply copying its url.

tubemp3 Desktop application to download videos and playlists from youtube by simply copying its url. You just need to run tubemp3 and copy (CTRL + C)

Oct 25, 2022
Project to get Youtube video descriptions and search those videos as required

FamPayProject Project to get Youtube video descriptions and search those videos as required Prerequisities Postgres DB for persisting data Youtube Dat

Nov 5, 2021
Export Adobe Connect videos to Mkv!
Export Adobe Connect videos to Mkv!

AdobeConnect To .mkv Introduction This app helps exporting AdobeConnect videos in situations like when you can just watch the past videos and you can'

Jan 5, 2023
A tool to stream videos📺 directly into VLC media player just by its name from terminal.
A tool to stream videos📺 directly into VLC media player just by its name from terminal.

PeerWatch A tool to stream videos directly into the VLC media player. Download Download the tool from here: Windows Linux win-x64 linux-x64 Building Y

Feb 12, 2022
Synthetic media is a realistic transformation of audio and video using artificial intelligence.

Synthetic media is a realistic transformation of audio and video using artificial intelligence.

Nov 20, 2021
golang function that download a video from youtube, and convert it to a mp3 file using ffmpeg

echedwnmp3 echedwnmp3 is a function that download a video from youtube, and convert it to a mp3 file using ffmpeg example package main import(echedwn

Dec 7, 2021
lmmp3 is a little golang library that download a video from youtube, and convert it to a mp3 file using ffmpeg

lmmp3 lmmp3 is a function that download a video from youtube, and convert it to a mp3 file using ffmpeg You need to have installed ffmpeg in your syst

Aug 12, 2022
Live on-demand transcoding in go using ffmpeg. Also with NVIDIA GPU hardware acceleration.

Go live HTTP on-demand transcoding Transcoding is expensive and resource consuming operation on CPU and GPU. For big companies with thousands of custo

Dec 16, 2022
Self-hosted web app for encoding files to a target format using distributed computing.
Self-hosted web app for encoding files to a target format using distributed computing.

What is Encodarr? Encodarr is a self-hosted web application that encodes video files to a target format using distributed computing to spread the work

Dec 30, 2022
Go-video-preview-ffmpeg-wrapper - A simple helper wrapper to generate small webm video previews using ffmpeg, useful for web previews.

Go-video-preview-ffmpeg-wrapper A simple helper wrapper to generate small webm video previews using ffmpeg, useful for web previews. Getting Started u

Jan 5, 2022
Package implement reading and writing popular playlist formats: PLS, ASX, M3U, XSPF and others.

go-playlist ⚠️ WARNING The API is not stable yet and can change. Package playlist implement reading and writing popular playlist formats: PLS, ASX, M3

Oct 14, 2021
ffcommander - An easy frontend to FFmpeg and Imagemagick to automatically process video and manipulate subtitles.

% FFCOMMANDER(1) ffcommander 2.39 % Mikael Hartzell (C) 2018 % 2021 Name ffcommander - An easy frontend to FFmpeg and Imagemagick to automatically pro

May 9, 2022
Parse and demux MPEG Transport Streams (.ts) natively in GO

This is a Golang library to natively parse and demux MPEG Transport Streams (ts) in GO. WARNING: this library is not yet production ready. Use at your

Jan 9, 2023
golang library to read and write various subtitle formats

libgosubs Golang library to read and write subtitles in the following formats Advanced SubStation Alpha v4 SRT TTML v1.0 - This is based on the spec p

Sep 27, 2022
Go bindings for libVLC and high-level media player interface
Go bindings for libVLC and high-level media player interface

Go bindings for libVLC 2.X/3.X/4.X and high-level media player interface. The package can be useful for adding multimedia capabilities to applications

Dec 31, 2022
RTSP 1.0 client and server library for the Go programming language

RTSP 1.0 client and server library for the Go programming language

Jan 3, 2023
falco is VCL parser and linter optimized for Fastly.
falco is VCL parser and linter optimized for Fastly.

falco falco is VCL parser and linter optimized for Fastly. Disclaimer This is a VCL parser, but dedicated to Fastly's VCL (version 2.x), so we don't c

Dec 7, 2022