npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

bitmovin-player-react

v1.0.1

Published

A React component that creates an instance of Bitmovin player

Downloads

1,149

Readme

Bitmovin Player React

This is an open-source project created to enable customers to integrate the Bitmovin Player into React projects. It has been created to provide customers with a starting point, which can be built upon through active collaboration and contributions. We look forward to seeing this library expand and grow.

CI MIT License Bitmovin Community npm version npm dm npm dt

Getting Started

  1. npm i bitmovin-player-react bitmovin-player bitmovin-player-ui --save
  2. Add import "bitmovin-player-ui/dist/css/bitmovinplayer-ui.css"; to your entry point file
  3. Use the player in your React components:
import { PlayerConfig, SourceConfig } from "bitmovin-player";
import { BitmovinPlayer } from "bitmovin-player-react";
import { Fragment } from "react";

const playerConfig: PlayerConfig = {
  key: "<key>",
  playback: {
    muted: true,
    autoplay: true,
  },
};

const playerSource: SourceConfig = {
  hls: "https://cdn.bitmovin.com/content/assets/streams-sample-video/sintel/m3u8/index.m3u8",
};

export function MyComponent() {
  return (
    <Fragment>
      <h1>Simple demo</h1>
      <BitmovinPlayer config={playerConfig} source={playerSource} />
    </Fragment>
  );
}

Documentation

Dynamically update player source config

BitmovinPlayer keeps track of the source config and reloads the source on changes:

const playerSources: Array<SourceConfig | undefined> = [
  {
    hls: "https://cdn.bitmovin.com/content/assets/streams-sample-video/sintel/m3u8/index.m3u8",
  },
  {
    hls: "https://cdn.bitmovin.com/content/assets/streams-sample-video/tos/m3u8/index.m3u8",
  },
  // To demonstrate that the source can be unloaded as well.
  undefined,
];

export function MyComponent() {
  const [playerSource, setPlayerSource] = useState(playerSources[0]);

  useEffect(() => {
    let lastSourceIndex = 0;

    const intervalId = setInterval(() => {
      const newIndex = ++lastSourceIndex % playerSources.length;

      console.log(`Switching to source ${newIndex}`, playerSources[newIndex]);

      setPlayerSource(playerSources[newIndex]);
    }, 15_000);

    return () => clearInterval(intervalId);
  }, []);

  return (
    <Fragment>
      <h1>Dynamic source demo</h1>
      <BitmovinPlayer config={playerConfig} source={playerSource} />
    </Fragment>
  );
}

Dynamically update player config and UI config

BitmovinPlayer keeps track of the player config and UI config and reinitializes the player (destroys the old instance and creates a new one) on changes :

const playerConfigs: Array<PlayerConfig> = [
  {
    key: "<key>",
    playback: {
      autoplay: true,
      muted: true,
    },
  },
  {
    key: "<key>",
    playback: {
      autoplay: false,
      muted: false,
    },
  },
];

export function MyComponent() {
  const [playerConfig, setPlayerConfig] = useState(playerConfigs[0]);

  useEffect(() => {
    let lastConfigIndex = 0;

    const intervalId = setInterval(() => {
      const newIndex = ++lastConfigIndex % playerConfigs.length;

      console.log(`Switching to player config ${newIndex}`, playerConfigs[newIndex]);

      setPlayerConfig(playerConfigs[newIndex]);
    }, 15_000);

    return () => clearInterval(intervalId);
  }, []);

  return (
    <Fragment>
      <h1>Dynamic player config demo</h1>
      <BitmovinPlayer config={playerConfig} source={playerSource} />
    </Fragment>
  );
}

The same applies to the customUi object.

Attach event listeners

import { PlayerConfig, PlayerEvent } from "bitmovin-player";

export function MyComponent() {
  const playerConfig: PlayerConfig = {
    key: "<key>",
    playback: {
      muted: true,
      autoplay: true,
    },
    events: {
      [PlayerEvent.Play]: (event) => {
        console.log("Play event fired", event);
      },
    },
  };

  return (
    <Fragment>
      <h1>Events demo</h1>
      <BitmovinPlayer config={playerConfig} source={playerSource} />
    </Fragment>
  );
}

Get player instance

import { PlayerAPI } from "bitmovin-player";

export function MyComponent() {
  const handlePlayerRef = (player: PlayerAPI) => {
    console.log("Player version", player.version);
  };

  return (
    <Fragment>
      <h1>Player instance demo</h1>
      <BitmovinPlayer
        playerRef={handlePlayerRef}
        config={playerConfig}
        source={playerSource}
      />
    </Fragment>
  );
}

Customize player UI

Use UI container

You can use UIContainer from https://www.npmjs.com/package/bitmovin-player-ui to customize the player UI:

import { PlaybackToggleOverlay, UIContainer, CustomUi } from "bitmovin-player-ui";

// Ensure this function returns a new instance of the `UIContainer` on every call.
const uiContainerFactory = () =>
  new UIContainer({
    components: [new PlaybackToggleOverlay()],
  });

const customUi: CustomUi = {
  containerFactory: uiContainerFactory
};

export function MyComponent() {
  return (
    <Fragment>
      <h1>UI container demo</h1>
      <BitmovinPlayer
        source={playerSource}
        config={playerConfig}
        customUi={customUi}
      />
    </Fragment>
  );
}

Use UI variants

You can use UIVariants from https://www.npmjs.com/package/bitmovin-player-ui to customize the player UI:

import { UIVariant, CustomUi } from "bitmovin-player-ui";

// Ensure this function returns a new instance of the `UIVariant[]` on every call.
const uiVariantsFactory = (): UIVariant[] => [
  {
    ui: new UIContainer({
      components: [
        new PlaybackToggleOverlay(),
        new ControlBar({
          components: [new SeekBar()],
          hidden: false,
        }),
      ],
    }),
    condition: (context) => context.isFullscreen,
  },
  {
    ui: new UIContainer({
      components: [new PlaybackToggleOverlay()],
    }),
    condition: (context) => !context.isFullscreen,
  },
];

const customUi: CustomUi = {
  variantsFactory: uiVariantsFactory
};

export function MyComponent() {
  return (
    <Fragment>
      <h1>UI variants demo</h1>
      <BitmovinPlayer
        source={playerSource}
        config={playerConfig}
        customUi={customUi}
      />
    </Fragment>
  );
}

Use custom CSS

You either can implement your own CSS for the default player UI or build on top of bitmovin-player-ui/dist/css/bitmovinplayer-ui.css.

Create a new CSS file:

/* customStyles.css */

.bmpui-ui-playbacktimelabel {
  color: red;
}

Import the CSS file:

import "./customStyles.css";

export function MyComponent() {
  return (
    <Fragment>
      <h1>Custom CSS demo</h1>
      <BitmovinPlayer source={playerSource} config={playerConfig} />
    </Fragment>
  );
}

Disable UI

import { PlayerConfig } from "bitmovin-player";

const playerConfig: PlayerConfig = {
  key: "<key>",
  playback: {
    muted: true,
    autoplay: true,
  },
  // Disable UI
  ui: false,
};

export function MyComponent() {
  return (
    <Fragment>
      <h1>Disable UI demo</h1>
      <BitmovinPlayer
        source={playerSource}
        config={playerConfig}
      />
    </Fragment>
  );
}

Possible pitfalls

Avoid player config, UI config, and source objects recreation on every render

export function MyComponent() {
  const [_counter, setCounter] = useState(0);

  // This will create a new source object on every render and the player will be reloaded unnecessarily.
  const playerSource: SourceConfig = {
    hls: "https://cdn.bitmovin.com/content/assets/streams-sample-video/sintel/m3u8/index.m3u8",
  };

  useEffect(() => {
    const intervalId = setInterval(() => {
      setCounter((previousCounter) => previousCounter + 1);
    }, 500);

    return () => clearInterval(intervalId);
  }, []);

  return (
    <Fragment>
      <h1>Wrong source usage demo</h1>
      <BitmovinPlayer config={playerConfig} source={playerSource} />
    </Fragment>
  );
}

Instead do one of the following:

  • Create a source object outside of the component (refer to the "Simple demo" above)
  • Use useState (refer to the "Dynamic source demo" above)
  • Use useMemo:

The same applies to the config, source, and customUi objects.

export function MyComponent() {
  const [_counter, setCounter] = useState(0);

  // Ensure that the source object is created only once.
  const playerSource: SourceConfig = useMemo(
    () => ({
      hls: "https://cdn.bitmovin.com/content/assets/streams-sample-video/sintel/m3u8/index.m3u8",
    }),
    // Add dependencies here if needed to build the source object.
    [],
  );

  useEffect(() => {
    const intervalId = setInterval(() => {
      setCounter((previousCounter) => previousCounter + 1);
    }, 500);

    return () => clearInterval(intervalId);
  }, []);

  return (
    <Fragment>
      <h1>Right source usage demo</h1>
      <BitmovinPlayer config={playerConfig} source={playerSource} />
    </Fragment>
  );
}

Maintenance and Updates

As an open source project, this library is not part of a regular maintenance or update schedule and is updated on an adhoc basis when contributions are made.

Contributing to this project

We are pleased to accept changes, updates and fixes from the community wishing to use and expand this project. Bitmovin will review any Pull Requests made. We do our best to provide timely feedback, but please note that no SLAs apply. New releases are tagged and published on our discretion. Please see CONTRIBUTING.md for more details on how to contribute.

Raising a Feature Suggestion

If you see something missing that might be useful but are unable to contribute the feature yourself, please feel free to submit a feature request through the Bitmovin Community. Feature suggestions will be considered by Bitmovin’s Product team for future roadmap plans.

Reporting a bug

If you come across a bug related to the Bitmovin Player React, please raise this through the support ticketing system accessible in your Bitmovin Dashboard.

Support and SLA Disclaimer

As an open-source project and not a core product offering, any request, issue or query related to this project is excluded from any SLA and Support terms that a customer might have with either Bitmovin or another third-party service provider or Company contributing to this project. Any and all updates are purely at the contributor's discretion.

Need more help?

Should you need further help, please raise your request to your Bitmovin account team. We can assist in a number of ways, from providing you professional services help to putting you in touch with preferred system integrators who can work with you to achieve your goals.