WebAssembly C++开发环境搭建
WebAssembly 开发环境搭建
简介
WebAssembly 是一种新的编码方式,可以在现代的网络浏览器中运行 - 它是一种低级的类汇编语言,具有紧凑的二进制格式,可以接近原生的性能运行,并为诸如C/C++等语言提供一个编译目标,以便它们可以在 Web 上运行。它也被设计为可以与 JavaScript 共存,允许两者一起工作。
简而言之,对于网络平台而言,WebAssembly 具有巨大的意义——它提供了一条途径,以使得以各种语言编写的代码都可以以接近原生的速度在 Web 中运行。在这种情况下,以前无法以此方式运行的客户端软件都将可以运行在 Web 中。
WebAssembly 被设计为可以和 JavaScript 一起协同工作——通过使用 WebAssembly 的 JavaScript API,你可以把 WebAssembly 模块加载到一个 JavaScript 应用中并且在两者之间共享功能。这允许你在同一个应用中利用 WebAssembly 的性能和威力以及 JavaScript 的表达力和灵活性,即使你可能并不知道如何编写 WebAssembly 代码。
本文展示了将 FFmpeg 应用到 WebAssembly 的例子。
编译环境
https://hub.docker.com/r/emscripten/emsdk/tags
拉取远程镜像
docker pull emscripten/emsdk:2.0.24
启动容器
映射自己的目录
docker run -d -it --name mediawasm -v d:/.../wasmff:/code emscripten/emsdk:2.0.24 /bin/bash
编译
编译脚本
#!/bin/bash
#set -eo pipefail
WORKPATH=$(cd $(dirname $0); pwd)
DEMO_PATH=$WORKPATH/demo
echo "WORKPATH"=$WORKPATH
rm -rf ${WORKPATH}/demo/mp4encoder.js ${WORKPATH}/demo/mp4encoder.wasm
FFMPEG_ST=yes
EMSDK=/emsdk
THIRD_DIR=${WORKPATH}/lib/third/build
# 生成调试文件
DEBUG="-g -fno-inline -gseparate-dwarf=/code/demo/temp.debug.wasm -s SEPARATE_DWARF_URL=http://localhost:5000/temp.debug.wasm"
#--closure 压缩胶水代码,有可能会造成变量重复定义。生产发布可设为1
OPTIM_FLAGS="-O1 $DEBUG --closure 0"
if [[ "$FFMPEG_ST" != "yes" ]]; then
EXTRA_FLAGS=(
-pthread
-s USE_PTHREADS=1 # enable pthreads support
-s PROXY_TO_PTHREAD=1 # detach main() from browser/UI main thread
-o ${DEMO_PATH}/mp4encoder.js
)
else
EXTRA_FLAGS=(
-o ${DEMO_PATH}/mp4encoder.js
)
fi
FLAGS=(
-I$WORKPATH/lib/ffmpeg-emcc/include -L$WORKPATH/lib/ffmpeg-emcc/lib -I$THIRD_DIR/include -L$THIRD_DIR/lib
-Wno-deprecated-declarations -Wno-pointer-sign -Wno-implicit-int-float-conversion -Wno-switch -Wno-parentheses -Qunused-arguments
-lavdevice -lavfilter -lavformat -lavcodec -lswresample -lswscale -lavutil -lpostproc
-lm -lharfbuzz -lfribidi -lass -lx264 -lx265 -lvpx -lwavpack -lmp3lame -lfdk-aac -lvorbis -lvorbisenc -lvorbisfile -logg -ltheora -ltheoraenc -ltheoradec -lz -lfreetype -lopus -lwebp
$DEMO_PATH/encode_v.c
-s FORCE_FILESYSTEM=1
-s WASM=1
-s USE_SDL=2 # use SDL2
-s INVOKE_RUN=0 # not to run the main() in the beginning
-s EXIT_RUNTIME=1 # exit runtime after execution
-s MODULARIZE=1 # 延迟加载 use modularized version to be more flexible
-s EXPORT_NAME="createMP4Encoder" # assign export name for browser
-s EXPORTED_FUNCTIONS="[_main,_malloc,_free]" # export main and proxy_main funcs
-s EXPORTED_RUNTIME_METHODS="[FS, cwrap, ccall, setValue, writeAsciiToMemory]" # export preamble funcs
-s INITIAL_MEMORY=134217728 # 64 KB * 1024 * 16 * 2047 = 2146435072 bytes ~= 2 GB
-s ALLOW_MEMORY_GROWTH=1 # 允许动态扩展内存
--pre-js $WORKPATH/pre.js
--post-js $WORKPATH/post.js
$OPTIM_FLAGS
${EXTRA_FLAGS[@]}
)
echo "FFMPEG_EM_FLAGS=${FLAGS[@]}"
emcc "${FLAGS[@]}"
./build-demo.sh
会在项目目录下生成 mp4encoder.js
与 mp4encoder.wasm
其中js文件文件为胶水代码,使得C++接口能在浏览器js中调用。实际的C++逻辑存放于wasm文件中。
在容器外的项目目录下, 启动web静态服务器查看效果
调试
介绍
https://developer.chrome.com/blog/wasm-debugging-2020/
下载安装插件
https://goo.gle/wasm-debugging-extension
1、打开开发者工具,设置(F1) -> 实验 -> 勾选 WebAssembly Debug
2、因为项目在Docker下编译,需要把Docker路径映射到本地磁盘
3、打开开发者工具 -> 源代码 -> 左侧file://下即可找到源代码 -> 设置断点 -> 右侧监视添加变量
参数传递
简单参数传递
//把js string 转成 utf8 array
var getCStringPtr = function (jstr) {
var lengthBytes = lengthBytesUTF8(jstr) + 1;
var p = MP4Encoder._malloc(lengthBytes);
stringToUTF8(jstr, p, lengthBytes);
return p;
}
//allocateUTF8功能相同
//值类型可以直接传递,string必须先转array
var strPtr = getCStringPtr("/tmp/demo2.mp4");
var ret = MP4Encoder._createH264(strPtr, 1920, 1080, 25);
大块内存拷贝
//js 数组内存
let fileBuffer = new Uint8Array(imagedata.data.buffer);
//wasm 数组内存
let bufferPtr = MP4Encoder._malloc(fileBuffer.length);
//js -> wasm
MP4Encoder.HEAP8.set(fileBuffer, bufferPtr);
var ret = MP4Encoder._addFrame(bufferPtr);
_malloc
和 _free
这些系统方法是模块默认导出的。如果想查看其他方法是否可用,可以控制台打印MP4Encoder模块看其挂载的方法
文件读写
<input type="file" value="选择文件" onchange="inputJsFile(event)"></input>
var inputJsFile = function (event) {
let file = event.target.files[0];
file.arrayBuffer().then(t=>{
console.log(t)
//创建文件夹
FS.mkdir('/working');
//写入二进制数据到wasm虚拟目录
FS.writeFile('/working/input.txt', new Uint8Array(t), { flags:'w+' });
//查看写入成功
console.log(FS.stat('/working/input.txt'))
//从wasm读取到js
var buff = FS.readFile('/working/input.txt', { encoding: 'binary' });
console.log(buff)
var pStr = getCStringPtr("/working/input.txt");
var ret = MP4Encoder._openTestFile(pStr);
});
}
项目地址
https://github.com/gaobowen/wasmff
扩展阅读
https://developer.mozilla.org/zh-CN/docs/WebAssembly
https://developer.mozilla.org/zh-CN/docs/Web/API/IndexedDB_API
https://emscripten.org/docs/api_reference/index.html
WebAssembly C++开发环境搭建的更多相关文章
- python开发环境搭建
虽然网上有很多python开发环境搭建的文章,不过重复造轮子还是要的,记录一下过程,方便自己以后配置,也方便正在学习中的同事配置他们的环境. 1.准备好安装包 1)上python官网下载python运 ...
- IntelliJ IDEA安装及jsp开发环境搭建
一.前言 现在.net国内市场不怎么好,公司整个.net组技术转型,就个人来说还是更喜欢.net,毕竟不是什么公司都像微软一样财大气粗开发出VS这样的宇宙级IDE供开发者使用,双击sln即可打开项目, ...
- Qt for Android开发环境搭建及测试过程记录
最近学习了Qt的QML编程技术,感觉相较于以前的QtGUI来说更方便一些,使用QML可以将界面与业务逻辑解耦,便于开发. QML支持跨平台,包括支持Android平台,因此可以使用Qt的QML进行An ...
- node.js之开发环境搭建
一.安装linux系统 (已安装linux可跳此步骤) 虚拟机推荐选择:VirtualBox 或者 Vmware (专业版永久激活码:5A02H-AU243-TZJ49-GTC7K-3C61N) 我这 ...
- TODO:小程序开发环境搭建
TODO:小程序开发环境搭建 1.第一步当然是要先注册小程序了 2.登录到小程序 a)完善小程序信息,如名称,图标,描述 3.绑定开发者 4.获取AppID,并设置服务器信息 5.下载并安装开发者工具 ...
- Eclipse中Python开发环境搭建
Eclipse中Python开发环境搭建 目 录 1.背景介绍 2.Python安装 3.插件PyDev安装 4.测试Demo演示 一.背景介绍 Eclipse是一款基于Java的可扩展开发平台. ...
- Windows 10 IoT Serials 1 - 针对Minnow Board MAX的Windows 10 IoT开发环境搭建
目前,微软针对Windows IoT计划支持的硬件包括树莓派2,Minnow Board MAX 和Galileo (Gen 1和Gen 2).其中,Galileo (Gen 1和Gen 2)运行的是 ...
- Eclipse swt开发环境搭建
原料: eclipse swt.下载链接为: Eclipse 4.6.2 Release Build: 4.6.2 配置说明: Developing SWT applications using Ec ...
- Ionic- Android 开发环境搭建
Ionic- Android 开发环境搭建 为时一周的IONIC ADNROID 环境终于在各种处理错误中搭建成功,以下记录下搭建过程中遇到的各种情况的处理办法. 一 首先,当然是enviroment ...
- visual studio 2015 + Cordova 开发环境搭建
简单的写一些,备忘,太折腾了,特别是通过代理上网的我们国内的开发者 1.当然是安装Visual Studio 2015,别忘了选择Tools For Apache Cordova. 对于通过Proxy ...
随机推荐
- 【Mybatis】Bonus02 补充
关于主键生成问题 Mybatis的主键生成是基于JDBC的使用主键[getGeneratedKeys()]方法 也就是说,必须要JDBC驱动的支持才行 @Test public void junitT ...
- 【DataBase】排课设计思路
想设计一个排课系统,看了网上文库的表结构设计弄的我是一点没看懂 看看知乎又是扯一堆算法 我想一个适用所有学校的排课程序是不现实的,需求是千变万化的 我们理解的,看到的都是已经排好的结果,是Excel把 ...
- 绝对要收藏!!! JavaEE开发常用注解
目录 前言 1.Mybatis常用注解 2.SpringMVC常用注解 3.Spring常用注解 1. IoC注解 2. DI注解 3. 事务注解 4.SpringBoot常用注解 5.Lombok注 ...
- NVIDIA具身机器人实验室 —— GEAR —— Generalist Embodied Agent Research —— NVIDIA机器人实验室
相关: https://www.youtube.com/watch?v=jbJPG2H8hn4
- 再谈汤普森采样(Thompson Sampling)
相关: [转载] 推荐算法之Thompson(汤普森)采样 [转载] 推荐系统 EE 问题与 Bandit 算法 python语言绘图:绘制一组beta分布图 转载: beta分布介绍 python语 ...
- vscode 单步调试时设置——是否进入非本项目的代码
如题,在vscode中默认设置在调试时不能进入非本项目的代码(类.函数.模块),这个设置基本是OK的,因为确实没有必要进入到非本项目的代码中,但是如果有特殊需要想改变设置使其能够进入到本项目外的代码时 ...
- 后端开发学习敏捷需求-->产品价值的定位
产品价值的定位 为什么要写这一系列文章 2023年网上报名学习了,敏捷软件需求的培训课程 ,一直都没有进行回顾,回顾学习,总结 业务分析的能力偏弱,学习和了解关于业务需求相关的方法和理论 每一年都有一 ...
- AWG(American wire gauge)美国线规
AWG(American wire gauge)美国线规,是一种区分导线直径的标准,又被称为 Brown & Sharpe线规.这种标准化线规系统于1857年起在美国开始使用.AWG前面的数值 ...
- WPF 如何利用Blend给Button添加波纹效果
先看一下效果吧: 如果不会写动画或者懒得写动画,就直接交给Blend来做吧; 其实Blend操作起来很简单,有点类似于在操作PS,我们只需要设置关键帧,鼠标点来点去就可以了,Blend会自动帮我们生成 ...
- python 离线安装依赖
步骤: 1. 访问 https://pypi.org/ 2. 搜索要下载的依赖 3. 下载tar.gz文件 4. 解压,再解压(第一次解压后的dist文件夹内tar文件需解压) 5. 解压后的文件夹内 ...