This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2021-03-21
Channels
- # announcements (2)
- # asami (8)
- # aws (4)
- # beginners (32)
- # calva (12)
- # cider (72)
- # clj-kondo (16)
- # clojure (11)
- # clojure-germany (2)
- # clojure-italy (4)
- # clojure-serbia (2)
- # clojurescript (26)
- # data-oriented-programming (8)
- # datomic (9)
- # deps-new (17)
- # eastwood (4)
- # emacs (20)
- # fulcro (18)
- # funcool (1)
- # graalvm (8)
- # leiningen (12)
- # lsp (34)
- # malli (25)
- # meander (4)
- # membrane (4)
- # off-topic (153)
- # practicalli (1)
- # releases (2)
- # remote-jobs (3)
- # rewrite-clj (77)
- # ring (5)
- # shadow-cljs (108)
- # spacemacs (12)
- # tools-deps (9)
- # vscode (11)
- # xtdb (4)
Hi all! I want to capture microphone input with clojurescript.
I wonder if there are any existing examples. I have not found any yet.
Anything related to audio/video input will most likely be all about JavaScript, so I would search JS tutorials/resources and use CLJS interop.
Here is an example of using the speechsynthesis
API https://github.com/athomasoriginal/clojurescript-30/tree/master/23-speech-synthesis
I feel that demo might have a bug in it, but perhaps it can help you on your journey 🙏
https://github.com/athomasoriginal/clojurescript-30/tree/master/20-native-speech-recognition does speech rec
I've created a minimal example, based on MDN's MediaStream Recording API: https://developer.mozilla.org/en-US/docs/Web/API/MediaStream_Recording_API/Using_the_MediaStream_Recording_API
(ns web-audio.app.core
(:require [reagent.core :as r]
[reagent.dom :as rdom]))
(defn log [x]
(.log js/console x))
(defonce chunks (r/atom []))
(defn app []
(let [nav (.-mediaDevices js/navigator)
gum (.-getUserMedia nav)
cs (clj->js {:audio true})
rec-ref (atom nil)
stp-ref (atom nil)
_ (if gum
(-> (.getUserMedia nav cs)
(.then (fn [stream]
(let [mr (js/MediaRecorder. stream)
rh #(do (.start mr)
(log (.-state mr))
(log "recorder started"))
sh #(do (.stop mr)
(log (.-state mr))
(log "recorder stopped"))
stop-mr (fn []
(let [aud (.createElement js/document "audio")
_ (.setAttribute aud "controls" "")
_ (set! (.-controls aud) true)
_ (.appendChild (.-body js/document) aud)
attr (clj->js {"type" "audio/ogg; codecs=opus"})
blob (js/Blob. @chunks attr)
audio-url (.createObjectURL (.-URL js/window) blob)]
(log "media recorder stopped")
(reset! chunks [])
(set! (.-src aud) audio-url)))
_ (set! (.-ondataavailable mr)
(fn [e]
(swap! chunks conj (.-data e))))]
(set! (.-onclick @rec-ref) rh)
(set! (.-onclick @stp-ref) sh)
(set! (.-onstop mr) stop-mr))))
(.catch (fn [err] (log err))))
(log "getUserMedia not supported on your browser!"))]
(fn []
[:div
[:h1 "Web Audio Recording"]
[:button {:ref #(reset! rec-ref %)} "Record"]
[:button {:ref #(reset! stp-ref %)} "Stop"]])))
(defn render []
(rdom/render [app] (.getElementById js/document "root")))
(defn ^:export main []
(render))
(defn ^:dev/after-load reload! []
(render))
@U3ES97LAC From the example above, it's just a lot of JS interop, setting up a few event listeners manually (ie. not via React) since they need to be embedded in the Promise returned by getUserMedia. You may find it simpler to use a library such as https://github.com/closeio/mic-recorder-to-mp3 , which I've used before and like.
I am trying to support the syntax foo.bar.baz
for JS objects stored in vars (don't exist at runtime, I know) or locals, in clj-kondo.
cljs.user=> (def foo #js {:foo #js {:bar 1}})
#'cljs.user/foo
cljs.user=> foo.bar
nil
cljs.user=> foo.foo.bar
1
I run into some issues with goog
as a special case:
cljs.user=> (some? goog.global)
true
cljs.user=> (some? goog)
^
WARNING: Use of undeclared Var cljs.user/goog at line 1
false
What is goog
, why can you do goog.global
, but not goog
instead of js/goog
?
Is there a special list of goog.{global, ...}
things that are supported whereas other goog.foobars
are not supported?Or is goog.foobar
special syntactic sugar for js/goog.foobar
, while goog
itself isn't treated as js/goog
?
This is the issue: https://github.com/clj-kondo/clj-kondo/issues/1189
This is it maybe? https://github.com/clojure/clojurescript/blob/3fdaabedb1343f434b6cb4f75fa28e748f96eff0/src/main/clojure/cljs/analyzer.cljc#L2593
@borkdude symbols with dots are somewhat of a weird case in the compiler. goog
is the root object of the closure library provided by the goog/base.js
file. it is implicit and always exists as a namespace alias
so if goog
is an alias, why can I do goog.global
but not:
cljs.user=> (require '[clojure.set :as set])
nil
cljs.user=> set.union
Execution error (ReferenceError) at (<cljs repl>:1).
Can't find variable: set
well as I said it is weird and buggy if you ask me but the basic logic for symbols with a .
is to just treat them as regular JS lookups
so goog.global
will end up as goog.global
in the JS code, which exists provided by the goog/base.js
What are people using to componentize their CSS these days?