Skip to content

Commit 81b669e

Browse files
authored
Merge branch 'main' into generateme-surfaces-3d
2 parents 62e806a + d160cd3 commit 81b669e

8 files changed

Lines changed: 458 additions & 2 deletions

File tree

deps.edn

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@
4848

4949
org.soulspace/qclojure {:mvn/version "0.22.0"}
5050
org.babashka/http-client {:mvn/version "0.4.22"}
51+
com.github.danielsz/bioscoop {:mvn/version "1.0.5"}
5152
}
5253

5354
:aliases

site/db.edn

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,12 @@
2121
:url "https://scicloj.github.io/contributors/daslu/"
2222
:affiliation [:scicloj]
2323
:links [{:icon "github" :href "https://github.com/daslu"}]}
24+
{:id :danielsz
25+
:name "Daniel Szmulewicz"
26+
:image "https://avatars.githubusercontent.com/u/859131?v=4"
27+
:url "https://danielsz.github.io/"
28+
:affiliation []
29+
:links [{:icon "github" :href "https://github.com/danielsz"}]}
2430
{:id :alexmiller
2531
:name "Alex Miller"
2632
:image "https://avatars.githubusercontent.com/u/171129?v=4"
@@ -147,7 +153,13 @@
147153
:image "https://avatars.githubusercontent.com/u/38646601?v=4"
148154
:url "https://github.com/genmeblog"
149155
:affiliation [:scicloj]
150-
:links [{:icon "github" :href "https://github.com/genmeblog"}]}]
156+
:links [{:icon "github" :href "https://github.com/genmeblog"}]}
157+
{:id :com.github/teodorlu
158+
:name "Teodor Heggelund"
159+
:url "https://teod.eu/"
160+
:image "https://play.teod.eu/img/teodor-heggelund-skitur.jpg"
161+
:links [{:icon "github" :href "https://github.com/teodorlu"}]}
162+
,]
151163

152164
:affiliation
153165
[{:id :clojure.core

src/bioscoop/bioscoop.gif

25.8 KB
Loading

src/bioscoop/masterpiece.gif

1.01 MB
Loading

src/bioscoop/quickstart.clj

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
^{:kindly/hide-code true
2+
:clay {:title "Bioscoop, a DSL for FFmpeg"
3+
:quarto {:author [:danielsz]
4+
:description "Quickstart for Clojurians"
5+
:draft false
6+
:type :post
7+
:date "2025-10-27"
8+
:category :clojure
9+
:tags [:creative_coding]}}}
10+
(ns bioscoop.quickstart
11+
(:require [scicloj.kindly.v4.kind :as kind]
12+
[bioscoop.quickstart :as qs]))
13+
14+
;; This document serves as a quickstart for the Bioscoop library. It is geared toward Clojurians as it assumes knowledge of namespaces, the REPL, etc.
15+
16+
;; Bioscoop is a DSL to program FFmpeg's filtergraphs. Start by requiring the Bioscoop macros and the `bioscoop.built-in` namespace.
17+
18+
(require '[bioscoop.macro :refer [bioscoop defgraph]]
19+
'[bioscoop.built-in :refer [help]])
20+
21+
;; Let's build a simple animation. We will start with a black background. The _color_ filter provides that.
22+
23+
(bioscoop (color))
24+
25+
;; Note that we didn't require _color_. It is available thanks to the `bioscoop.built_in` namespace, alongside all of the other filters.
26+
27+
;; If you need help with the parameters that a filter accepts, type in the REPL:
28+
29+
^:kind/hidden
30+
(help "color")
31+
32+
;; Bioscoop recognizes the same parameters as FFmpeg, with a caveat. In FFmpeg, some filters define the same parameter twice, once fully spelled out, and once in shorthand form (as if the syntax wasn't terse enough). For example, _w_ and _width_. Bioscoop doesn't accept the shorthand version *by design*.
33+
34+
;; On top of that black canvas, we are going to draw text twice per second, positioned randomly. In order to achieve that, we will refer the _x_ and _y_ coordinates to an expression instead of fixed values.
35+
36+
(bioscoop (drawtext {:text "bioscoop" :fontcolor "white" :x "'mod(random(0)*10000,W-tw)'" :y "'mod(random(1)*10000,H-th)'"}))
37+
38+
;; The bioscoop macro accepts a subset of Clojure. You can use _let_ bindings and all of _clojure.core_. It returns a data structure, the internal representation of a filtergraph.
39+
40+
;; Putting everything together, we can write:
41+
42+
(bioscoop (chain (color {:duration 5})
43+
(drawtext {:text "bioscoop"
44+
:fontcolor "white"
45+
:x "'mod(random(0)*10000,W-tw)'"
46+
:y "'mod(random(1)*10000,H-th)'"})
47+
(fps {:fps "2"})))
48+
49+
;; Or, if we need a handle on the filtergraph, we can use _defgraph_ which will intern a Var with a name of our choosing.
50+
51+
(defgraph filtergraph (chain (color {:duration 5})
52+
(drawtext {:text "bioscoop"
53+
:x "'mod(random(0)*10000,W-tw)'"
54+
:y "'mod(random(1)*10000,H-th)'"})
55+
(fps {:fps "2"})))
56+
57+
;; To convert the internal data structure, or the handle, back to a filtergraph, we use _to-ffmpeg_:
58+
59+
(require '[bioscoop.render :refer [to-ffmpeg]])
60+
(to-ffmpeg filtergraph)
61+
62+
;; Finally, the filtergraph is ready to be fed to FFmpeg. While there is a helper in Bioscoop, how and where you run the FFmpeg command is entirely up to you. For example, you can display the animation in the terminal with `ffplay -f lavfi -i` followed by the filtergraph.
63+
;;
64+
;; *Note:* FFplay is a companion player that is most often installed together with FFMpeg.
65+
66+
;; ![Bioscoop](bioscoop.gif)
67+
;;
68+
;; And voilà!
69+
70+
;; Content creators often reuse a preamble in their broadcasts. This use case is an excellent opportunity to demonstrate how Bioscoop provides means of composition.
71+
;; It also demonstrates how you reuse definitions across namespace boundaries.
72+
73+
^:kind/hidden
74+
(in-ns 'bioscoop.masterpiece)
75+
^{:kindly/hide-code true :kindly/kind :kind/hidden}
76+
(clojure.core/refer-clojure)
77+
(require '[bioscoop.quickstart :refer [filtergraph]]
78+
'[bioscoop.macro :refer [bioscoop defgraph]]
79+
'[bioscoop.built-in])
80+
81+
;; We will simulate the actual video content with a FFMpeg dummy filter, _testsrc_. The intro is our filtergraph referred to in the `bioscoop.quickstart` namespace.
82+
83+
(defgraph masterpiece (testsrc))
84+
(bioscoop (compose [filtergraph ["intro"]]
85+
[masterpiece ["masterpiece"]]
86+
[["intro"] ["masterpiece"] (concat {:n 2})]))
87+
88+
;; ![Masterpiece](masterpiece.gif)
89+
;;
90+
91+
;; And voilà, again!
92+
;;
93+
;; What are you going to make? We'll be happy to link to **your** masterpiece in Bioscoop's [gallery](https://github.com/danielsz/bioscoop#gallery).
94+
95+
96+
Lines changed: 155 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,155 @@
1+
^{:clay {:title "Growing explanations together" :quarto {:author :com.github/teodorlu :draft true :type :post :date "2025-10-26"}}}
2+
(ns civitas.why.growing-explanations-together
3+
(:require [babashka.fs :as fs]
4+
[scicloj.kindly.v4.kind :as kind]))
5+
6+
;; # Growing explanations together
7+
;;
8+
;; _reflections from a personal learning journey_
9+
10+
11+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
12+
;; ## You should make a little home for yourself on the web!
13+
14+
;; “Civitas is stupid, everyone should just create their own static site!”
15+
;; I read something like this one time.
16+
;; And I think it's wrong!
17+
;; I say it's wrong with conviction because I've previously believed it's right.
18+
;;
19+
;; But first, let's discover the truth in that statement.
20+
;;
21+
;; Our mother's milk as Clojurians is simplicity.
22+
;; Do create simple systems.
23+
;; Don't complect.
24+
;; Don't pull in lots of other people's depencies.
25+
;; This is how you learn.
26+
;; This is how you avoid ending up in a frontend hell with 53 MB of javascript required to show anything.
27+
;; This is how you end up with a simple system!
28+
;;
29+
;; The web is a wonderful place, and I encourage you strongly to make a part of it your own!
30+
;; I find it *completely amazing that I can type up some random shit about [the kind of things I like to learn], make a URL for that idea, and give it to a friend.
31+
;; How wonderful is that!
32+
;; And how *quick* is that!
33+
;; Before the World Wide Web, Tim Berners Lee had jump through way many more hoops to achieve that.
34+
;;
35+
;; [the kind of things I like to learn]: https://play.teod.eu/computing-learning-designing-researching/
36+
;;
37+
;; Additionally, a simple web site is just a folder of files.
38+
;; No program-running necessary!
39+
;; Just write an HTML file and publish.
40+
;; In the event that you want a better interface for typing, you are in complete control in order to solve that.
41+
;; For me personally, [Babashka] has been a super-tool for doing that.
42+
;; I can write the HTML generation program in the programming language I prefer (Clojure), and regenerate my web site quickly without having warm JVM at hand.
43+
;; Oh, the joy!
44+
;; The experience with Babashka-powered knowledge on the web got me so excited I had to present [Build Your Own Little Memex with Babashka] on the first Babashka conference.
45+
;; Oh, the joy!
46+
;; Absolutely recommended, you should *totally* do that yourself
47+
;;
48+
;; [Babashka]: https://babashka.org/
49+
;; [Build Your Own Little Memex with Babashka]: https://play.teod.eu/build-your-own-little-memex-with-babasha/
50+
;;
51+
;; But.
52+
;;
53+
;; After having written, ... let me check, ...
54+
55+
(comment
56+
(count (fs/glob "../../teodorlu/play.teod.eu" "*/play.edn"))
57+
;; => 479
58+
;; Explanations get better with a Clojure REPL at hand, am I right???
59+
;;
60+
;; (this code is evaluated as I'm writing it because other people
61+
;; shouldn't have to depend on my personal mess.)
62+
)
63+
64+
;; After having written 479 documents, what have I gained?
65+
;;
66+
;; - I've explored what happens when I let myself have ideas
67+
;; - I've learned to build my own knowledge system
68+
;; - … and I've learned that this is *my* thing.
69+
;; Due to the amount of personalization on my site, it works super well for me.
70+
;; For others?
71+
;; I woudn't recommend using it.
72+
;; Consider stealing a piece or two or fishing for some inspiration, but *please do make your own thing*.
73+
;;
74+
;; What about the knowledge-building?
75+
;; For me, it's superb.
76+
;; I've learned to learn.
77+
;; Write an explanation for myself, then I understand it.
78+
;; The two explanations I'm most happy with are [Easy, explicit parallellism with pipeline-blocking] (collaboration with [Ruben Svealdson])
79+
;; and [Rainbow tables: what they are, and why we salt passwords before hashing, explained with Clojure] (which I decided to move from my site to Clerk.Garden).
80+
;;
81+
;; [Easy, explicit parallellism with pipeline-blocking]: https://play.teod.eu/clojure-easy-parallellism-with-pipeline-blocking/
82+
;; [Ruben Svealdson]: https://github.com/rubensseva
83+
;; [Rainbow tables: what they are, and why we salt passwords before hashing, explained with Clojure]: https://github.clerk.garden/teodorlu/lab/commit/1cfe71b8bf1b34ecbcf2fd6d1119985b49eab74c/src/rainbow_tables_2/
84+
;;
85+
86+
87+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
88+
;; ## Simple, great for learning—but ultimately isolated.
89+
;;
90+
;; My personal web site is great for myself, but not comprehensible for others.
91+
;;
92+
;; > Lisp allows you to just chuck things off so easily, and it is easy to take
93+
;; > this for granted. I saw this 10 years ago when looking for a GUI to my
94+
;; > Lisp. No problem, there were 9 different offerings. The trouble was that
95+
;; > none of the 9 were properly documented and none were bug free. Basically
96+
;; > each person had implemented his own solution and it worked for him so that
97+
;; > was fine. This is a BBM attitude; it works for me and I understand it. It
98+
;; > is also the product of not needing or wanting anybody else's help to do
99+
;; > something.
100+
;;
101+
;; That's me.
102+
;; I made my own tiny world, lived in it, and it was awesome.
103+
;; But I couldn't invite anybody else in.
104+
105+
106+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
107+
;; ## Solving for cohesion and curation
108+
;;
109+
;; You exist in context.
110+
;; People might be interested in what you have to say, and they're also going to be interested in what others have to say.
111+
;; If you're Alan Kay or Bret Victor, you may be able to create a microworld and invite people in, but most people aren't Alan Kay or Bret Victor.
112+
;; That means people are going to be experiencing your creations in a context of other people's creations.
113+
;;
114+
;; That means my tiny, little static web site is never going to be someone else's world.
115+
;; Sure, a curious reader may look around prompted by interest, but the reader will finish that trail of curiosity and do something else.
116+
;;
117+
;; To reach more with the explanations we create, we want to ensure cohesion with other people's explanations, and curate the very good explanations.
118+
;;
119+
;; The Clojure Civitas that Timothy Pratley has created hits the bullseye for that aim.
120+
;;
121+
;; Everyone writes in the same Git repository.
122+
;; That means you can follow one Git log and catch every change, should you want to.
123+
;; You can write prose and Clojure, and share it.
124+
125+
126+
;; ## Explanation playlists is the key.
127+
;;
128+
;; Curation has not yet been visibly tackled (as I see it), but the foundation has been laid.
129+
;; In my Memex presentation, I argued that we need [knowledge playlists][knowledge playlist].
130+
;; Today, I prefer the term _explanation playlist_.
131+
;; I define an explanation playlist as
132+
;;
133+
;; > an ordered list of contextualized explanations that can be consumed from start to end.
134+
;;
135+
;; [knowledge playlist]: https://play.teod.eu/knowledge-playlist/
136+
;;
137+
;; What's the right medium for an explanation playlist?
138+
;; Something special, right?
139+
;; No!
140+
;; It's just another explanation.
141+
;; It weaves other explanations together, letting you more easily orient yourself in the bigger picture.
142+
;; It's just yet another hypertext document.
143+
;;
144+
;; Clojure Civitas can help us beat the [Curse of Lisp], and give Clojure the reach it deserves.
145+
;;
146+
;; [Curse of Lisp]: https://winestockwebdesign.com/Essays/Lisp_Curse.html
147+
148+
149+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
150+
;; ## Consider contributing!
151+
;;
152+
;; After being very pleasantly surprised by the Noj-powered tooling that drives Clojure Civitas, I'm excited to lean into Civitas.
153+
;; My personal web site continues to be a place of eploratory play, but now I have a goal for Clojure content:
154+
;; Put it on Civitas.
155+
;; On Civitas it can outlive me, and help grow a commons of knowledge, instead of yet another isolated island.

0 commit comments

Comments
 (0)