Skip to content
This repository has been archived by the owner on Oct 17, 2024. It is now read-only.

How do you add a simple video player with LightingJS & SolidJS #10

Open
samueleastdev opened this issue Feb 15, 2024 · 3 comments
Open

Comments

@samueleastdev
Copy link

Hi, i am reading through the docs here. https://github.com/Metrological/metrological-sdk/blob/master/docs/plugins/videoplayer.md

For the VideoPlayer plugin.

From what I understand the previous way to add a VideoPlayer was like this.

import {Lightning, VideoPlayer} from "@lightningjs/sdk";
import {RouterPage} from "./RouterPage"; // Defines isPage:true in the TypeConfig.
// @ts-ignore
import shaka from 'shaka-player';
import PlayPause from "../components/PlayPause";

export default class Player extends Lightning.Component<Lightning.Component.TemplateSpecLoose, RouterPage> {

    _player: shaka.Player

    static override _template(): Lightning.Component.Template<Lightning.Component.TemplateSpecLoose> {
        return {
            Wrapper: {
                alpha: 1,

                PlayPause: {
                    type: PlayPause,
                    i: 'playpause'
                }
            }
        }
    }

    override _firstActive() {
        VideoPlayer.consumer(this);
        VideoPlayer.loader(this._loadPlayback.bind(this));
        VideoPlayer.unloader(this._unloadPlayback.bind(this));
    }

    override _active() {
        VideoPlayer.open('https://demo.unified-streaming.com/k8s/features/stable/video/tears-of-steel/tears-of-steel.ism/.mpd')
    }

    override _getFocused(): Lightning.Component {
        return this.tag('PlayPause');
    }

    _setupShakaPlayer (videoEl: HTMLVideoElement) {
        videoEl.autoplay = true;
        this._player = new shaka.Player(videoEl);
    }

    async _loadPlayback (url: string, videoEl: HTMLVideoElement) {
        this._setupShakaPlayer(videoEl);

        await this._player.load(url);
    }

    async _unloadPlayback () {
        await this._player.unload();
    }

    override _handleEnter () {
        const button = this.tag('PlayPause');

        button.isPlaying = !button.isPlaying;
        button.isPlaying ? VideoPlayer.play() : VideoPlayer.pause();
    }
}

But this seem to have changed with the new setup with SolidJS. How can you setup a simple player with SolidJS? I know this is wrong as the video el is not outputted to the dom but what can you use in its place?

import Button from '../components/Button/Button';
import { Row } from '@lightningjs/solid-primitives';
import { VideoPlayer } from '@lightningjs/sdk'


const VideoPage = () => {
  function onEnter(event, elm) {
    this.states.toggle('disabled');

    // VideoPlayer.consumer(this);
    const videoUrl = 'http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4'

    const myLoader = (url, videoEl, config) => {
        console.log(url, videoEl, config);
        return new Promise(resolve => {
            videoEl.setAttribute('src', url)
            videoEl.load()
            resolve()
        })
    }

    VideoPlayer.loader(myLoader(videoUrl, document.querySelector("video")))
    VideoPlayer.size(960, 540)
    VideoPlayer.open(url)
  }

  const RowStyles = {
    display: 'flex',
    justifyContent: 'flexStart',
    width: 1500,
    height: 300,
    color: '00000000',
    gap: 26,
    y: 400,
    x: 100
  }

  return (
    <Row style={RowStyles}>
        <Button autofocus onEnter={onEnter}>Play Video</Button>
        <video></video>
    </Row>
  );
};

export default VideoPage;

Any info would be great.

@chiefcll
Copy link
Contributor

You can get the VideoElement quite easily via document.getElementById. videoEl in this example is a global reference to the video player object. If I had time I'd create a VideoPlayer component in SolidJS which would wrap commands to the video player tag on the page.

@samueleastdev
Copy link
Author

samueleastdev commented Feb 15, 2024

Ok I understand now lighting uses WebGL which doesnt use html you have to create a video element in the root and then overlay components over the top with LightingJS.

<!DOCTYPE html>
<html>
<head>
	<title>Solid App</title>
	<meta charset="UTF-8" />
	<style>
	html, body, * { padding: 0; margin: 0}
        canvas {
            position: absolute;
            z-index: 2;
        }
	</style>
</head>
<body>
    <video id="video" style="z-index: 0; position: absolute; top: 0; left: 0; width: 100%; height: 100%;"></video>
    <div id="app" style="background-color: transparent;"></div>
    <script type="module" src="./src/index.jsx"></script>
</body>
</html>

Shaka service

import shaka from 'shaka-player';

export class VideoPlayerService {
    constructor() {
        // Ensure Shaka Player is supported on the platform
        if (shaka.Player.isBrowserSupported()) {
            // Instantiate Shaka Player
            this.player = new shaka.Player(document.getElementById('video'));
            this.videoEl = document.getElementById('video');

            // Listen for errors
            this.player.addEventListener('error', this.onErrorEvent);
        } else {
            console.error('Browser not supported for Shaka Player!');
        }
    }

    onErrorEvent(event) {
        // Log or handle errors
        console.error('Error code', event.detail.code, 'object', event.detail);
    }

    // Method to load a video
    loadVideo(manifestUri) {
        this.player.load(manifestUri).catch(this.onErrorEvent);
    }

    play() {
        this.videoEl.play();
    }
}

Video Component

import Button from '../components/Button/Button';
import { Row } from '@lightningjs/solid-primitives';
import { VideoPlayerService } from '../components/Button/VideoPlayerService';


const VideoPage = () => {

    const videoPlayerService = new VideoPlayerService();
    videoPlayerService.loadVideo('https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4');


    function onEnter(event, elm) {
        this.states.toggle('disabled');
        videoPlayerService.play();
    }

    const RowStyles = {
        zIndex: 999,
        display: 'flex',
        justifyContent: 'flexStart',
        width: 1500,
        height: 300,
        color: '00000000',
        gap: 26,
        y: 400,
        x: 100
    }

  return (
    <Row style={RowStyles}>
        <Button autofocus onEnter={onEnter}>Play</Button>
    </Row>
  );
};

export default VideoPage;

Add the z-index for the video player and canvas element and then make the background of the Canvas transparent which I cant figure out how this is done.

From what I undertand you should use clearColor: 0x00000000, but dont know where to add this.

@chiefcll
Copy link
Contributor

Let me know if you figured this out - sorry for the late reply. Also if you have time to add to the project would love the video player to be built out further - and I think the canvas is clear by default. Just have to make sure all the elements on top are clear as well

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants