Coder Social home page Coder Social logo

kagami / vmsg Goto Github PK

View Code? Open in Web Editor NEW
348.0 9.0 58.0 1.26 MB

:musical_note: Library for creating voice messages

Home Page: https://kagami.github.io/vmsg/

License: Creative Commons Zero v1.0 Universal

Makefile 3.37% C 6.77% CSS 10.71% JavaScript 79.15%
voice voice-messaging emscripten webassembly lame mp3

vmsg's Introduction

vmsg npm

vmsg is a small library for creating voice messages. While traditional way of communicating on the web is via text, sometimes it's easier or rather funnier to express your thoughts just by saying it. Of course it doesn't require any special support: record your voice with some standard program, upload to file hosting and share the link. But why bother with all of that tedious stuff if you can do the same in browser with a few clicks.

๐ŸŽŠ ๐ŸŽ‰ DEMO ๐ŸŽ‰ ๐ŸŽŠ

Features

  • No dependencies, framework-agnostic, can be easily added to any site
  • Small: ~73kb gzipped WASM module and ~3kb gzipped JS + CSS
  • Uses MP3 format which is widely supported
  • Works in all latest browsers

Supported browsers

  • Chrome 32+
  • Firefox 27+
  • Safari 11+
  • Edge 12+

Usage

npm install vmsg --save
import { record } from "vmsg";

someButton.onclick = function() {
  record(/* {wasmURL: "/static/js/vmsg.wasm"} */).then(blob => {
    console.log("Recorded MP3", blob);
    // Can be used like this:
    //
    // const form = new FormData();
    // form.append("file[]", blob, "record.mp3");
    // fetch("/upload.php", {
    //   credentials: "include",
    //   method: "POST",
    //   body: form,
    // }).then(resp => {
    // });
  });
};

That's it! Don't forget to include vmsg.css and vmsg.wasm in your project. For browsers without WebAssembly support you need to also include wasm-polyfill.js.

See demo directory for a more feasible example.

A minimal React example for using Recorder with your own UI can be found here.

See also non React demo and Recording mp3 audio in HTML5 using vmsg article.

Development

  1. Install Emscripten SDK.
  2. Install latest LLVM, Clang and LLD with WebAssembly backend, fix LLVM_ROOT variable of Emscripten config.
  3. Make sure you have a standard GNU development environment.
  4. Activate emsdk environment.
  5. git clone --recurse-submodules https://github.com/Kagami/vmsg.git && cd vmsg
    make clean all
    npm install
    npm start

These instructions are very basic because there're a lot of systems with different conventions. Docker image would probably be provided to fix it.

Technical details for nerds

vmsg uses LAME encoder underneath compiled with Emscripten to WebAssembly module. LAME build is optimized for size, weights only little more than 70kb gzipped and can be super-efficiently fetched and parsed by browser. It's like a small image.

Access to microphone is implemented with Web Audio API, data samples sent to Web Worker which is responsibe for loading WebAssembly module and calling LAME API.

Module is produced with modern LLVM WASM backend and LLD linker which should become standard soon, also vmsg has own tiny WASM runtime instead of Emscripten's to decrease overall size and simplify architecture. Worker code is included in the main JS module so end-user has to care only about 3 files: vmsg.js, vmsg.css and vmsg.wasm. CSS can be inlined too but IMO that would be ugly.

In order to support browsers without WebAssembly, WebAssembly polyfill is being used. It translates binary module into semantically-equivalent JavaScript on the fly (almost asm.js compatible but doesn't fully validate yet) so we don't need separate asm.js build and can use standard WebAssembly API. It's not as effecient but for audio encoding should be enough.

See also: Creating WebAssembly-powered library for modern web article.

Why not MediaRecorder?

MediaStream Recording API is great but:

  • Works only in Firefox and Chrome
  • Provides little to no options, e.g. VBR quality can't be specified
  • Firefox/Chrome encode only to Opus which can't be natively played in Safari and Edge

But you can use e.g. ogv.js polyfill!

  • It make things more complicated, now you need both encoder and decoder
  • Opus gives you ~2x bitrate win but for 500kb per minute files it's not that much
  • MP3 is much more widespread, so even while compression is not best compatibility matters

License

vmsg is licensed under CC0.
LAME is licensed under LGPL.
MP3 patents seems to have expired since April 23, 2017.

vmsg's People

Contributors

adamfranco avatar dependabot[bot] avatar kagami avatar neilpoulin avatar oleg-rdk avatar transitive-bullshit avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

vmsg's Issues

Issues on Safari and Chrome

Hi Kagami,

First, thanks for the great package. It's been wonderful to use, especially compared to a lot of the alternatives out there. I am using vmsg in a React app to record audio and post it to a server. I want users to be able to record many short samples within a single page session (just saying one or two words, so the audio file would only be a few seconds long). My implementation of the recording is very similar to your React demo. I wanted to ask for your help regarding issues I was having with Chrome, and make you aware about an issue that I found in Safari.

Regarding Safari, my application was freezing after 4 recordings. I found that this was because vmsg kept opening new AudioContexts, and I believe Safari limits the number of AudioContexts you can have open in a page. I was able to solve that by adding "this.audioCtx.close()" to the stopRecording() method in your code.

For Chrome, I get the following error after around 30 recordings in a page session:
"Error: RangeError: WebAssembly Instantiation: Out of memory: wasm memory at Worker.worker.onmessage"
I'm not very familiar with WebAssembly, and I wasn't able to find much regarding this by searching online. Would appreciate your help a lot. Thanks!

Feature: Option to specify HTML / CSS template

Hi, thanks for this library which makes life easier for me.

The recording works nicely, but there is no easy way to change the popup recording UI.

Would you consider to add in option to allow user to specific our own HTML / CSS?

Thanks.

missing audio initialization

Uncaught Error: missing audio initialization
const recorder = new vmsg.Recorder({ wasmURL: "https://unpkg.com/[email protected]/vmsg.wasm" });

onClicking start button

await recorder.initAudio()
        await recorder.initWorker()
        recorder.startRecording()

on clickong stop button
recorder.stopRecording().then(res => { console.log("yesRecorded",res) }

here once when i m clicking on the stop button it shows missong audio initialization...

please do help...thanks in advance

Clicking/clipping and bad audio quality in demo.

Recently I've started to notice extremely low quality audio, including clicking/clipping in both the version of vmsg I'm using as well as the online demo. I thought it was my mic but I tried it on multiple computers/phones, and also recorded the audio using Audacity and in audacity it comes back free of any artifacts. Has anyone else noticed this?

Emscripten comparison

If I understand correctly you replace the emscripten JS and runtime with custom code? I'm curious if you have a comparison on the overhead that saves (especially in -O3 or -Os so that metadce is run).

And is it mainly in JS (in which case, comparing with --closure 1 is most interesting) or wasm?

(I ask because maybe this can point us to things we should improve in emscripten.)

ios 11.3 beta , mobile safari - unplayable audio tag

after record , after enter text , tap send button , go to new screen with music note ( tap to get player

tap music note and an audio player comes up with the / slash thru the play icon .. i guess this means that safari cant play the format associated with the audio tag.

probably gonna be the same on 11.2. n due to the wasm regression bug

im not set up real well for ios debug but will attach before /after shots from devtools showing that the problem appears to be that the audio blob was not created successfully ( probably zero length or with just the headers )

It looks like the standard issue on ios 11.2+ where wasm fails.

fwiw - your script.processor will probably implement the following:

      processor.onaudioprocess = function(event) {
        //encoder.encode(getBuffers(event));
        worker.postMessage({ command: 'record', buffers: getBuffers(event) });
      }; 

in other similar libs exhibiting the same bug, note that 'onaudioprocess()' never gets called or is called once and the error stops the recording glomming up the state of the buffers storing / handling the raw audio.

see 'test case' ... near the bottom of [this thread](emscripten-core/emscripten#6042
screenshot from 2018-03-05 10-45-24
screenshot from 2018-03-05 10-49-39

)

FR: support encoding to AAC-LC?

AAC as well supported as mp3 in browers
https://en.wikipedia.org/wiki/HTML5_audio#Supported_audio_coding_formats

ffmpeg native aac encoder
https://trac.ffmpeg.org/wiki/Encode/AAC#NativeFFmpegAACEncoder

Licensing:

Licensee's products that are not end-user products (e.g. components or implementations) are not covered by the license and would require that the party incorporating such a component or implementation into its end-user product obtain a license.

License fees are due on the sale of encoders and/or decoders only. There are no patent license fees due for the distribution of bit-streams encoded in AAC, whether such bit-streams are broadcast, streamed over a network, or provided on physical media.

http://www.via-corp.com/us/en/licensing/aac/faq.html

What do you think? AAC should compress even better than mp3 in lower bitrate, but I'm not sure about the encoder speed. What bitrate does vmsg use? I thought you use CBR but looking at a few samples they range from 48kps to 56kps?

Audio quality issues 48k files

Hello,

I'm using this project on my website to receive recorded messages on my website: https://thenewsjunkie.com/audio/recording/

Many of the messages sound fine but some are poor quality and choppy.

All of the recordings that sound fine are 44.1k and all of the poor quality recordings at 48k. It seems like there's a mismatch between the device output and the recorded file or something.

Does anyone have experience with improving the audio quality in this situation?

NetworkError on Record in Firefox

Both Firefox 62.0a1 Nightly on Windows 10 and Firefox 60.0.1 on Android, when I click [Record] I'm prompted to allow kagami.github.io to use my microphone, then both report Error: "TypeError: NetworkError when attempting to fetch resource." in a vmsg-popup .

On desktop, the developer console has a long error stack

Error: "TypeError: NetworkError when attempting to fetch resource."  at 4fd14265bdd18cc7447ea3ab5f8313f6.js:50:8938 
ฮป onmessage    https://kagami.github.io/vmsg/4fd14265bdd18cc7447ea3ab5f8313f6.js:50:4692
ฮป value        https://kagami.github.io/vmsg/4fd14265bdd18cc7447ea3ab5f8313f6.js:50:4600
...
ฮป require      https://kagami.github.io/vmsg/4fd14265bdd18cc7447ea3ab5f8313f6.js:1:584
ฮป <anonymous>  https://kagami.github.io/vmsg/4fd14265bdd18cc7447ea3ab5f8313f6.js:1:9

Then "Error: no record made"

VMSG Architecture

Hello Kagami,

is VMSG architecture allows to easily add or remove audio encoders as it would be great to follow the trends of audio encoders on the web?

Thanks

PS: I'm also very interested to contribute to real time live streaming audio encoding with vmsg.

Error: getUserMedia is not implemented in this browser on Mac OS 10.15

@Kagami I know there is a closed Issue covering this but Users on Ipads exprerience this bug on both Chrome Mobile iOS 81.0.4044 and Safari 13.0.5.

Is there anything that can be done to prevent: "Error: getUserMedia is not implemented in this browser"? It works fine on other devices and browsers across desktop and mobile.

User Agent:
Mozilla/5.0 (iPad; CPU OS 13_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) CriOS/81.0.4044.62 Mobile/15E148 Safari/604.1

How to recompile vmsg.wasm?

I have downloaded Emscripten SDK, downloaded the latest and activated it.

Not sure what

fix LLVM_ROOT variable of Emscripten config

means.

When make clean all finishes successfully, the generated vmsg.wasm contains the following imports:

Import[2]:
 - func[0] sig=10 <a.a> <- a.a // aka env.exit
 - func[1] sig=1 <a.b> <- a.b // aka env.emscripten_resize_heap

which is not compatible with the imports specified in vmsg.js:

{
         memory: memory,
         pow: Math.pow,
         exit: exit,
         powf: Math.pow,
         exp: Math.exp,
         sqrtf: Math.sqrt,
         cos: Math.cos,
         log: Math.log,
         sin: Math.sin,
         sbrk: sbrk,
};

As a result, trying to run a project with the recompiled vmsg.wasm throws an error TypeError: WebAssembly.instantiate(): Import #0 module="a" error: module is not an object or function
I am guessing that the vmsg.js should be also regenerated using the Emscripten SDK. However, simply using the _vmsg.js in place of vmsg.js does not work - it causes other issues. It seems that vmsg.js has vmsg specific logic, that is not generated in _vmsg.js.

I tried to update the env object in vmsg.js to match the needs of the generated _vmsg.wasm, that is, to:

{
      "exit": _exit,
      "emscripten_resize_heap": _emscripten_resize_heap,
}

However, the implementation of _emscripten_resize_heap is dependent on a lot of generated logic/variables, that I find very hard to take and include in the original vmsg.js file.

Any advice on how to proceed with building this project?

separate section in readme.md for the 3 demos and 1 usage

Hi,

I'm looking into vmsg for the WebAssembly library after researching both Recorder.js (wav only) and Web Audio Recorder (same LAME library but compiled to asm.js).

It would be quite easier to get up and running with vmsg if all 4 demos

  1. https://kagami.github.io/vmsg/
  2. https://github.com/Kagami/vmsg/tree/master/demo
  3. https://github.com/Kagami/vmsg#usage
  4. https://codesandbox.io/s/v67oz43lm7

would be grouped together and documented together in a demos section in readme.md

Error: getUserMedia is not implemented in this browser

Awesome plugin!

Works great on Desktop everywhere. However it appears that there's an issue with "getUserMedia" not being supported on mobile (iOS) Chrome and FireFox.

Any possibility you'd be willing to fix that?

Bitrate

Hello, thank you for this library.

What bitrate is used to encode MP3 audio? Thank you!

Developer instructions - clarification please

Hi.

Re developer instructions, and this line:

  1. Install latest LLVM, Clang and LLD with WebAssembly backend, fix LLVM_ROOT variable of Emscripten config.

For a emscripten rookie, what exactly does the above mean / require ?

Currently, I have Ubuntu 18.04, emscripten 1.22.1, a git clone of your repo, and get these errors when running make. I'm unsure if these errors are related to whatever needs to be done to satisfy 2. above?

... lots of success, then

make[4]: Entering directory '/home/bevand10/Documents/djb/git/vmsg/lame-svn/lame/libmp3lame/vector'
/bin/bash ../../libtool  --tag=CC   --mode=compile /usr/share/emscripten/emcc -DHAVE_CONFIG_H  -I. -I../.. -I../../include -I. -I../../libmp3lame -I../../mpglib -I../..    -DNDEBUG -Oz -MT xmm_quantize_sub.lo -MD -MP -MF .deps/xmm_quantize_sub.Tpo -c -o xmm_quantize_sub.lo xmm_quantize_sub.c
libtool: compile:  /usr/share/emscripten/emcc -DHAVE_CONFIG_H -I. -I../.. -I../../include -I. -I../../libmp3lame -I../../mpglib -I../.. -DNDEBUG -Oz -MT xmm_quantize_sub.lo -MD -MP -MF .deps/xmm_quantize_sub.Tpo -c xmm_quantize_sub.c  -fPIC -DPIC -o .libs/xmm_quantize_sub.o
xmm_quantize_sub.c:62:1: warning: unknown attribute 'force_align_arg_pointer' ignored [-Wunknown-attributes]
SSE_FUNCTION void
^
xmm_quantize_sub.c:56:37: note: expanded from macro 'SSE_FUNCTION'
#define SSE_FUNCTION __attribute__((force_align_arg_pointer))
                                    ^
xmm_quantize_sub.c:72:34: error: implicit declaration of function '_mm_loadu_ps' is invalid in C99 [-Werror,-Wimplicit-function-declaration]
    const __m128 vec_fabs_mask = _mm_loadu_ps(&fabs_mask._float[0]);
                                 ^
xmm_quantize_sub.c:72:34: note: did you mean '_mm_add_ps'?
/usr/share/emscripten/system/include/emscripten/xmmintrin.h:36:1: note: '_mm_add_ps' declared here
_mm_add_ps(__m128 a, __m128 b)
^
xmm_quantize_sub.c:72:18: error: initializing 'const __m128' (aka 'const float32x4') with an expression of incompatible type 'int'
    const __m128 vec_fabs_mask = _mm_loadu_ps(&fabs_mask._float[0]);
                 ^               ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
xmm_quantize_sub.c:77:5: error: implicit declaration of function '_mm_prefetch' is invalid in C99 [-Werror,-Wimplicit-function-declaration]
    _mm_prefetch((char *) cod_info->xr, _MM_HINT_T0);
    ^
xmm_quantize_sub.c:77:41: error: use of undeclared identifier '_MM_HINT_T0'
    _mm_prefetch((char *) cod_info->xr, _MM_HINT_T0);
                                        ^
xmm_quantize_sub.c:78:34: error: use of undeclared identifier '_MM_HINT_T0'
    _mm_prefetch((char *) xrpow, _MM_HINT_T0);
                                 ^
xmm_quantize_sub.c:80:27: error: implicit declaration of function '_mm_set_ps1' is invalid in C99 [-Werror,-Wimplicit-function-declaration]
    vec_xrpow_max._m128 = _mm_set_ps1(0);
                          ^
xmm_quantize_sub.c:80:27: note: did you mean '_mm_set_ps'?
/usr/share/emscripten/system/include/emscripten/xmmintrin.h:6:1: note: '_mm_set_ps' declared here
_mm_set_ps(float z, float y, float x, float w)
^
xmm_quantize_sub.c:80:25: error: assigning to '__m128' (aka 'float32x4') from incompatible type 'int'
    vec_xrpow_max._m128 = _mm_set_ps1(0);
                        ^ ~~~~~~~~~~~~~~
xmm_quantize_sub.c:81:19: error: assigning to '__m128' (aka 'float32x4') from incompatible type 'int'
    vec_sum._m128 = _mm_set_ps1(0);
                  ^ ~~~~~~~~~~~~~~
xmm_quantize_sub.c:84:23: error: assigning to '__m128' (aka 'float32x4') from incompatible type 'int'
        vec_tmp._m128 = _mm_loadu_ps(&(cod_info->xr[i])); /* load */
                      ^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
xmm_quantize_sub.c:89:9: error: implicit declaration of function '_mm_storeu_ps' is invalid in C99 [-Werror,-Wimplicit-function-declaration]
        _mm_storeu_ps(&(xrpow[i]), vec_tmp._m128); /* store into xrpow[] */
        ^
xmm_quantize_sub.c:89:9: note: did you mean '_mm_store_ps'?
/usr/share/emscripten/system/include/emscripten/xmmintrin.h:24:1: note: '_mm_store_ps' declared here
_mm_store_ps(float *p, __m128 a)
^
xmm_quantize_sub.c:91:19: error: assigning to '__m128' (aka 'float32x4') from incompatible type 'int'
    vec_tmp._m128 = _mm_set_ps1(0);
                  ^ ~~~~~~~~~~~~~~
xmm_quantize_sub.c:123:1: warning: unknown attribute 'force_align_arg_pointer' ignored [-Wunknown-attributes]
SSE_FUNCTION static void
^
xmm_quantize_sub.c:56:37: note: expanded from macro 'SSE_FUNCTION'
#define SSE_FUNCTION __attribute__((force_align_arg_pointer))
                                    ^
xmm_quantize_sub.c:135:1: warning: unknown attribute 'force_align_arg_pointer' ignored [-Wunknown-attributes]
SSE_FUNCTION void
^
xmm_quantize_sub.c:56:37: note: expanded from macro 'SSE_FUNCTION'
#define SSE_FUNCTION __attribute__((force_align_arg_pointer))
                                    ^
xmm_quantize_sub.c:189:20: error: implicit declaration of function '_mm_set_ps1' is invalid in C99 [-Werror,-Wimplicit-function-declaration]
            v_c1 = _mm_set_ps1(c1);
                   ^
xmm_quantize_sub.c:189:18: error: assigning to '__m128' (aka 'float32x4') from incompatible type 'int'
            v_c1 = _mm_set_ps1(c1);
                 ^ ~~~~~~~~~~~~~~~
xmm_quantize_sub.c:190:18: error: assigning to '__m128' (aka 'float32x4') from incompatible type 'int'
            v_s1 = _mm_set_ps1(s1);
                 ^ ~~~~~~~~~~~~~~~
xmm_quantize_sub.c:191:18: error: assigning to '__m128' (aka 'float32x4') from incompatible type 'int'
            v_c2 = _mm_set_ps1(c2);
                 ^ ~~~~~~~~~~~~~~~
xmm_quantize_sub.c:192:18: error: assigning to '__m128' (aka 'float32x4') from incompatible type 'int'
            v_s2 = _mm_set_ps1(s2);
                 ^ ~~~~~~~~~~~~~~~
xmm_quantize_sub.c:208:21: error: implicit declaration of function '_mm_setr_ps' is invalid in C99 [-Werror,-Wimplicit-function-declaration]
                q = _mm_setr_ps(fi[k1], fi[k3], gi[k1], gi[k3]); /* Q := {fi_k1,fi_k3,gi_k1,gi_k3}*/
                    ^
xmm_quantize_sub.c:208:19: error: assigning to '__m128' (aka 'float32x4') from incompatible type 'int'
                q = _mm_setr_ps(fi[k1], fi[k3], gi[k1], gi[k3]); /* Q := {fi_k1,fi_k3,gi_k1,gi_k3}*/
                  ^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
xmm_quantize_sub.c:209:32: error: passing 'int' to parameter of incompatible type '__m128' (aka 'float32x4')
                p = _mm_mul_ps(_mm_set_ps1(s2), q);              /* P := s2 * Q */
                               ^~~~~~~~~~~~~~~
/usr/share/emscripten/system/include/emscripten/xmmintrin.h:48:19: note: passing argument to parameter 'a' here
_mm_mul_ps(__m128 a, __m128 b)
                  ^
fatal error: too many errors emitted, stopping now [-ferror-limit=]
3 warnings and 20 errors generated.
ERROR    root: compiler frontend failed to generate LLVM bitcode, halting
Makefile:423: recipe for target 'xmm_quantize_sub.lo' failed

Changing VBR methods to CBR throws error

Hello,
So I have been using another library that utilises vmsg for audio recording and since I have some issues with VBR audio file I needed a way to record audio mp3 in CBR, thankfully vmsg has those options.
What I did was fork this library and started development in my system and after modifying the VBR methods such as lame_set_VBR in vmsg.c and then using make to build the wasm file for it. But after doing so it's throwing errors which I can't see anywhere even tried logging and it never records.
Am I doing something wrong? I am new to this whole emscripten, clang and wasm stuff so won't be able to explain better.

Streaming encoder

First of all, thanks for this great library.

I have a question: is there a way to do encoding of a specific audio buffer and only get that back, and not the whole recording?
For example, sending a Float32Array, vmsg encodes it and then sends it back.
Right now I think during a recording, everything is held in memory and returned when calling vmsg_flush().
This would be useful for longer recordings where you want to encode something and maybe upload it and not keep it in memory.

I've tried to do something similar, by calling vmsg_init, vmsg_encode and then vmsg_flush, inside the data event listener for the worker. I don't think this is the right way to do it.

  case "data":

    if (!vmsg_init(msg.rate)) return postMessage({type: "error", data: "vmsg_init"});

    if (!vmsg_encode(msg.data)) return postMessage({type: "error", data: "vmsg_encode"});

    const blob = vmsg_flush();
    if (!blob) {
      return postMessage({type: "error", data: "vmsg_flush"});
    }

    postMessage({
      type: "blob",
      data: blob
    });
    
    break;

Is there a way to do that? A change would also need to be made inside vmsg.c, right?
Thanks

Blob comes back null after stop recording React

Hi, thank you for your work on vmsg. I am trying to implement a functional component version of the React demo from the README. Everything seems to work, and it's almost the same code as the example, but the blob comes back null. I am using vmsg 0.3.0, and I traced the code in vmsg.stopRecording and it seems though the worker is null even though I'm calling initWorker(). I'm probably messing up something basic with async/await or promises but I've tried to track it down with no luck. Thank you.

import React, {useState} from 'react'
import PropTypes from 'prop-types'
import classNames from 'classnames'

import vmsg from 'vmsg'


function Recorder() {
    const [recordings, setRecordings] = useState([])
    const [isRecording, setIsRecording] = useState(false)
    const [isLoading, setIsLoading] = useState(false)
    const [isWorkerInitialized, setIsWorkerInitalized] = useState(false)
    const recorder = new vmsg.Recorder({
        wasmURL: "https://unpkg.com/[email protected]/vmsg.wasm"
      });
    const handleRecording = async() => {
        setIsLoading(true)
        if (isRecording){
            console.log("Finish recording")
            let blob = await recorder.stopRecording();

            console.log("Blob", blob)

            setIsRecording(false)
            setIsLoading(false)
            setRecordings([URL.createObjectURL(blob)])
        }
        else{
            try {
                if (!isWorkerInitialized){
                    await recorder.initAudio();
                    await recorder.initWorker();
                    setIsWorkerInitalized(true)
                }
                recorder.startRecording();
                setIsRecording(true)
                setIsLoading(false)
            } catch (e) {
                console.error(e);
                setIsLoading(false)
                }
        }

    }
    return (
        <>
            <button disabled={isLoading} onClick={handleRecording}>
                {isRecording ? "Stop" : "Record"}
            </button>
            <ul style={{ listStyle: "none", padding: 0 }}>
                {recordings.map(url => (
                <li key={url}>
                    <audio src={url} controls />
                </li>
                ))}
            </ul>
        </>
    )

    }

export default Recorder

Some issue with codesandbox example

is there a way to lose the weird form that opens when you want to record? I'd like to implement my own interface. I just need to be able to record audio from a microphone is a smal file format, readable by ios.

Cannot read property 'vmsg_flush' of null

Hi,

I get this error randomly.. often on short recordings.

Uncaught TypeError: Cannot read property 'vmsg_flush' of null
    at vmsg_flush (blob:https://localhost:3000/d90fc477-de7d-45da-a372-6707d7cb41bf:77)
    at onmessage (blob:https://localhost:3000/d90fc477-de7d-45da-a372-6707d7cb41bf:166)
vmsg_flush @ blob:https://localhost:3000/d90fc477-de7d-45da-a372-6707d7cb41bf:77
onmessage @ blob:https://localhost:3000/d90fc477-de7d-45da-a372-6707d7cb41bf:166

Occasional garbled audio recording

Hello! Vmsg is awesome - we're using it in a production React web app. The vast majority of the time it works flawlessly, but we've had a few instances where the recorded audio file will be a little garbled (almost like it's being sped up or slowed down). We are not setting the pitch option to anything, so its default value of 0 should be active.

This seems to happen randomly - for a given user most recordings are fine, and then once in a while one is messed up. I can upload an example if it helps.

Any ideas on what might cause this?

Demo broken on Firefox for Android

Hi there,

I just tried our demo in my mobile firefox (latest) on android 9 and I get

NotAllowedError: The request is not allowed by the user agent or the platform in the current context.

There's also no mic permission request dialog.

Any idea whats wrong?

Thanks you ๐Ÿ‘

Publish new version with exported Recorder

Hi there, thanks for the great work!
I'm looking into using this for Common Voice. Atm we're using MediaRecorder which (as you well know) doesn't let us support Safari & Edge. I investigated using a lame encoder written in JS but that didn't seem to work for iOS. So my next thought was to go full WASM and fortunately I found that somebody already did the heavy lifting. Awesome! Also can confirm that it works with iOS 11.3 (discussion in #3 was very helpful) & Edge.
I was wondering if you could publish the most recent version to NPM, so that we can use the recently extracted Recorder?

ios safari reclaims the scriptprocessor - audio context init needs to happen under start button

i think you also have the bug mentioned here and resolved by gerson rosoles sample # 3

i looked at your code and noticed that the init of the audiocontext is NOT tied to a UI event as mentioned in the above linked thread. This is also a cause of issues on ios 11.2+

i think the thread and gerson's sample 3 show the required rearraingment required in the code.

your init needs to be under a UI event like the start button otherwise as explained ios reclaims it

This will also cause symptoms similar to those described in #3

TypeError: Failed to execute 'compile' on 'WebAssembly': HTTP status code is not ok

Hello!

I tried to run

this.rec.initAudio().then(()=> { this.rec.initWorker().then(()=> { this.rec.startRecording(); }); });

and got:

Error: TypeError: Failed to execute 'compile' on 'WebAssembly': HTTP status code is not ok
at Worker.worker.onmessage [as __zone_symbol__ON_PROPERTYmessage] (vmsg.js:249)
at Worker.wrapFn (zone-evergreen.js:1191)
at ZoneDelegate.invokeTask (zone-evergreen.js:391)
at Object.onInvokeTask (core.js:34182)
at ZoneDelegate.invokeTask (zone-evergreen.js:390)
at Zone.runTask (zone-evergreen.js:168)
at ZoneTask.invokeTask [as invoke] (zone-evergreen.js:465)
at invokeTask (zone-evergreen.js:1603)
at Worker.globalZoneAwareCallback (zone-evergreen.js:1629)
at resolvePromise (zone-evergreen.js:797)
at resolvePromise (zone-evergreen.js:754)
at zone-evergreen.js:858
at ZoneDelegate.invokeTask (zone-evergreen.js:391)
at Object.onInvokeTask (core.js:34182)
at ZoneDelegate.invokeTask (zone-evergreen.js:390)
at Zone.runTask (zone-evergreen.js:168)
at drainMicroTaskQueue (zone-evergreen.js:559)
at ZoneTask.invokeTask [as invoke] (zone-evergreen.js:469)
at invokeTask (zone-evergreen.js:1603)

Any idea what might be going on?

Possible to get levels?

Hi,

I'm trying to get the microphone levels to show in the UI while this is recording.

navigator.mediaDevices.getUserMedia({ audio: true })

isn't receiving the stream while VMSG is running, I assume because VMSG is using the microphone, is it possible to get the steam levels using this?

embed vmsg.wasm directly

It'd be great if vmsg.wasm was embedded directly via an ArrayBuffer or as a compile-time step.

Having the end user reference the URL of vmsg.wasm is pretty clunky, though I understand why it's setup that way at the moment.

[ERROR] import in MeteorJS

when inporting es6 version we get an error untill we import es5 version like that
import vmsg from 'vmsg/vmsg.es5'

Fix initial dynamicTop

Reserved area at the top of the memory is slightly more than TOTAL_STACK, see Emscripten's JS wrapper.

Encoding in wav format

Hi Kagami,

First of all, thanks for the package. It's hard to record on iOS, but it's possible with the library.

My projects employ a voice recognition API but that requires a .wav format audio data, which is not the default encoded format from vmsg.

I know the core of the encoding is in defined in the C layer, but I don't have any experience with C.
I found a relevant function vmsg_encode which sounds like the place to define the encoding, but I have no idea how could I modify on it.. Would appreciate your help if you add an audio encoding format for .wav apart from the default .mp3.

Tag new release?

Hi Kagami, would you mind tagging a new release? v0.3.6 is almost two years old at this point and it would be great if the recent dependency changes and accessibility fixes from #47 were available to be deployed easily through package-managers.

As background, I've released a Drupal audiorecorder module that utilizes vmsg and now that others have started using it too, the need to apply patches to vmsg makes the installation process more difficult than it needs to be. Thanks in advance!

memory access out of bounds

When i try to record more than 8min i receive this error. (in google chrome)
anybody know's how to remedy ?

Uncaught RuntimeError: memory access out of bounds
at wasm-function[11]:24
at wasm-function[254]:86
at wasm-function[241]:34
at vmsg_flush (blob:)
at onmessage (blob:)

thank you

Non React demo

All 3 demos are React based. Would love to see a non React demo or better documentation around using vmsg in a plain HTML/JS app.

Demo page error in Chrome

Hello. I have opened demo page, allow microphone usage and have this popup error:

Error: CompileError: AsyncCompile: Wasm decoding failed: 
expected magic word 00 61 73 6d, found 3c 21 44 4f @+0

Browser

Chrome Version 64.0.3282.140 (Official Build) (64-bit)

OS

Ubuntu 14.04

Console error:

image

Maybe helpful...

Poor quality on iOS

The recordings on the demo are pristine in their quality but not so in mine.

Is there some discrepancy between the code here and the one that's served by npm or in the demo?

Thanks

Can I pause recording?

Hello, I LOVE this library.

Quick question (if you have the time). How would I go about pausing a voice message?

Do I need to add a new method to the WASM code?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.