标签: emscripten

如何在JavaScript中使用ffmpeg将H.264帧解码为RGB帧

我正在尝试将 ffmpeg 编译为 javascript,以便可以使用 node.js 解码 H.264 视频流。这些流是打包到 RTP NALU 中的 H.264 帧,因此任何解决方案都必须能够接受 H.264 帧而不是整个文件名。这些帧不能位于 MP4 或 AVI 等容器中,因为这样解复用器需要在进行解复用之前需要每个帧的时间戳,但我正在处理实时流,没有容器。

通过 RTP 传输 H.264

下面是我用来监听 udp 套接字的基本代码。在“消息”回调中,数据包是 RTP 数据报。数据报的数据部分是 H.264 帧(P 帧和 I 帧)。

var PORT = 33333;
var HOST = '127.0.0.1';

var dgram = require('dgram');
var server = dgram.createSocket('udp4');

server.on('listening', function () {
    var address = server.address();
    console.log('UDP Server listening on ' + address.address + ":" + address.port);
});

server.on('message', function (message, remote) {
    console.log(remote.address + ':' + remote.port +' …
Run Code Online (Sandbox Code Playgroud)

ffmpeg h.264 node.js emscripten fluent-ffmpeg

5
推荐指数
1
解决办法
3906
查看次数

emscripten 中绑定属性和函数时出错

我正在尝试使用 emscripten 编译 C++ 类并公开绑定。我遇到编译器错误。

#include <emscripten/bind.h>
#include <emscripten/emscripten.h>


using namespace emscripten;

class  MyClass {
private:
    int _year;
    int _month;
    int _day;
public:
    MyClass() { }
    MyClass(int year, int month, int day);

    int getMonth();
    void setMonth(int);
    int getYear();
    void setYear(int);
    int getDay();
    void setDay(int);
    bool isLeapYear();
    int daysInMonth();

    void increment();
    void decrement();
};

EMSCRIPTEN_BINDINGS(my_sample_class) {
class_<MyClass>("MyClass") 
    .constructor<>()
    .constructor<int, int, int>()
    .function("getMonth",  &MyClass::getMonth)
    .function("increment", &MyClass::increment)
    .function("decrement", &MyClass::decrement)
    .property("year",&MyClass::getYear, &MyClass::setYear )
    //.property("month", &MyClass::getMonth, &MyClass::setMonth )
    //.property("day",&MyClass::getDay, &MyClass::setDay )
    ;
}
Run Code Online (Sandbox Code Playgroud)

编译器对构造函数或函数绑定没有任何问题。我遇到了属性绑定的问题。我只有一个未注释的,以最大限度地减少我返回的错误(它们只是同一错误的重复,但针对不同的行)。这是我返回的错误。

In …
Run Code Online (Sandbox Code Playgroud)

c++ llvm emscripten webassembly

5
推荐指数
1
解决办法
1174
查看次数

如何从 emscripten/web assembly 函数返回字符串给 ac 调用者

尝试遵循 emscripten 教程,在对 emscripten 的 C 调用之间传递参数,但仅正确传递数字,而不传递字符串。如何从 js 库调用将字符串返回到 C?

测试.c:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <emscripten.h>
extern char *getText(void);

int main() {
    printf(getText());
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

mylib.js:

mergeInto(LibraryManager.library, {
    getText: function() {
        return "a test string";
    }
});
Run Code Online (Sandbox Code Playgroud)

构建命令:

emcc test.c -o test.html --js-library mylib.js
Run Code Online (Sandbox Code Playgroud)

我期望看到的输出是“测试字符串”,但我实际看到的是“emcc”

我在 stackoverflow 和其他地方进行了广泛的查找,但是我找不到任何关于将字符串值从 JS 返回到 C 的信息,只能找到将它们从 C 传递到 JS 的信息,所以这不是我能找到的任何其他问题的重复。

是什么赋予了?

emscripten webassembly

5
推荐指数
1
解决办法
1837
查看次数

Emrun 和 Headless chrome - 如何让这两者一起工作?

我想在 docker 环境中使用 headless chrome 来运行编译为 Web 程序集的 C++ 测试。

我已确保我的测试可执行文件与--emrun标志链接,以确保所有输出都发布到 emrun 服务器并打印到控制台(然后由 CTest 框架捕获)。

但是,当运行无头铬时

emrun --browser=chrome --browser_args="--no-sandbox --disable-gpu --use-gl=swiftshader --headless" ./MyTestExecutable.html --gtest_filter=MyTestFixture.myTest
Run Code Online (Sandbox Code Playgroud)

没有任何内容打印到输出中。但是,如果我将命令更改为

emrun --browser=chrome --browser_args="--no-sandbox --disable-gpu --use-gl=swiftshader --headless --remote-debugging-port=9222" ./MyTestExecutable.html --gtest_filter=MyTestFixture.myTest
Run Code Online (Sandbox Code Playgroud)

测试输出很高兴地打印到命令行,但如果输出超过 cca 9kB,则会被截断,这是它自己的问题 - 见下文。但是,chrome 调试会话保持挂起并使用端口 9222。我当前的解决方法是确保 CTest 框架中的每个单元测试都有自己独特的调试端口,并让 chrome 会话保持生成状态,直到容器停止 - docker 清理它们那就起来吧。这个解决方案很脏,我不喜欢它。

--remote-debugging-port我想知道是否有人知道如果没有提供给 Chrome,为什么 emrun 服务器不会打印任何内容?

我的预感是,chrome 在完成执行后会停止向 emrun 服务器发送数据,并且启用调试会以某种方式减慢 chrome 的速度,从而为至少一些输出发送到 emrun 服务器腾出时间(这也解释了大输出大小的截断) 。

我还去查看了 Emscripten 人员如何运行他们的 CI 测试,发现他们在 Xvfb 下使用完整的 chrome,而不是 headless chrome。我也尝试过,但是,这导致了一些其他问题,例如如果在容器内运行但不是以 root 用户身份运行,则 chrome 会因 SIGTRAP 崩溃,而 …

c++ google-chrome headless emscripten docker

5
推荐指数
1
解决办法
408
查看次数

如何检测 Emscripten 生成的 .js 何时完成加载 wasm,以便我可以运行调用它的 JS 函数?

我正在使用 Emscripten 将一些 C 代码编译为 WebAssembly。这是我的 Makefile 中的最后一个 emcc 调用:

emcc $(CFLAGS) iva.a -o iva.js
Run Code Online (Sandbox Code Playgroud)

它按预期工作并生成 .js 文件和 .wasm 文件。JS 加载到我的 HTML 页面中,如下所示:

<script src="../dist/iva.js">
Run Code Online (Sandbox Code Playgroud)

它会正确加载并实例化 WebAssembly 代码iva.wasm。加载页面后不久,此消息就会出现在控制台中:

Fetch finished loading: GET "http://localhost:6931/dist/iva.wasm".
Run Code Online (Sandbox Code Playgroud)

我认为这意味着我的 WebAssembly 是通过 fetch() 加载的,也许在等待一些处理时,我可以通过控制台访问我的函数:

Module._init_display_system()
Run Code Online (Sandbox Code Playgroud)

并获取返回值。这是正确的并且一切正常。

显然,我也应该能够通过脚本来做到这一点。但是,我看不到一种仅在实例化 WebAssembly后运行函数的方法。我感觉我错过了一些相当明显的东西。

无论如何,我该怎么做?

javascript emscripten webassembly

5
推荐指数
2
解决办法
4854
查看次数

WASM链接错误:函数签名不匹配

我已经通过 emscripten 使用 WASM 几个星期了,并且取得了良好的进展,直到出现此错误:

exception thrown: RuntimeError: function signature mismatch,RuntimeError: function signature mismatch
Run Code Online (Sandbox Code Playgroud)

这种情况开始发生在以前可以工作的代码中,似乎与 WASM 缺乏对 javascript 中 64 位整数的支持以及文件管理中使用的偏移量有关。我做了一个孤立的案例:

#include <iostream>

int main(int argc, char const *argv[])
{   
    char test[30];
    std::cout << __LINE__ << std::endl;
    FILE *f = fopen("minimal_call_dispatch.cpp","ra");
    std::cout << __LINE__ << std::endl; 
    fseek(f, 100, SEEK_SET);
    std::cout << __LINE__ << std::endl;
    fclose(f);
    std::cout << __LINE__ << std::endl; 
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

建筑:

call emcc -o ./test.js test_file.cpp -s WASM=1 -s NO_EXIT_RUNTIME=1 -std=c++1z 
Run Code Online (Sandbox Code Playgroud)

由于上述错误,在“fseek”失败之前会输出“6\n8\n”。

在此过程中,我怀疑 wasm 正在尝试使用与具有 64 位整数而不是 …

c++ mismatch emscripten

5
推荐指数
1
解决办法
1万
查看次数

Emscripten - 有没有办法限制对标准输出的写入?

我正在运行一个使用 emscripten 编译为 wasm 的 C 工具。该工具适用于非常大的文件。在 CLI 上正常运行此工具时,通常操作会传输结果并在返回足够的数据后提前终止程序。例如你可以运行:

./tool <input-file> | head -n 100

该工具将在检测到 stdout 已被 关闭后终止head,实际上仅读取一小部分输入。

问题是带有 emscripten 的 stdout 似乎是异步的(通过覆盖 Module.print),因此该工具每次都会运行完成。有没有办法让它在标准输出上阻塞,这样我只能读取我需要的内容,然后终止该工具?

javascript c emscripten webassembly

5
推荐指数
1
解决办法
847
查看次数

Emscripten:自定义生成的 js,以便以自定义方式加载 .wasm 文件

通过使用以下选项进行编译,

emcc -s WASM=1 main.cpp -o index.js

emscripten 生成一个index.wasm, 和一个 js 包装器index.js。js 包装器在浏览器中运行时加载.wasm位于同一目录中的文件。XMLHttpRequest

那么如果我需要手动加载文件该怎么办呢.wasm?加载部分似乎是硬编码在包装器中的。

以下是我需要这样做的一些情况:

  • 我需要.wasm从另一个 url(例如从 CDN)提供该文件。
  • 下载文件的 url.wasm是动态生成的。
  • 代码在XMLHttpRequest不允许的沙箱中运行,只有像getMyData('some_file').
  • 我需要将所有文件嵌入为 base64 字符串。

.wasm我知道我只能通过以下方式生成文件

emcc -s WASM=1 main.cpp -o index.wasm

但随后我丢失了包装器,这在使用 SDL 和 GLES 等 emscripten API 时并非易事。

javascript emscripten webassembly

5
推荐指数
1
解决办法
1203
查看次数

使用 CMake 时如何导出 Emscripten 中的 C 函数

本教程中,它展示了以下导出 C 函数的示例

./emcc tests/hello_function.cpp -o function.html -s EXPORTED_FUNCTIONS='["_int_sqrt"]' -s EXPORTED_RUNTIME_METHODS='["ccall", "cwrap"]'
Run Code Online (Sandbox Code Playgroud)

我想做同样的事情,除了我像这样使用 CMake

cd bin
emcmake cmake ../src
emmake make
Run Code Online (Sandbox Code Playgroud)

emmake 中指定的规范方式是什么-s?我应该添加它来CMakeLists.txt喜欢吗

set(EXPORTED_FUNCTIONS '["_int_sqrt"]')
Run Code Online (Sandbox Code Playgroud)

或者做类似的事情?

c cmake emscripten emmake

5
推荐指数
1
解决办法
3563
查看次数

QtCreator找不到emscripten编译器

我按照指南使用emsdk$PATH安装了 emscripten 并激活了它。然后我按照 emsdk 本身的指示配置了我的文件并获取了源。现在我可以在终端中emsdk-master/emsdk_env.sh访问emcc和。该文件也存在(这是 QtCreator 将生成的文件) fetch 来查找 WASM 编译器的路径)。em++~/.emscripten

Qt 的套件WebAssembly也已由 Qt 安装Maintenance Tool

现在,在 QtCreator 的套件配置中,我得到了这个(QtCreator 在采购后通过终端打开emsdk_env.sh):

在此输入图像描述

它本身无法确定编译器的路径。

“编译器”选项卡中,我手动添加了一个编译器,如下所示:

在此输入图像描述

但之后我在“套件”选项卡中收到此错误:

在此输入图像描述

这意味着什么?我跳过了什么?有人有这样做的经验吗?

另外,将编译器从 更改em++wasm-32-wasi-clang++clang++不会改变任何内容。

在此输入图像描述

顺便说一句,如果我使用该套件,我会得到:

Error while parsing file whatever.pro. Giving up.
Project ERROR: Cannot run target compiler 'em++'. Output:
===================
===================
Maybe you forgot to setup the environment?
Run Code Online (Sandbox Code Playgroud)

请不要告诉我这个问题是这个 …

linux qt qt-creator emscripten webassembly

5
推荐指数
1
解决办法
1952
查看次数