1.0.0 • Public • Published


A Native Module for React Native, to use the Libmedia library.
Libmedia is a library of helpers dealing with media management, as a toolbox for developers to build their applications on Android.

WARNING: The module is for the Android platform only, as is the library.


This package, as a wrapper, is of no use without the library which is subject to a license for commercial usage.


  • Run the following commands from your React Native project directory:

     npm install @maxcom/react-native-libmedia
    • Additional step for React Native < 0.60:

      react-native link @maxcom/react-native-libmedia
    • Additional step for React Native < 0.58:
      If your gradle plugin version is already 3.0.0+, you should replace the deprecated compile dependency type by the implementation dependency type in android/app/build.gradle.

    • Additional step for React Native < 0.56:
      On build, Gradle 4.4 will produce a warning because of the presence of a '/' character in the project name derived from a scoped node package name. The support of such a character is annonced to have been deprecated and is scheduled to be removed in Gradle 5.0.
      An adjustment in the react-native tooling to replace '/' by '_' is effective as of version 0.56. Before it, you have to do yourself the replacement of ':@maxcom/react-native-libmedia' by ':@maxcom_react-native-libmedia' in these project files: android/settings.gradle and android/app/build.gradle.

  • Get the necessary jar files, as mentioned in Integration Guidelines Step 1 and Step 1a, but put them in <your_project>\node_modules\@maxcom\react-native-libmedia\android\libs\.

  • Apply Integration Guidelines Step 2, Step 3. Step 4 is already embedded in the module.


import Libmedia from '@maxcom/react-native-libmedia';

Module API


Creates the server, if not already done, as a LocalSingleHttpServer instance.


Creates the server, if not already done, as a WifiSingleHttpServer instance.

Libmedia.setCipher(transformation: string, key: Array<number>, algorithm: string, iv?: Array<number>)

Sets the Cipher for decryption.


  • transformation - The name of the transformation, of the form: "algorithm/mode/padding" or "algorithm".
  • key - The encryption key, as a byte array.
  • algorithm - The name of the secret-key algorithm to associate with the key.
  • iv - The Initialization Vector, as a byte array, if necessary for the transformation.

Libmedia.setCipherFactory(transformation: string, key: Array<number>, algorithm: string, iv?: Array<number>)

Sets the cipher factory for decryption.

Parameters: same as setCipher().


Clears the cipher of the server.


Starts the server.

Libmedia.getUrl(path: string)

Returns the URL to serve a resource specified by the provided path.


  • path - The path of a resource.


Stops the server.


Releases the reference to the server, after stopping it if necessary.


Hereunder is the source of a TestLibmediaScreen.js, as an example of a screen for a navigator with react-navigation.

 * Copyright (c) 2019-present, Maxcom.

import React, { Component } from 'react';
import { PermissionsAndroid } from "react-native";
import { WebView} from 'react-native-webview';

import Libmedia from '@maxcom/react-native-libmedia';

 * Produce an array of numbers, one for each of the characters of a string.
 * WARNING: charCodeAt() returns the Unicode value of a character, in the range 0-65535.
 * As the aim is to return bytes, this simple converter is usable only with Ascii characters (code point < 0x80)
const numberArrayFromAscii = (str) => str.split('').map(c => c.charCodeAt());

export default class TestLibmediaScreen extends Component<{}> {
  constructor(props) {
    __DEV__ && console.log(`${this.constructor.name} const`, props);
    this.state = {
      path: "",
  componentDidMount() {
    __DEV__ && console.log(`${this.constructor.name} componentDidMount`);
    this.requestStoragePermission();  // better to do it beforehand to avoid a fail on the first run
  componentWillUnmount() {
    __DEV__ && console.log(`${this.constructor.name} componentWillUnmount`);

  async requestStoragePermission() {
    try {
      const isGranted = await PermissionsAndroid.check(PermissionsAndroid.PERMISSIONS.READ_EXTERNAL_STORAGE);
      if (!isGranted) {
        const granted = await PermissionsAndroid.request(PermissionsAndroid.PERMISSIONS.READ_EXTERNAL_STORAGE);
        if (granted === PermissionsAndroid.RESULTS.GRANTED) {
          __DEV__ && console.log(`${this.constructor.name} Permission granted`);
        } else {
          __DEV__ && console.log(`${this.constructor.name} Permission denied`);
    } catch (err) {

  async setUp() {
    try {
      await Libmedia.createLocalSingleHttpServer();
// uncomment one of these cases
      // no Cipher needed
      //var path = 'asset://clear.mp4';

      //var path = 'asset://encrypted.mp4';
      //await Libmedia.setCipher('ARC4', numberArrayFromAscii('BrianIsInTheKitchen'), 'ARC4', null);

      var path = '/mnt/sdcard/Movies/libm/secure.ctr.mp4';
      await Libmedia.setCipher('AES/CTR/NoPadding', numberArrayFromAscii('1234567890123456'), 'AES', new Array(16).fill(0));
      await Libmedia.start();

      path = await Libmedia.getUrl(path);
      __DEV__ && console.log(`${this.constructor.name} path ${path}`);
    } catch(e) {
      console.error(this.constructor.name, e);

  async tearDown() {
    await Libmedia.stop();
    await Libmedia.destroy();

  render() {
    const source = { html: `
<video src='${this.state.path}' controls></video>
    return (
<WebView style={{ flex: 1 }} source={source} />

Package Sidebar


npm i @maxcom/react-native-libmedia

Weekly Downloads






Unpacked Size

16.9 kB

Total Files


Last publish


  • maxcom