# build using Emscriptengit clone https://github.com/ggerganov/whisper.cpp
cd whisper.cpp
mkdir build-em &&cd build-em
emcmake cmake ..make-j# copy the produced page to your HTTP pathcp bin/whisper.wasm/* /path/to/html/
cp bin/libmain.worker.js /path/to/html/
$ emcmake cmake ..
configure: cmake .. -DCMAKE_TOOLCHAIN_FILE=/home/pdd/Downloads/emsdk/upstream/emscripten/cmake/Modules/Platform/Emscripten.cmake -DCMAKE_CROSSCOMPILING_EMULATOR=/home/pdd/Downloads/emsdk/node/16.20.0_64bit/bin/node
-- Found Git: /usr/bin/git (found version "2.34.1")
-- Performing Test CMAKE_HAVE_LIBC_PTHREAD
-- Performing Test CMAKE_HAVE_LIBC_PTHREAD - Success
-- Found Threads: TRUE
-- CMAKE_SYSTEM_PROCESSOR: x86
-- x86 detected
-- Embedding WASM inside whisper.js
-- SDL2_INCLUDE_DIRS = /home/pdd/Downloads/emsdk/upstream/emscripten/cache/sysroot/include/SDL2
-- SDL2_LIBRARIES = -sUSE_SDL=2
-- Embedding WASM inside main.js
-- Embedding WASM inside stream.js
-- Embedding WASM inside command.js
-- Embedding WASM inside talk.js
-- Embedding WASM inside bench.js
-- Configuring done
-- Generating done
-- Build files have been written to: /home/pdd/le/whisper.cpp-1.5.0/build-em
$ make -j
[ 20%] Building C object CMakeFiles/whisper.dir/ggml-alloc.c.o
[ 20%] Building C object CMakeFiles/whisper.dir/ggml-backend.c.o
[ 20%] Building C object CMakeFiles/whisper.dir/ggml.c.o
[ 20%] Building CXX object examples/CMakeFiles/common-sdl.dir/common-sdl.cpp.o
[ 20%] Building C object CMakeFiles/whisper.dir/ggml-quants.c.o
[ 24%] Building CXX object CMakeFiles/whisper.dir/whisper.cpp.o
In file included from /home/pdd/le/whisper.cpp-1.5.0/examples/common-sdl.cpp:1:
In file included from /home/pdd/le/whisper.cpp-1.5.0/examples/common-sdl.h:3:
/home/pdd/Downloads/emsdk/upstream/emscripten/cache/sysroot/include/fakesdl/SDL.h:1:2: error: "To use the emscripten port of SDL use -sUSE_SDL or -sUSE_SDL=2"
1 | #error "To use the emscripten port of SDL use -sUSE_SDL or -sUSE_SDL=2"
以上错误的原因是我在文章“webassembly003 whisper.cpp的main项目-1https://blog.youkuaiyun.com/ResumeProject/article/details/135584313”中想使用SDL,所以设置了:
set(WHISPER_SDL2 ON)#option(WHISPER_SDL2 "whisper: support for libSDL2" OFF)
现在改回来option(WHISPER_SDL2 "whisper: support for libSDL2" OFF)或者直接set(WHISPER_SDL2 OFF)即可
$ make -j
-- CMAKE_SYSTEM_PROCESSOR: x86
-- x86 detected
-- Embedding WASM inside whisper.js
-- Embedding WASM inside main.js
-- Embedding WASM inside stream.js
-- Embedding WASM inside command.js
-- Embedding WASM inside talk.js
-- Embedding WASM inside bench.js
-- Configuring done
-- Generating done
-- Build files have been written to: /home/pdd/le/whisper.cpp-1.5.0/build-em
Consolidate compiler generated dependencies of target whisper
[ 26%] Built target whisper
[ 43%] Building CXX object examples/stream.wasm/CMakeFiles/libstream.dir/emscripten.cpp.o
[ 43%] Building CXX object bindings/javascript/CMakeFiles/libwhisper.dir/emscripten.cpp.o
[ 43%] Building CXX object examples/bench.wasm/CMakeFiles/libbench.dir/emscripten.cpp.o
[ 43%] Building CXX object examples/CMakeFiles/common.dir/common.cpp.o
[ 47%] Building CXX object examples/whisper.wasm/CMakeFiles/libmain.dir/emscripten.cpp.o
[ 52%] Building CXX object examples/CMakeFiles/common.dir/grammar-parser.cpp.o
[ 56%] Building CXX object examples/CMakeFiles/common.dir/common-ggml.cpp.o
/home/pdd/le/whisper.cpp-1.5.0/examples/whisper.wasm/emscripten.cpp:105:52: warning: initialized lambda captures are a C++14 extension [-Wc++14-extensions]
105 | g_worker = std::thread([index, params, pcmf32 = std::move(pcmf32)]() {
| ^
/home/pdd/le/whisper.cpp-1.5.0/examples/stream.wasm/emscripten.cpp:109:35: warning: unused variable 't0' [-Wunused-variable]
109 | const int64_t t0 = whisper_full_get_segment_t0(ctx, i);
| ^~
/home/pdd/le/whisper.cpp-1.5.0/examples/stream.wasm/emscripten.cpp:110:35: warning: unused variable 't1' [-Wunused-variable]
110 | const int64_t t1 = whisper_full_get_segment_t1(ctx, i);
| ^~
/home/pdd/le/whisper.cpp-1.5.0/examples/stream.wasm/emscripten.cpp:155:74: warning: unused parameter 'index' [-Wunused-parameter]
155 | emscripten::function("free", emscripten::optional_override([](size_t index) {
| ^
[ 60%] Linking CXX executable ../../bin/libbench.js
1 warning generated.
[ 65%] Linking CXX executable ../../bin/libmain.js
[ 69%] Linking CXX executable ../../bin/libwhisper.js
cache:INFO: generating system asset: symbol_lists/86ce62757fe763e6970094b2fb6256b6a9303462.json... (this will be cached in "/home/pdd/Downloads/emsdk/upstream/emscripten/cache/symbol_lists/86ce62757fe763e6970094b2fb6256b6a9303462.json" for subsequent builds)
3 warnings generated.
[ 73%] Linking CXX executable ../../bin/libstream.js
em++: warning: -pthread + ALLOW_MEMORY_GROWTH may run non-wasm code slowly, see https://github.com/WebAssembly/design/issues/1271 [-Wpthreads-mem-growth]
cache:INFO: - ok
cache:INFO: generating system asset: symbol_lists/48222c973266f0adfbab77d6354fb223bdb90ef2.json... (this will be cached in "/home/pdd/Downloads/emsdk/upstream/emscripten/cache/symbol_lists/48222c973266f0adfbab77d6354fb223bdb90ef2.json" for subsequent builds)
cache:INFO: - ok
warning: deprecated item in EXPORTED_RUNTIME_METHODS: print use out instead.
warning: deprecated item in EXPORTED_RUNTIME_METHODS: printErr use err instead.
em++: warning: warnings in JS library compilation [-Wjs-compiler]
warning: deprecated item in EXPORTED_RUNTIME_METHODS: print use out instead.
warning: deprecated item in EXPORTED_RUNTIME_METHODS: printErr use err instead.
em++: warning: warnings in JS library compilation [-Wjs-compiler]
warning: deprecated item in EXPORTED_RUNTIME_METHODS: print use out instead.
warning: deprecated item in EXPORTED_RUNTIME_METHODS: printErr use err instead.
em++: warning: warnings in JS library compilation [-Wjs-compiler]
[ 78%] Linking CXX static library libcommon.a
[ 78%] Built target common
[ 82%] Building CXX object examples/command.wasm/CMakeFiles/libcommand.dir/emscripten.cpp.o
[ 86%] Building CXX object examples/talk.wasm/CMakeFiles/libtalk.dir/emscripten.cpp.o
[ 91%] Building CXX object examples/talk.wasm/CMakeFiles/libtalk.dir/gpt-2.cpp.o
/home/pdd/le/whisper.cpp-1.5.0/examples/talk.wasm/gpt-2.cpp:130:31: warning: cast from 'const char *' to 'char *' drops const qualifier [-Wcast-qual]
130 | fin.read((char *) word.data(), len);
| ^
/home/pdd/le/whisper.cpp-1.5.0/examples/command.wasm/emscripten.cpp:266:74: warning: unused parameter 'index' [-Wunused-parameter]
266 | emscripten::function("free", emscripten::optional_override([](size_t index) {
| ^
/home/pdd/le/whisper.cpp-1.5.0/examples/talk.wasm/emscripten.cpp:294:74: warning: unused parameter 'index' [-Wunused-parameter]
294 | emscripten::function("free", emscripten::optional_override([](size_t index) {
| ^
/home/pdd/le/whisper.cpp-1.5.0/examples/talk.wasm/emscripten.cpp:327:81: warning: unused parameter 'index' [-Wunused-parameter]
327 | emscripten::function("force_speak", emscripten::optional_override([](size_t index) {
| ^
1 warning generated.
[ 95%] Linking CXX executable ../../bin/libcommand.js
1 warning generated.
warning: deprecated item in EXPORTED_RUNTIME_METHODS: print use out instead.
warning: deprecated item in EXPORTED_RUNTIME_METHODS: printErr use err instead.
em++: warning: warnings in JS library compilation [-Wjs-compiler]
2 warnings generated.
[100%] Linking CXX executable ../../bin/libtalk.js
cache:INFO: generating system asset: symbol_lists/861182d6f58950bacb50ecea0d73a4f4991e3033.json... (this will be cached in "/home/pdd/Downloads/emsdk/upstream/emscripten/cache/symbol_lists/861182d6f58950bacb50ecea0d73a4f4991e3033.json" for subsequent builds)
cache:INFO: - ok
[100%] Built target libbench
warning: deprecated item in EXPORTED_RUNTIME_METHODS: print use out instead.
warning: deprecated item in EXPORTED_RUNTIME_METHODS: printErr use err instead.
em++: warning: warnings in JS library compilation [-Wjs-compiler]
[100%] Built target libmain
[100%] Built target libstream
[100%] Built target libwhisper
[100%] Built target libcommand
[100%] Built target libtalk
$ tree ./bin
./bin
├── bench.wasm
│ ├── bench.js
│ ├── helpers.js
│ └── index.html
├── command.wasm
│ ├── command.js
│ ├── helpers.js
│ └── index.html
├── libbench.js
├── libbench.worker.js
├── libcommand.js
├── libcommand.worker.js
├── libmain.js
├── libmain.worker.js
├── libstream.js
├── libstream.worker.js
├── libtalk.js
├── libtalk.worker.js
├── libwhisper.js
├── libwhisper.worker.js
├── stream.wasm
│ ├── helpers.js
│ ├── index.html
│ └── stream.js
├── talk.wasm
│ ├── helpers.js
│ ├── index.html
│ └── talk.js
└── whisper.wasm
├── helpers.js
├── index.html
└── main.js
5 directories, 27 files
<body><divid="main-container"><b>Minimal <ahref="https://github.com/ggerganov/whisper.cpp">whisper.cpp</a> example running fully in the browser</b><br><br>
Usage instructions:<br><ul><li>Load a ggml model file (you can obtain one from <ahref="https://ggml.ggerganov.com/">here</a>, recommended: <b>tiny</b> or <b>base</b>)</li><li>Select audio file to transcribe or record audio from the microphone (sample: <ahref="https://whisper.ggerganov.com/jfk.wav">jfk.wav</a>)</li><li>Click on the "Transcribe" button to start the transcription</li></ul>
Note that the computation is quite heavy and may take a few seconds to complete.<br>
The transcription results will be displayed in the text area below.<br><br><b>Important:</b><ul><li>your browser must support WASM SIMD instructions for this to work</li><li>Firefox cannot load files larger than 256 MB - use Chrome instead</li></ul><b>More examples:</b><ahref="https://whisper.ggerganov.com/">main</a> |
<ahref="https://whisper.ggerganov.com/bench">bench</a> |
<ahref="https://whisper.ggerganov.com/stream">stream</a> |
<ahref="https://whisper.ggerganov.com/command">command</a> |
<ahref="https://whisper.ggerganov.com/talk">talk</a> |
<hr><divid="model">
Whisper models: <spanid="model-whisper-status"></span><br><br><buttonid="fetch-whisper-tiny-en"onclick="loadWhisper('tiny.en')">tiny.en (75 MB)</button><buttonid="fetch-whisper-tiny"onclick="loadWhisper('tiny')">tiny (75 MB)</button><buttonid="fetch-whisper-base-en"onclick="loadWhisper('base.en')">base.en (142 MB)</button><buttonid="fetch-whisper-base"onclick="loadWhisper('base')">base (142 MB)</button><buttonid="fetch-whisper-small-en"onclick="loadWhisper('small.en')">small.en (466 MB)</button><buttonid="fetch-whisper-small"onclick="loadWhisper('small')">small (466 MB)</button><inputtype="file"id="whisper-file"name="file"onchange="loadFile(event,'whisper.bin')"/><br><br>
Quantized models:<br><br><buttonid="fetch-whisper-tiny-en-q5_1"onclick="loadWhisper('tiny-en-q5_1')">tiny.en (Q5_1, 31 MB)</button><buttonid="fetch-whisper-tiny-q5_1"onclick="loadWhisper('tiny-q5_1')">tiny (Q5_1, 31 MB)</button><buttonid="fetch-whisper-base-en-q5_1"onclick="loadWhisper('base-en-q5_1')">base.en (Q5_1, 57 MB)</button><buttonid="fetch-whisper-base-q5_1"onclick="loadWhisper('base-q5_1')">base (Q5_1, 57 MB)</button><buttonid="fetch-whisper-small-en-q5_1"onclick="loadWhisper('small-en-q5_1')">small.en (Q5_1, 182 MB)</button><buttonid="fetch-whisper-small-q5_1"onclick="loadWhisper('small-q5_1')">small (Q5_1, 182 MB)</button><br><buttonid="fetch-whisper-medium-en-q5_0"onclick="loadWhisper('medium-en-q5_0')">medium.en (Q5_0, 515 MB)</button><buttonid="fetch-whisper-medium-q5_0"onclick="loadWhisper('medium-q5_0')">medium (Q5_0, 515 MB)</button><buttonid="fetch-whisper-large-q5_0"onclick="loadWhisper('large-q5_0')">large (Q5_0, 1030 MB)</button><spanid="fetch-whisper-progress"></span></div><br><!-- radio button to select between file upload or microphone --><divid="input">
Input:
<inputtype="radio"id="file"name="input"value="file"checked="checked"onchange="changeInput('file')"/><labelfor="file">File</label><inputtype="radio"id="mic"name="input"value="mic"onchange="changeInput('mic')"/><labelfor="mic">Microphone</label></div><br><divid="input_file">
Audio file:
<inputtype="file"id="file"name="file"onchange="loadAudio(event)"/></div><divid="input_mic"style="display: none;">
Microphone:
<buttonid="start"onclick="startRecording()">Start</button><buttonid="stop"onclick="stopRecording()"disabled>Stop</button><!-- progress bar to show recording progress --><br><br><divid="progress"style="display: none;"><divid="progress-bar"style="width: 0%;height: 10px;background-color: #4CAF50;"></div><divid="progress-text">0%</div></div></div><audiocontrols="controls"id="audio"loophidden>
Your browser does not support the <audio> tag.
<sourceid="source"src=""type="audio/wav"/></audio><hr><br><table><tr><td>
Language:
<selectid="language"name="language"><optionvalue="en">English</option>
……
<optionvalue="yi">Yiddish</option></select></td><!-- Slider to select number of threads between 1 and 16 --><td>
Threads:
<inputtype="range"id="threads"name="threads"min="1"max="16"value="8"onchange="changeThreads(this.value)"/><spanid="threads-value">8</span></td><td><buttononclick="onProcess(false);">Transcribe</button></td><td><buttononclick="onProcess(true);">Translate</button></td></tr></table><br><!-- textarea with height filling the rest of the page --><textareaid="output"rows="20"></textarea><br><br><divclass="cell-version"><span>
|
Build time: <spanclass="nav-link">@GIT_DATE@</span> |
Commit hash: <aclass="nav-link"href="https://github.com/ggerganov/whisper.cpp/commit/@GIT_SHA1@">@GIT_SHA1@</a> |
Commit subject: <spanclass="nav-link">@GIT_COMMIT_SUBJECT@</span> |
<aclass="nav-link"href="https://github.com/ggerganov/whisper.cpp/tree/master/examples/whisper.wasm">Source Code</a> |
</span></div></div>
// https://github.com/ggerganov/whisper.cpp/tree/master/examples/whisper.wasm
# build using Emscripten
git clone https://github.com/ggerganov/whisper.cpp
cd whisper.cpp
mkdir build-em && cd build-em
emcmake cmake ..
make -j
# copy the produced page to your HTTP path
cp bin/whisper.wasm/* /path/to/html/
cp bin/libmain.worker.js /path/to/html/