mediainfo.js

repository·main·Indexed 21 days ago

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

A WebAssembly port of the MediaInfoLib C++ library for high-performance media metadata extraction in browsers and Node.js. It provides a JavaScript API via mediaInfoFactory to analyze video and audio files, supporting multiple output formats (object, JSON, XML, HTML, text) and a CLI for file inspection. The library includes specialized configurations for integration with Angular, Vite, React, and Webpack to handle the MediaInfoModule.wasm binary.

Tokens
11.2K
Snippets
26
Records
37
Agent score
74%

What's inside mediainfo.js

  1. Overview of mediainfo.js

    main
    mediainfo.js is a web-compatible version of the MediaInfoLib (originally written in C++), compiled to WebAssembly. It allows developers to extract media metadata in both browser environments and Node.js. It provides a high-performance way to inspect media files directly in the client or server-side JavaScript environments.
  2. Configure Webpack for mediainfo.js WASM

    main

    When using mediainfo.js with Webpack, you must configure the webpack.config.js to ensure the WebAssembly (WASM) file is preserved with its original name and is discoverable via an alias. This prevents Webpack from renaming the file during the build process, which would break the internal loading mechanism of the library.

    // In webpack.config.js
    module.exports = {
      // 1. Preserve the original WASM filename
      assetModuleFilename: '[name][ext]',
    
      // 2. Make the WASM file discoverable via alias
      alias: {
        'MediaInfoModule.wasm': wasmFilePath
      },
    };
  3. Use mediainfo.js in a Vite + React project

    main

    To use mediainfo.js with Vite and React, you should leverage Vite's asset pipeline to handle the WebAssembly (WASM) file. Instead of relying on relative paths that might break after bundling, import the WASM file as an asset URL using the ?url suffix. This ensures Vite fingerprints the file and provides a reliable URL that can be passed to the locateFile option in the mediaInfoFactory configuration.

    import mediaInfoFactory from 'mediainfo.js'
    import mediaInfoWasmUrl from 'mediainfo.js/MediaInfoModule.wasm?url'
    
    await mediaInfoFactory({
      locateFile: (path, prefix) =>
        path === 'MediaInfoModule.wasm' ? mediaInfoWasmUrl : `${prefix}${path}`,
    })
  4. Configure MediaInfoModule.wasm assets in Angular

    main

    To use mediainfo.js in an Angular project, you must ensure the WebAssembly module (MediaInfoModule.wasm) is included in your build assets. This allows the application to load the WASM binary at runtime. Add the following configuration to your angular.json file under the assets array of your build target:

    "assets": [
      {
        "input": "node_modules/mediainfo.js/dist",
        "glob": "MediaInfoModule.wasm",
        "output": ""
      }
    ],
  5. Load the WASM file in React using locateFile

    main

    To ensure mediainfo.js can find its required WebAssembly binary in a React application, you must provide a locateFile function to the mediaInfoFactory. This function tells the library how to resolve the path to the .wasm file. In a standard Webpack setup, you can override it to return the filename directly, allowing the alias configured in Webpack to handle the resolution.

    // In App.tsx
    const mediaInfo = await mediaInfoFactory({
      locateFile: (filename) => filename,
    });
  6. Understand the BaseTrack @type and @typeorder properties

    main

    In the BaseTrack interface, the @type property identifies the category of the media track. Supported values are:

    • General
    • Video
    • Audio
    • Text
    • Image
    • Menu
    • Other

    The @typeorder property (optional) provides a string indicating the sequence of tracks of the same type within the bitstream.

  7. Resolve Vite build warnings for MediaInfoModule.wasm

    main
    When using mediainfo.js with Vite, you may encounter a build warning related to new URL('MediaInfoModule.wasm', import.meta.url) within the generated loader. This can be resolved by implementing a small transform plugin (e.g., fixMediainfoWasmImportMetaUrl) in your vite.config.ts to handle the import meta URL correctly.
  8. Configure MediaInfo output formats

    main

    When creating a MediaInfo instance via the factory, you can specify the output format. The available FormatType options are:

    • 'object': Returns a parsed JavaScript object (MediaInfoResult). This is the default.
    • 'JSON': Returns a serialized JSON string.
    • 'XML': Returns a serialized XML string.
    • 'HTML': Returns a serialized HTML string.
    • 'text': Returns a serialized text string.

    The FORMAT_CHOICES constant contains the string literals ['JSON', 'XML', 'HTML', 'text'] which correspond to the non-object formats.

    // The available format strings are:
    // 'JSON', 'XML', 'HTML', 'text'
  9. Configure MediaInfoFactoryOptions

    main

    When calling mediaInfoFactory, you can pass a MediaInfoFactoryOptions object to customize the behavior of the MediaInfo instance.

    Available options:

    • coverData (boolean): If true, output cover data as base64.
    • chunkSize (number): The chunk size used by analyzeData in bytes.
    • format (TFormat): The desired result format. Supported values are object, JSON, XML, HTML, or text.
    • full (boolean): If true, provides full information display including all internal tags.
    • locateFile (function): A function used to locate the MediaInfoModule.wasm file. This is useful if the WASM file is hosted at a different URL than the default path. It follows the Emscripten locateFile pattern: (path: string, prefix: string) => string.
    const options = {
      coverData: true,
      chunkSize: 1024 * 1024,
      format: 'JSON' as const,
      full: true,
      locateFile: (path: string, prefix: string) => `https://my-cdn.com/wasm/${path}`
    };
    
    const mediaInfo = await mediaInfoFactory(options);
  10. How to use analyzeData with a callback

    main

    If you prefer a callback-based approach over Promises, analyzeData supports a ResultCallback signature. The callback is invoked with (result, err), where result is the analyzed data (or null) and err is an error object if the analysis fails.

    mediaInfo.analyzeData(size, readChunk, (result, err) => {
      if (err) {
        console.error('Analysis failed:', err);
        return;
      }
      console.log('Analysis result:', result);
    });
  11. Analyze media data using analyzeData()

    main

    The analyzeData method is the primary way to process media files chunk by chunk. It is designed to work with large files by reading data in segments rather than loading the entire file into memory.

    It accepts two main arguments:

    1. size: The total size of the buffer in bytes. This can be a number or a function that returns a Promise<number> or number.
    2. readChunk: A function used to fetch the next segment of data. It receives the size to read and the current offset, and must return a Uint8Array or a Promise<Uint8Array>.

    The method returns a Promise that resolves with the analysis result (based on your configured format) or rejects if an error occurs. You can also provide a callback function instead of using the Promise.

    Note: You cannot start a new analysis while another is currently in progress on the same MediaInfo instance.

    // Example: Analyzing a file using a custom chunk reader
    const result = await mediaInfo.analyzeData(
      fileSize, 
      async (size, offset) => {
        // Your logic to fetch a chunk from a File, Blob, or network
        const chunk = await fetchChunk(offset, size);
        return new Uint8Array(chunk);
      }
    );
  12. Initialize MediaInfo using mediaInfoFactory

    main

    Use mediaInfoFactory to create a new MediaInfo instance. This function is asynchronous and handles the loading of the underlying WASM module. You can use it in two ways:

    1. Promise-based: Call it with options to receive a Promise that resolves to a MediaInfo instance.
    2. Callback-based: Provide a success callback and an optional error callback.

    By default, the output format is set to object unless specified otherwise in the options.

    import mediaInfoFactory from './mediaInfoFactory.js';
    
    // Promise approach
    const mediaInfo = await mediaInfoFactory({
      format: 'JSON'
    });
    
    // Callback approach
    mediaInfoFactory(
      { format: 'XML' },
      (instance) => {
        console.log('MediaInfo ready:', instance);
      },
      (err) => {
        console.error('Failed to load MediaInfo:', err);
      }
    );