Can't render custom UI

Hi!

I’m trying to render custom UI using ui: false flag in player configuration + initializing new UIManager with my custom UIContainer. However it doesn’t completely work as expected. Default UI is gone indeed, however another UI does not appear on the screen, despite that part of that UI appears in page structure. Would appreciate any advise…

Here’s some samples:

if (!playerRef.current) {
      playerRef.current = new Player(playerContainerRef.current, conf);

      if (!uiManagerRef.current) {
        const uiConfig = {
          metadata: {
            title: product.title,
            description: product.description,
          }
        }

        uiManagerRef.current = new UIManager(
          playerRef.current,
          playerBitmovinUi({
            onForwardClick: () => {
              smtpeControllerRef.current?.step(1)
            },
            onRewindClick: () => {
              smtpeControllerRef.current?.step(-1)
            }
          }),
          uiConfig)

        console.debug('uiManager', uiManagerRef.current)
      }
const playerBitmovinUi = ({
  onForwardClick,
  onRewindClick
}: PlayerBitmovinUiProps) => {

  const buildNavigationButton = (buttonText: string, onClickHandler?: () => void): Button<ButtonConfig> => {
    const navigationButton = new Button({ text: UIManager.localize(buttonText) })
    navigationButton.onClick.subscribe((event: any) => {
      onClickHandler?.()
    })

    return navigationButton
  }

  const forwardButton = buildNavigationButton('Next frame', onForwardClick)
  const rewindButton = buildNavigationButton('Previous frame', onRewindClick)
  const shareFrameButton = buildNavigationButton('Share this frame', () => { toast('Clicked on share frame...') })
  const addToFavouritesButton = buildNavigationButton('Add to Favourites', () => { toast('Clicked on Add...') })
  const advancedOptionsButton = buildNavigationButton('Advanced Options', () => { toast('Clicked on Options...') })

  return new UIContainer({
    id: 'ui-root',
    components: [
      new PlaybackToggleOverlay(),
      new ControlBar({
        components: [
          new Container({
            components: [
              new SeekBar({
                label: new SeekBarLabel(),
                enableSeekPreview: false
              }),
            ],
            cssClasses: ['controlbar-top'],
          }),
        ],
      }),
      new ControlBar({
        id: 'pause-navigation',
        cssClasses: ['controlbar-bottom'],
        components: [
          new Container({
            id: 'container-left',
            role: 'button',
            ariaLabel: 'previous frame',
            components: [
              new Component({
                id: 'arrow-left',
                tag: 'div',
                cssClass: 'icon-arrow-left'
              }),
              rewindButton as Button<ButtonConfig>
            ]
          }),
          new Container({
            id: 'container-center-button',
            components: [
              shareFrameButton,
              addToFavouritesButton,
              advancedOptionsButton
            ]
          }),
          new Container({
            id: 'container-right',
            role: 'button',
            ariaLabel: 'next frame',
            components: [
              forwardButton as Button<ButtonConfig>,
              new Component({
                tag: 'div',
                cssClass: 'icon-arrow-right'
              }),
            ]
          }),
        ]
      })
    ],
    hideDelay: 1000
  })
}

hello Niakros,

thanks for posting your question. In order to start with the troubleshooting, I’d like to confirm with you if you have been able to follow the instructions from the Bitmovin Custom UI repository? GitHub - bitmovin/bitmovin-player-ui: The Bitmovin Adaptive Streaming Player UI

thanks for sharing your code, UIManager creation looks correct. Have you tried testing for example creating only one controlbar object?
I am particularly interested on the controlbar creation, please have a look at this example, where a controlbar-top and -bottom are created as 2 containers inside the same controlbar object: bitmovin-player-web-samples/customForwardRewindButtons.html at main · bitmovin/bitmovin-player-web-samples · GitHub

Could you for example try disabling one of your controlbar objects (remove temporarily your controlbar bottom) does it make any difference? is the rest of the UI rendered?

these other examples of custom UIs might be useful as well: bitmovin-player-web-samples/playerUi/tv at main · bitmovin/bitmovin-player-web-samples · GitHub

looking forward to your response

Hi ! Thanks for the response!

First of all - I want to mention that I make the UI appear if I set ui: true in the PlayerConfig, which makes default UI to not be rendered with the following warning BUT! then my custom UI appears on the screen:

Could not load UI TypeError: Cannot create property 'metadata' on boolean 'true'
    at new e (bitmovinplayer-ui.js:19:7026)
    at Object.ae [as buildModernUI] (bitmovinplayer-ui.js:19:634)
    at Object.t [as buildDefaultUI] (bitmovinplayer-ui.js:18:26371)
    at e.createUI (bitmovinplayer.js?97d2:11:2039699)
    at eval (bitmovinplayer.js?97d2:11:2039509)

However on next component render cycle that warning becomes error which crashes my app while it’s unhandled.

Regarding the guide in official repo - yes, it was the place where I learnt how to add custom UI.
Now to your suggestion - I disabled controllbar with my custom buttons but nothing changed, ui still is not shown, however, it appear in page structure:

Also, interesting behavior: I’m working with next-js (not sure if that matters), and like other react apps it supports hot reload. So, if I follow these steps, then my UI appear until I reload the page:

  1. Open page with ui: false. UI didn’t appeared.
  2. Remove UI property from PlayerConfig and trigger hot reload: component re-rendered and two UI appeared: default one + custom
  3. Bring ui: false back into PlayerConfig and trigger reload: component re-rendered and only custom UI appeared.
    Hope that helps to understand the possible issue, while I’m quite out of ideas

thanks for your reply Niakros,

To summarise what you share:

  • If you set ui:true while loading the custom UI, you receive a warning, however if you do this while implementing on Next.JS this becomes an error.

  • as a separate finding: If you apply changes on your player config and save+ hot reload , you don’t see the applied changes until the second attempt of hot reload (that involves re-setting the previous changes).

These 2 issues sound to me very related with the implementation of your application on Next.js.

For the first issue, have you checked if you are using React StrictMode?. However since ui:false is the recommendation when using an external custom UI, I would not encourage investing much more time on figuring this option out.

For the second finding, hmm its hard to point out why this would happen. If you build this and run it , does it also fail to load the desired UI?

is there a chance you can share this example with us? we would like to take a deeper look.
thanks!

-Thomas

Hi!

Correction:

The app is allways running on next js. First time the page is loaded (first component render) - I recieve warning. next component render - it appeared as error.

Both hot reload have changes. first time both UI appear, second time only custom ui appear. Both behaviors are undrestodable except the fact that regular component render (triggered by page reload) fails to load UI but render triggereded but hot-reload can do this.

yes, we were by default in strict mode, but I also tried to disable it, no change

No difference with dev env

I asked the product owner and I will reach back to you as soon as Ill get his answer.

Best regards!

Just got green light to add you to the repo so you could see the issue itself. If you can dm me your email would be nice.

Thanks Kirill, I just sent you a DM.

hello Kirill,

I am back from holiday and very happy to see you were able to solve your issue.
For completeness of this thread, I am adding the solution here. Please feel free to add anything else to consider necessary.

The issue was solved by adding the location configuration for css and js files of the custom UI:

  location: {
    ui: '//domain.tld/path/to/bitmovinplayer-ui.js',
    ui_css: 'styles/bitmovinplayer-ui.css',
  },

we are confirming with our engineering team wether this configuration should become mandatory and the documentation on our GH repo should be updated.

thanks

-Thomas

This topic was automatically closed 60 minutes after the last reply. New replies are no longer allowed.