/cljs-audiocapture

ClojureScript core.async interface for audio capture

Primary LanguageJavaScriptOtherNOASSERTION

cljs-audio

ClojureScript core.async interface for capturing audio in modern browsers

Installation

cljs-audio is available in Maven Central. Add it to your :dependencies in your Leiningen project.clj or in your build.boot:

[cljs-audiocapture "0.1.4"]

If you use boot to build your project, use sift task to add audiocapture.swf to your project:

(sift :add-jar {'cljs-audiocapture #"^audiocapture\.swf"})

Compatibility

Tested against lastest stable versions of Chromium-based browsers, Firefox. With Flash fallback cljs-audiocapture works in IE11 (and maybe below) and Safari.

Usage

cljs-audiocapture namespace has one public funtion capture-audio. It returns channel that blocks and waits while user allow or deny access to their microphone. The only value in this channel is map with keys :audio-chan and :error.

If user denies access or other error occurs :error value will be filled with browser-specific error. Otherwise you get bidirectional channel in :audio-chan.

To start or resume audio capture you should put :start to this channel. After you should read frames from this channel. Each frame is ArrayBuffer of raw PCM data. You can record it and wrap to RIFF WAV or process other way. To pause just put :pause to channel.

To use flash fallback you should put audiocapture.swf to place your script has access to.

(ns cljs-audiocapture-demo
  (:require
    [cljs.core.async :as async]
    [cljs-audiocapture.core :refer [capture-audio]])
  (:require-macros
    [cljs.core.async.macros :refer [go]]))

(go
  (let [{:keys [audio-chan error]} (async/<! (capture-audio))]
    (if error
      (js/console.error error)
      (do
        (async/put! audio-chan :start)
        ; Print first 5 frames to console
        (loop [counter 4]
          (.log js/console (async/<! audio-chan))
          (if (zero? counter)
            (async/put! audio-chan :pause)
            (recur (dec counter))))))))

Examples

(go
  ; This will fail after queue overflow
  (let [{:keys [audio-chan error]} (async/<! (capture-audio))]
    (if error
      (js/console.error error)
      (async/put! audio-chan :start))))

(go
  ; This will work while browser runs
  (let [{:keys [audio-chan error]} (async/<! (capture-audio (async/sliding-buffer 10)))]
    (if error
      (js/console.error error)
      (async/put! audio-chan :start)))))

(go
  ; This will stop after printing 6 frames and pause capture
  (let [{:keys [audio-chan error]} (async/<! (capture-audio))]
    (if error
      (js/console.error error)
      (do
        (async/put! audio-chan :start)
        (loop [counter 5]
          (.log js/console (async/<! audio-chan))
          (if (zero? counter)
            (async/put! audio-chan :pause)
            (recur (dec counter))))))))

License

Copyright © YANDEX LLC, 2015. Distributed under the Eclipse Public License, which can be found in LICENSE.md at the root of this distribution. By using this software in any fashion, you are agreeing to be bound by the terms of this license. You must not remove this notice, or any other, from this software.