Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

HLS ready to use component #688

Closed
realamirhe opened this issue Nov 15, 2021 · 17 comments
Closed

HLS ready to use component #688

realamirhe opened this issue Nov 15, 2021 · 17 comments
Labels
enhancement New feature or request feature_request help wanted Extra attention is needed

Comments

@realamirhe
Copy link
Collaborator

I'm not that player expert but being it seems that HLS player is so popular among the community,

In this way we've some known mentioned issues we will try to fix, but don't hesitate to add you add your need or special use cases.

up-vote this issue (comment) if you see it helpful for your project?

@realamirhe realamirhe pinned this issue Nov 15, 2021
@realamirhe realamirhe added enhancement New feature or request feature_request help wanted Extra attention is needed labels Nov 15, 2021
@ShivamJoker
Copy link

ShivamJoker commented Feb 25, 2022

Any updates on this?
Is it implemented?

@realamirhe
Copy link
Collaborator Author

Hi @ShivamJoker,
The concern is that HLS integration need some extra attention about the package selection,
It also needs a basic understanding of HTTP Live Streaming.

We are thinking about the ecosystem of integratabtle/composable player, But I think we got over thinking about the mechanism which prevent us from further progress.
Soon I will try to implement a simple wrapper around the hls.js but hope to get peoples feedback.

@realamirhe
Copy link
Collaborator Author

realamirhe commented Mar 23, 2022

Dear everyone, (@ShivamJoker, @vhfmag, @sessgreem, @marcelfahle and @chintan9)

I got some time to work on HLS video player, I put some efforts to make it more reusable, more handy and specifically more reliable.

  • Get rid of old node-sass package and use the newly maintained dart-sass package

Good news if you want to help us with your PRS

  • Implement a ready to use quality changer useHls hook

It is production ready hook just use it once :)
It can be used as a base structure for any future progress on hls integration side.

  • Remove extra over head for the old prop-types package

Although it reduce our and your bundle size, but keeps your eye on change log, cause it is breaking change.

  • Move to newer version of node.

Now minimum node version required for development is 14 and minimum version is 8
although it might not effect the users but makes the path toward Pure-ESM packages easier.

Custom HLS player

Updates are scoped in the dev branch and all changes are documented and explained so would be pleasure if you could test and give us feedback.

As these point we also really appreciate if you want to help in our infrastructure core.
writing more test, configuring more robust build flow, improve DX with more strict typescript config, reduce the bundle size with your amazing solutions.

Hope to see you all, and happy Nowruz.

@krmgumus
Copy link

Which version should we install to use it?
I install "plyr-react": "^4.0.0-alpha.1" with yarn but video don't get

@realamirhe
Copy link
Collaborator Author

Hey @Kerotobil, it is not published in npm yet
You can use github as an npm registry till we get it published.

yarn add "https://github.com/chintan9/plyr-react.git#release"

More info on installation process, stackoverflow

@krmgumus
Copy link

import { usePlyr, APITypes, PlyrProps, PlyrOptions } from 'plyr-react';
import 'plyr-react/dist/plyr.css';
import Hls from 'hls.js';
import React, { useEffect, useRef, useState } from 'react';

const videoOptions = null;
const videoSource = null;
const hlsSource = 'https://content.jwplatform.com/manifests/vM7nH0Kl.m3u8';

const useHls = (src: string, options: PlyrOptions | null) => {
  const hls = useRef<Hls>(null);
  const hasQuality = useRef<boolean>(false);
  const [plyrOptions, setPlyrOptions] = useState<PlyrOptions | null>(options);

  useEffect(() => {
    hasQuality.current = false;
  }, [options]);

  useEffect(() => {
    hls.current?.loadSource(src);
    // NOTE: although it is more reactive to use the ref, but it seems that plyr wants to use the old as lazy process
    hls.current?.attachMedia(document.querySelector('.plyr-react')!);
    /**
     * You can all your custom event listener here
     * For this example we iterate over the qualities and pass them to plyr player
     * ref.current.plyr.play() ❌
     * console.log.bind(console, 'MANIFEST_PARSED') ✅
     * NOTE: you can only start play the audio here
     * Uncaught (in promise) DOMException: play() failed because the user didn't interact with the document first.
     */
    
      
      hls.current?.on(Hls.Events.MANIFEST_PARSED, () => {
      if (hasQuality.current) return; // early quit if already set
      //@ts-ignore
      const levels = hls.current.levels;
      const quality: PlyrOptions['quality'] = {
        default: levels[levels.length - 1].height,
        options: levels.map((level) => level.height),
        forced: true,
        onChange: (newQuality: number) => {
          console.log('changes', newQuality);
          levels.forEach((level, levelIndex) => {
            if (level.height === newQuality) {
              //@ts-ignore
              hls.current.currentLevel = levelIndex;
            }
          });
        },
      };
      setPlyrOptions({ ...plyrOptions, quality });
      hasQuality.current = true;
    });
  });

  return { options: plyrOptions };
};

const CustomPlyrInstance = React.forwardRef<APITypes, PlyrProps & { hlsSource: string }>((props, ref) => {
  const { source, options = null, hlsSource } = props;
  const raptorRef = usePlyr(ref, {
    ...useHls(hlsSource, options),
    source,
  }) as React.MutableRefObject<HTMLVideoElement>;
  return <video ref={raptorRef} className="plyr-react plyr" />;
});

export const PlyrComp = () => {
  const ref = useRef<APITypes>(null);
  //const supported = Hls?.isSupported();

  return (
    <div className="wrapper">
      {true ? (
        <CustomPlyrInstance ref={ref} source={undefined} options={undefined} hlsSource={hlsSource} />
      ) : (
        'HLS is not supported in your browser'
      )}
    </div>
  );
};

Yes i installed with yarn add "https://github.com/chintan9/plyr-react.git#release" , but video don't getting.
I want playing hls file and get quality options in player. Where am i doing wrong?

@realamirhe
Copy link
Collaborator Author

Hey @Kerotobil, you nearly scared me to death 😂

It seems that you forgot to pass the HLS instance to useRef

- const hls = useRef<Hls>(nuull);
+ const hls = useRef<Hls>(new Hls());

Also you can now remove those @ts-ignore

@krmgumus
Copy link

Yes, actually I tried every form, but I always get a different error.

TypeError: hls_js__WEBPACK_IMPORTED_MODULE_3___default(...) is not a constructor.

Screen Shot 2022-03-24 at 20 48 31

@realamirhe
Copy link
Collaborator Author

Which version of hls.js do you have in your package.json? @Kerotobil

@krmgumus
Copy link

"hls.js": "^1.1.5"

@realamirhe
Copy link
Collaborator Author

realamirhe commented Mar 24, 2022

I made a codesandbox, but cause I need the latest version of plyr-react and codesandbox tried to load it from other registry, you will see duplication for the plyr-react itself.

I'm pretty sure the problem might be in the installation phase or our packaging side.
could you check your local environment with the following sandbox @Kerotobil

https://codesandbox.io/s/wild-field-tp14zg?file=/src/plyr-react.tsx:140-144

@krmgumus
Copy link

Yes, looks fine. But my webpack error persists, I'm trying to solve it. It may be due to a different plugin in the project. I'll post again when I'm done. Thanks

@realamirhe
Copy link
Collaborator Author

Yes, looks fine. But my webpack error persists, I'm trying to solve it. It may be due to a different plugin in the project. I'll post again when I'm done. Thanks

Looking forward to hearing from you.
We changed one of our dependencies, make sure you can find the react-aptor in your node_modules directory.

@chintan9
Copy link
Owner

chintan9 commented May 2, 2022

@chintan9 chintan9 closed this as completed May 2, 2022
@chintan9 chintan9 unpinned this issue Jun 2, 2022
@iDVB
Copy link

iDVB commented Mar 6, 2023

@chintan9 Just about to think about implementing this module into our lib, but curious why it seems v5 broke support that was in v4? We're getting the same error as @Kerotobil in v5.

@towfiqi
Copy link

towfiqi commented Jul 17, 2023

There are few issues with the Custom HLS player.

  1. It does not work with multiple videos. Although the hls content are loaded for all the videos. But only the player for the first video is loaded. I tried giving the video elements unique ids. But that did not solve the issue. https://haste.zneix.eu/uvodarezun.typescript

  2. The second issue is, since all the hls content are loaded at once, lots of data are loaded which uses lots of bandwidth. Setting preload none does not do anything obviously. The hls.loadSource() loading half of all the videos. Maybe it should be replaced with a custom hls loader: https://github.com/video-dev/hls.js/blob/master/docs/API.md#creating-a-custom-loader

@realamirhe
Copy link
Collaborator Author

@towfiqi , You can pass key={id} to re-redner the component you need.
There was a known issue with the Plyr package about changing video content on the fly!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request feature_request help wanted Extra attention is needed
Projects
None yet
Development

No branches or pull requests

6 participants