0

In my Next.js app, I am trying to load video from AWS Cloudfront using signed cookies. I am using plyr player and this hls library. When I load video without Next.js (with native JS) then video plays properly but with Next.js it destroyed my player design and started giving me following error

Uncaught ReferenceError: n is not defined

enter image description here

The player design was not destroyed until I enable the withCredentials

let config = {
    xhrSetup: function (xhr) {
        xhr.withCredentials = true; // do send cookies
    },
};

const hls = new Hls(config);

Player Component

const Player4 = ({options}) => {

    const dispatch = useDispatch();

    const {activeChapter} = useSelector(state => state.product.viewData);

    const componentMountedRef = useRef(null);
    const activeChapterRef = useRef(null);
    const updateDurationIntervalRef = useRef(null);

    activeChapterRef.current = activeChapter;

    const updateQuality = newQuality => {
        window.hls.levels.forEach((level, levelIndex) => {
            if (level.height === newQuality) {
                window.hls.currentLevel = levelIndex;
            }
        });
    }

    const destroyHLS = () => {
        clearInterval(updateDurationIntervalRef.current);
        window.hls.stopLoad();
        window.hls.detachMedia();
        window.hls.destroy();
    };

    if (typeof window !== 'undefined') {
        window.destroyHLS = destroyHLS;
        const video = document.getElementById('player');

        //Player Events
        const playerEvents = () => {
            window.player.on('ready', event => {
                updateDurationIntervalRef.current = setInterval(function () {
                    if (!window.player.paused) {
                        dispatch(updateWatchedDuration(activeChapterRef.current?.id, window.player.currentTime));
                    }
                }, 4000);
            });

            window.player.on('emptied', event => {
                console.log('Player Emptied Called', componentMountedRef.current);
                if (componentMountedRef.current) {
                    updateDurationIntervalRef.current = setInterval(function () {
                        dispatch(updateWatchedDuration(activeChapterRef.current?.id, window.player.currentTime));
                    }, 4000);
                }
            });

            window.player.on('ended', event => {
                console.log('Player Ended Called', componentMountedRef.current);
                if (componentMountedRef.current) {
                    updateDurationIntervalRef.current = setInterval(function () {
                        dispatch(updateWatchedDuration(activeChapterRef.current?.id, window.player.currentTime));
                    }, 4000);
                }
            });

            window.player.on('loadedmetadata', event => {
                //alert('loadedmetadata');
                dispatch(updateWatchedDuration(activeChapterRef.current?.id, activeChapterRef.current?.watched_duration));
                window.player.poster = activeChapterRef.current?.thumbnail?.url;
                window.player.currentTime = activeChapterRef.current?.watched_duration;

                if (window.player.paused) {
                    window.player.play();
                }
            });
        }

        const defaultOptions = {
            debug: false,
        };

        if (!Hls.isSupported()) {

            if (video?.canPlayType('application/vnd.apple.mpegurl')) {
                video.src = options.source.src;
                const player = new Plyr(video, defaultOptions);
                window.player = player;
                playerEvents();
            }

        } else {

            if (window.hls) destroyHLS();

            let config = {
                xhrSetup: function (xhr) {
                    xhr.withCredentials = true; // do send cookies
                },
            };

            const hls = new Hls();
            hls.loadSource(options.source.src);

            hls.on(Hls.Events.MANIFEST_PARSED, function (event, data) {

                const availableQualities = hls.levels.map((l) => l.height);

                defaultOptions.quality = {
                    default: availableQualities[0],
                    options: availableQualities,
                    forced: true,
                    onChange: (e) => updateQuality(e),
                }

                const player = new Plyr(video, defaultOptions)
                window.player = player;

                playerEvents();

            });

            hls.on(Hls.Events.LEVEL_SWITCHED, function (event, data) {
                var span = document.querySelector(".plyr__menu__container [data-plyr='quality'][value='0'] span")
                if (hls.autoLevelEnabled) {
                    span.innerHTML = `AUTO (${hls.levels[data.level].height}p)`
                } else {
                    span.innerHTML = `AUTO`
                }
            })

            hls.attachMedia(video);
            window.hls = hls;
        }
    }

    //Unmount component
    useEffect(() => {

        componentMountedRef.current = true;

        return () => {
            if (window.hls) {
                componentMountedRef.current = false;
                window.destroyHLS();
            }
        }
    }, [])

    return (

        <video id="player" autoPlay playsInline controls/>
    );
};

export default Player4;
juliomalves
  • 42,130
  • 20
  • 150
  • 146
fahad shaikh
  • 593
  • 1
  • 14
  • 29
  • Looks like the issue arises due to server-side rendering. Have you tried dynamically importing your `Player4` component on the client only with [`next/dynamic`](https://nextjs.org/docs/advanced-features/dynamic-import#with-no-ssr) and `{ ssr: false }` wherever you use it? – juliomalves Jul 12 '22 at 18:18
  • @juliomalves I tried it but didn't help – fahad shaikh Jul 13 '22 at 19:45

0 Answers0