Nelson Teixeira
Nelson Teixeira

Reputation: 6570

Mediainfo.js integration in Angular 8

I'm trying to use Mediainfo.js to get some video info on the frontend of an Angular 8 project. But I'm getting the errors below:

GET https://192.168.25.177:4200/MediaInfoModule.wasm 404 (Not Found)
wasm streaming compile failed: TypeError: Failed to execute 'compile' on 'WebAssembly': HTTP status code is not ok
falling back to ArrayBuffer instantiation
GET https://192.168.25.177:4200/MediaInfoModule.wasm 404 (Not Found)
bothg async and sync fetching of the wasm failed
failed to asynchronously prepare wasm: RuntimeError: abort(both async and sync fetching of the wasm failed). Build with -s ASSERTIONS=1 for more info.
RuntimeError: abort(both async and sync fetching of the wasm failed). Build with -s ASSERTIONS=1 for more info.
ERROR Error: Uncaught (in promise): RuntimeError: abort(RuntimeError: abort(both async and sync fetching of the wasm failed). Build with -s ASSERTIONS=1 for more info.). Build with -s ASSERTIONS=1 for more info.
RuntimeError: abort(RuntimeError: abort(both async and sync fetching of the wasm failed). Build with -s ASSERTIONS=1 for more info.). Build with -s ASSERTIONS=1 for more info.
at abort (vendor.js:131481)
at vendor.js:131481
at ZoneDelegate.invoke (polyfills.js:3709)
at Object.onInvoke (vendor.js:82905)
at ZoneDelegate.invoke (polyfills.js:3708)
at Zone.run (polyfills.js:3474)
at polyfills.js:4205
at ZoneDelegate.invokeTask (polyfills.js:3741)
at Object.onInvokeTask (vendor.js:82886)
at ZoneDelegate.invokeTask (polyfills.js:3740)
at resolvePromise (polyfills.js:4147)
at polyfills.js:4212
at ZoneDelegate.invokeTask (polyfills.js:3741)
at Object.onInvokeTask (vendor.js:82886)
at ZoneDelegate.invokeTask (polyfills.js:3740)
at Zone.runTask (polyfills.js:3518)
at drainMicroTaskQueue (polyfills.js:3909)

I tried to install wasm package, but it returned lots of V8 related errors. And in it's npm page says it's Node only (https://www.npmjs.com/package/wasm)

I also checked the Webpack example (https://github.com/buzz/mediainfo.js/blob/50830088bd775942a3962416ce61f759b13bc7c2/webpack.config.js#L34) But it's far too different from Angular's configuration. I also found this page that shows how to use an wasm module in Angular, but I ain't got a clue on what would I put instead of the example's fibonacci function.

Yet Mediainfo's page claims "All analyzing is done in the browser", so it should be possible.

How can I integrate Mediainfo into Angular 8 ? Any other info on this error that can help me ?

Also if anyone knows how to install wasm in the frontend, it would be helpful in order for me to continue to try the integration.

Edit

I made it work, but in a very clumsy way. I imported the CDN into index.html and put

declare let MediaInfo: any ;

in the component.

There has to be a better way than that.

Also in my production environment I get these messages in the console which don't appear locally:

DevTools failed to load SourceMap: Could not parse content for https://assiste.estaleiro.serpro.gov.br/assets/js/mediainfo.min.js.map: Unexpected token < in JSON at position 0
wasm streaming compile failed: TypeError: Failed to execute 'compile' on 'WebAssembly': Incorrect response MIME type. Expected 'application/wasm'.
falling back to ArrayBuffer instantiation

What I need is the correct integration with Angular. How do I integrate this using

import MediaInfo from 'mediainfo.js'

Maybe I should put some configuration in app-module or something. I just don't know where to start.

Upvotes: 0

Views: 2091

Answers (3)

Nelson Teixeira
Nelson Teixeira

Reputation: 6570

I tried to create a Pull Request to MediaInfo with a simple project with the above solution and the author showed me a better way to integrate it with Angular:

Step #1

Modify the angular.json file to add the wasm file from node_modules mediainfo dir to the assets section, in the options of build target

"architect": {
    "build": {
      "builder": "@angular-devkit/build-angular:browser",
      "options": {
        
        ...
        "assets": [
          "src/assets",
          "src/favicon.ico",
          {
              "input": "node_modules/mediainfo.js/dist",
              "glob": "MediaInfoModule.wasm",
              "output": ""  
          }
        ],
        "styles": [
        ...

Step #2

Include this section on package.json or you will get runtime errors when running mediainfo in the frontend. It could be just above dependencies:

...
"browser": {
    "fs": false,
    "path": false
},
"dependencies": {
...

Step #3

To make typescript stop complaining about mediainfo.js import, create the following file below src/

types/mediainfo.js/index.d.ts 

and put the following content inside:

declare module 'mediainfo.js'

Step #4

Restart ng serve

This way you don't need to commit wasm file and can benefit from any version upgrades without recopying the file.

Edit

@KhoPhi these are the links involved in the discussion:

Relevant links related to this question:

Original issues I opened about not being able to use Mediainfo.js in Angular: https://github.com/buzz/mediainfo.js/issues/38 https://github.com/buzz/mediainfo.js/issues/39

Pull request anouncement about Angular example and enhancement request:

https://github.com/buzz/mediainfo.js/issues/41

First pull request with angular example:

https://github.com/buzz/mediainfo.js/pull/40

Simplified pull request with angular example after request from author:

https://github.com/buzz/mediainfo.js/pull/42

Upvotes: 0

Daniel Wexler
Daniel Wexler

Reputation: 149

I know this question was for Angular, but in case anyone finds this post and wants a solution that uses a service worker and was tested with Create React App (CRA), I've posted my solution on this SO post.

Upvotes: 1

David
David

Reputation: 34455

The problem is that mediainfo will try to load the MediaInfoModule.wasm file from the root directory: http://localhost:4200/MediaInfoModule.wasm.

So you just need to make sure that this file is reachable.

Step #1

Copy the node_modules/mediainfo.js/dist/MediaInfoModule.wasm to your project's src directory,

Step #2

Modify the angular.json file to add that file to the assets section, in the options of build target

"architect": {
    "build": {
      "builder": "@angular-devkit/build-angular:browser",
      "options": {
        
        ...
        "assets": [
          "src/assets",
          "src/favicon.ico",
          "src/MediaInfoModule.wasm"
        ],
        "styles": [

Step #3

Restart ng serve

Upvotes: 3

Related Questions