!!con 2018 Presentation - Overscan
#lang overscan | |
(require overscan/macos | |
overscan/draw | |
(only-in racket/file make-temporary-file) | |
racket/draw | |
(only-in racket/math pi) | |
"twitch-secret.rkt") | |
(define cam+screen | |
; by default, a picture-in-picture draws a 640x360 video | |
; 426x240 is another good choice | |
(picture-in-picture (camera 0) (screen 0) | |
#:x 320 | |
#:y 180 | |
#:alpha 0.0)) | |
(define-values (drawable-pip drawing-surface) | |
(make-drawable cam+screen)) | |
(define (tmpfilesink [name #f]) | |
; just a handy function to have around | |
(parameterize ([current-logger overscan-logger]) | |
(let* ([tmpfile (make-temporary-file)] | |
[sink (filesink tmpfile)]) | |
(log-debug (path->string tmpfile)) | |
sink))) | |
(define pipeline | |
;; A TWITCH_STREAM_KEY env variable will configure the twitch sink | |
(make-broadcast drawable-pip (audio 0) (twitch-sink) | |
#:preview (osxvideosink))) | |
(define (go!) | |
(call-atomically-in-run-loop | |
(λ () | |
(start pipeline)))) | |
(define (fade-in pip secs) | |
(thread | |
(λ () | |
(let ([tick (/ secs 100)]) | |
(let loop ([alpha 0]) | |
(set-picture-in-picture-alpha! pip (exact->inexact alpha)) | |
(when (< alpha 1) | |
(sleep tick) | |
(loop (+ alpha 1/100)))))))) | |
(define (fade-out pip secs) | |
; I would have DRY but then I didn't | |
(thread | |
(λ () | |
(let ([tick (/ secs 100)]) | |
(let loop ([alpha 1]) | |
(set-picture-in-picture-alpha! pip (exact->inexact alpha)) | |
(when (> alpha 0) | |
(sleep tick) | |
(loop (- alpha 1/100)))))))) | |
;; Racket Logo stuff down here: | |
;; https://docs.racket-lang.org/draw/overview.html#%28part._.Drawing_.Paths%29 | |
(define (paint-racket dc) | |
(send dc set-smoothing 'smoothed) | |
(send dc translate 365 60) | |
(send dc set-scale 0.8 0.8) | |
(send dc set-pen "black" 0 'transparent) | |
(send dc set-brush "white" 'transparent) | |
(send dc draw-path lambda-path) | |
(send dc set-pen "black" 0 'transparent) | |
(send dc set-brush "red" 'solid) | |
(send dc draw-path left-logo-path) | |
(send dc draw-path bottom-logo-path) | |
(send dc set-brush "blue" 'solid) | |
(send dc draw-path right-logo-path)) | |
(define left-lambda-path | |
(let ([p (new dc-path%)]) | |
(send p move-to 153 44) | |
(send p line-to 161.5 60) | |
(send p curve-to 202.5 49 230 42 245 61) | |
(send p curve-to 280.06 105.41 287.5 141 296.5 186) | |
(send p curve-to 301.12 209.08 299.11 223.38 293.96 244) | |
(send p curve-to 281.34 294.54 259.18 331.61 233.5 375) | |
(send p curve-to 198.21 434.63 164.68 505.6 125.5 564) | |
(send p line-to 135 572) | |
p)) | |
(define left-logo-path | |
(let ([p (new dc-path%)]) | |
(send p append left-lambda-path) | |
(send p arc 0 0 630 630 (* 47/72 2 pi) (* 121/360 2 pi) #f) | |
p)) | |
(define bottom-lambda-path | |
(let ([p (new dc-path%)]) | |
(send p move-to 135 572) | |
(send p line-to 188.5 564) | |
(send p curve-to 208.5 517 230.91 465.21 251 420) | |
(send p curve-to 267 384 278.5 348 296.5 312) | |
(send p curve-to 301.01 302.98 318 258 329 274) | |
(send p curve-to 338.89 288.39 351 314 358 332) | |
(send p curve-to 377.28 381.58 395.57 429.61 414 477) | |
(send p curve-to 428 513 436.5 540 449.5 573) | |
(send p line-to 465 580) | |
(send p line-to 529 545) | |
p)) | |
(define bottom-logo-path | |
(let ([p (new dc-path%)]) | |
(send p append bottom-lambda-path) | |
(send p arc 0 0 630 630 (* 157/180 2 pi) (* 47/72 2 pi) #f) | |
p)) | |
(define right-lambda-path | |
(let ([p (new dc-path%)]) | |
(send p move-to 153 44) | |
(send p curve-to 192.21 30.69 233.21 14.23 275 20) | |
(send p curve-to 328.6 27.4 350.23 103.08 364 151) | |
(send p curve-to 378.75 202.32 400.5 244 418 294) | |
(send p curve-to 446.56 375.6 494.5 456 530.5 537) | |
(send p line-to 529 545) | |
p)) | |
(define right-logo-path | |
(let ([p (new dc-path%)]) | |
(send p append right-lambda-path) | |
(send p arc 0 0 630 630 (* 157/180 2 pi) (* 121/360 2 pi) #t) | |
p)) | |
(define lambda-path | |
(let ([p (new dc-path%)]) | |
(send p append left-lambda-path) | |
(send p append bottom-lambda-path) | |
(let ([t (new dc-path%)]) | |
(send t append right-lambda-path) | |
(send t reverse) | |
(send p append t)) | |
(send p close) | |
p)) |
#lang slideshow | |
(require slideshow/text | |
racket/draw | |
"solarized.rkt") | |
(define current-bg-color | |
(make-parameter "white")) | |
(define current-fg-color | |
(make-parameter "black")) | |
(parameterize ([current-font-size 36] | |
[current-main-font "Avenir Next"] | |
[current-bg-color solarized-base3] | |
[current-fg-color solarized-base03] | |
[current-title-color (apply make-color solarized-base03)] | |
[current-titlet (λ (s) | |
(colorize (with-scale 1.5 (bt s)) | |
(current-title-color)))] | |
[current-slide-assembler (let ([original-assembler (current-slide-assembler)]) | |
(λ (title sep body) | |
(ct-superimpose | |
(inset (colorize (filled-rectangle (+ client-w margin margin) | |
(+ client-h margin margin)) | |
(current-bg-color)) | |
(- margin)) | |
(original-assembler title sep (colorize body | |
(current-fg-color))))))]) | |
(slide | |
#:name "Intro" | |
(with-size 140 (bold (t "We’re live!!"))) | |
(blank-line) | |
(colorize (t "@markwunsch") | |
solarized-base01)) | |
(parameterize ([current-fg-color solarized-base01]) ;adjust this slide!!! | |
(slide | |
#:title "Live Coding" | |
'next | |
(para #:width (- client-w margin margin) | |
(list "Live coding" | |
"(sometimes referred to as" | |
(colorize (t "’on-the-fly programming’") | |
solarized-base03) | |
", 'just in time programming', and" | |
(colorize (t "’conversational programming’") | |
solarized-base03) | |
") is a performing arts form and a" | |
(colorize (t "creativity technique") | |
solarized-base03) | |
"centred upon the writing of source code and the use of " | |
(colorize (t "interactive programming ") | |
solarized-base03) | |
"in an improvised way.")) | |
(blank-line) | |
(para #:align 'center | |
(with-size 28 (it "Thanks Wikipedia!"))))) | |
(slide | |
#:title "Live Coding Environments" | |
#:name "Live Coding" | |
(item (with-size 42 (bt "Extempore")) | |
(colorize (with-size 28 (para "extemporelang.github.io")) | |
solarized-base00)) | |
(item (with-size 42 (bt "Sonic Pi")) | |
(colorize (with-size 28 (para "sonic-pi.net")) | |
solarized-base00)) | |
(item (with-size 42 (bt "Overtone")) | |
(colorize (with-size 28 (para "overtone.github.io")) | |
solarized-base00))) | |
(slide | |
#:title "TOPLAP" | |
#:name "Live Coding" | |
(blank-line) | |
(colorize (with-size 48 | |
(bold (para "``Obscurantism is dangerous. Show us your screens.''"))) | |
solarized-violet) | |
(blank-line) | |
(para #:align 'center | |
(colorize (with-size 28 (t "toplap.org")) | |
solarized-base01)) | |
(para #:align 'center | |
(colorize (with-size 28 (t "livecode.nyc")) | |
solarized-base01))) | |
(slide | |
#:name "Live Streaming" | |
(titlet "Live Streaming")) | |
(parameterize ([current-bg-color "white"]) | |
(slide | |
#:name "Live Streaming" | |
(scale-to-fit (bitmap "img/livestream-surface-go.jpg") | |
client-w client-h))) | |
(parameterize ([current-font-size 60]) | |
(slide | |
#:name "live coding + live streaming" | |
(bt "live coding") | |
'next | |
(bt "+") | |
'next | |
(bt "live streaming"))) | |
(parameterize ([current-bg-color solarized-base03] | |
[current-font-size 156]) | |
(slide | |
#:name "Overscan" | |
(colorize (bit "Overscan") | |
solarized-base3))) | |
(parameterize ([current-bg-color solarized-base03] | |
[current-font-size 28]) | |
(slide | |
#:name "Overscan" | |
(colorize (with-size 156 (bit "Overscan")) | |
solarized-base3) | |
'alts | |
(list (list (colorize (para #:align 'center | |
"A live coding environment for live streaming video.") | |
solarized-cyan)) | |
(list (colorize (with-size 42 (para #:align 'center | |
"Take back the airwaves!")) | |
solarized-blue))))) | |
(parameterize ([current-bg-color solarized-base03] | |
[current-font-size 80]) | |
(slide | |
#:name "DEMO" | |
(colorize (bt "DEMO") | |
solarized-magenta))) | |
(parameterize ([current-bg-color solarized-base03]) | |
(slide | |
#:name "DEMO" | |
(colorize (with-size 60 (it "We’re already in the")) | |
solarized-base1) | |
(colorize (with-size 80 (bt "DEMO")) | |
solarized-magenta))) | |
(parameterize ([current-font-size 72] | |
[current-bg-color solarized-base03]) | |
(slide | |
#:name "twitch.tv/wunschkraft" | |
(colorize (t "twitch.tv/wunschkraft") | |
solarized-violet))) | |
(parameterize ([current-bg-color solarized-base03] | |
[current-fg-color solarized-base00] | |
[current-title-color (apply make-color solarized-base1)]) | |
(slide | |
#:name "Demo complete" | |
(titlet "Did the demo work?") | |
(with-size 28 (t "if not, oops.")))) | |
(slide | |
#:title "Under the Hood" | |
(item (with-size 42 (bt "Racket")) | |
(colorize (with-size 28 (para "racket-lang.org")) | |
solarized-base00)) | |
'next | |
(item (with-size 42 (bt "GStreamer")) | |
(colorize (with-size 28 (para "gstreamer.freedesktop.org")) | |
solarized-base00))) | |
(parameterize ([current-bg-color "white"]) | |
(slide | |
#:name "GStreamer" | |
(bitmap "img/gstreamer.png") | |
(bitmap "img/gstreamer-overview.png"))) | |
; (parameterize ([current-bg-color solarized-base03] | |
; [current-fg-color solarized-base1] | |
; [current-font-size 48]) | |
; (slide | |
; #:name "GStreamer" | |
; (tt "(require gstreamer)"))) | |
; (parameterize ([current-font-size 48]) | |
; (slide | |
; #:name "graphviz" | |
; (tt "(graphviz \"stream.dot\")"))) | |
; (parameterize ([current-bg-color "white"]) | |
; (slide | |
; #:name "graphviz" | |
; (scale-to-fit (bitmap "img/stream.png") | |
; client-w client-h))) | |
(parameterize ([current-bg-color solarized-base03] | |
[current-fg-color solarized-green] | |
[current-font-size 80]) | |
(slide | |
#:name "GObject" | |
(bit "GObject"))) | |
(slide | |
#:title "GObject Introspection" | |
(para "GObject introspection is a middleware layer between C libraries (using GObject) and language bindings.") | |
(blank-line) | |
(para #:align 'center | |
(colorize (with-size 28 (it "wiki.gnome.org/Projects/GObjectIntrospection")) | |
solarized-base01))) | |
; (parameterize ([current-bg-color solarized-base03] | |
; [current-fg-color solarized-base1] | |
; [current-font-size 48]) | |
; (slide | |
; #:name "GObject Introspection" | |
; (tt "(require ffi/unsafe/introspection)"))) | |
(parameterize ([current-font-size 30]) | |
(slide | |
#:name "Installation" | |
(para #:width client-w | |
(list (colorize (tt "$") | |
solarized-base00) | |
(tt "raco pkg install git://github.com/mwunsch/overscan"))))) | |
(parameterize ([current-fg-color solarized-base02]) | |
(slide | |
#:name "More" | |
(colorize (with-size 176 (bit "Overscan")) | |
solarized-base03) | |
(t "markwunsch.com/overscan") | |
; (tt "#lang overscan") | |
'next | |
(para #:align 'center | |
(list (it "it works on my machine") | |
"¯\\_(ツ)_/¯")))) | |
(parameterize ([current-bg-color solarized-base03] | |
[current-fg-color solarized-base2] | |
[current-font-size 80]) | |
(slide | |
#:name "stop" | |
(tt "(stop)")))) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment