React-Shaka-Player
é um framework público em TypeScript para mídias adaptativas. Ele reproduz formatos de mídias adaptativas (como DASH e HLS) no browser, sem usar plugins ou Flash. Ao
invés, o React-Shaka-Player
usa a biblioteca JavaScript de código-aberto Shaka Player.
Nosso principal objetivo é facilitar, na medida do possível, a transmissão de bitrate videos e audios adaptativos usando as melhores propriedades e métodos que a biblioteca Shaka Player oferece. Nos esforçamos para manter o framework leve, simples e livre de outras dependencias. Tudo o que você precisa para construir seu código já está na fonte.
Para a instalação ser permitida, crie um arquivo .npmrc
na raiz do projeto.
📝 Arquivo .npmrc:
//npm.pkg.github.com/:_authToken=SEU_TOKEN_PESSOAL
@react-shaka-player:registry=https://npm.pkg.github.com
Em seguida, use o gerenciador de pacotes npm / yarn ou via package.json para instalar o react-shaka-player
.
🖥️ Instalação a partir de linha de comando:
yarn add react-shaka-player
ou
npm install react-shaka-player
📝 Instalação via package.json
"react-shaka-player": "x.x.x"
// import do css. Agora temos a estilização customizada do ui.css
// NextJs tem esse import de css no _app
import React, { useState, useEffect } from 'react';
import 'react-shaka-player/dist/ui.css';
import { ReactShakaPlayer } from 'react-shaka-player';
function App() {
const [mainPlayer, setMainPlayer] = useState(undefined);
const [adsRequest, setAdsRequest] = useState(undefined);
const [adBlock, setAdBlock] = useState(false);
useEffect(() => {
if (window.google) {
const ADS_CLASS = new google.ima.AdsRequest();
// Acesse o link para mais infos sobre o IMA SDK
// https://developers.google.com/interactive-media-ads/docs/sdks/html5/client-side/reference/js/google.ima.AdsRequest?hl=pt-br
setAdsRequest(ADS_CLASS);
setAdBlock(false);
return;
}
return setAdBlock(true);
}, []);
return !adsRequest || adBlock ? (
<Loader />
) : (
<ReactShakaPlayer adsRequest={adsRequest} adsTagUrl={'https://vid.ads.com/vmap'} superConfig="STREAMING" onLoad={(player) => setMainPlayer(player)} src={'https://yourvideo.mpd'} />
);
}
// import do css. Agora temos a estilização customizada do ui.css
// NextJs tem esse import de css no _app
import React, { useState, useEffect, useCallback } from 'react';
import 'react-shaka-player/dist/ui.css';
import { ReactShakaPlayer } from 'react-shaka-player';
function App() {
const [mainPlayer, setMainPlayer] = useState(undefined);
const [adsRequest, setAdsRequest] = useState(undefined);
const [adBlock, setAdBlock] = useState(false);
const [isLoading, setIsLoading] = useState(true)
const [showControls, setShowControls] = useState(true);
const [adsControls, setAdsControls] = useState(false);
const [muted, setMuted] = useState(false);
useEffect(() => {
if (window.google) {
const ADS_CLASS = new google.ima.AdsRequest();
// Acesse o link para mais infos sobre o IMA SDK
// https://developers.google.com/interactive-media-ads/docs/sdks/html5/client-side/reference/js/google.ima.AdsRequest?hl=pt-br
setAdsRequest(ADS_CLASS);
setAdBlock(false);
return;
}
return setAdBlock(true);
}, []);
useEffect(() => {
let time
if (!adsRequest) {
setIsLoading(true)
time = setInterval(() => {
setIsLoading(false)
}, 4000)
return () => clearInterval(time)
}
return setIsLoading(false)
}, [adsRequest])
const handleShakaControls = () => {
const element = document.getElementsByClassName('shaka-controls-container');
const controls = element?.item(0)?.hasAttribute('shown');
const adsControls = element?.item(0)?.hasAttribute('ad-active');
setShowControls(controls);
setAdsControls(adsControls);
};
const handleUnmute = useCallback(() => {
setMuted(false);
if (mainPlayer.videoElement) {
mainPlayer.videoElement.muted = false;
}
}, [mainPlayer]);
const handleFowardRewind = (label) => {
if (mainPlayer.videoElement && label === 'foward') {
mainPlayer.videoElement.currentTime = Math.floor(mainPlayer.videoElement.currentTime) + 10;
} else if (mainPlayer.videoElement && label === 'rewind') {
mainPlayer.videoElement.currentTime = Math.floor(mainPlayer.videoElement.currentTime) - 10;
}
};
return isLoading ? (
<PageLoader />
) : (
<div className="App">
<div className="App-main">
{!adsRequest || adBlock ? (
<CardContainer>
<CardTitleError>ops!</CardTitleError>
<CardDescriptionError>Desative seu bloqueador de anúncios para assistir o conteúdo.</CardDescriptionError>
<ButtonReload onClick={() => window.location.reload()}>
<Icon mt={6} color="neutral.n400" variant="reload" width={24} height={24} />
<span>tentar novamente</span>
</ButtonReload>
</CardContainer>
) : (
<ReactShakaPlayer
adsRequest={adsRequest}
adsTagUrl={'https://vid.ads.com/vast'}
superConfig="VOD"
src={'https://yourvideo.mpd'}
onTimeUpdate={handleShakaControls}
startTime={stopped_at ? stopped_at : 0}
onLoad={(player) => setMainPlayer(player)}
onFoward={!adsControls && showControls ? () => handleFowardRewind('foward') : null}
onRewind={!adsControls && showControls ? () => handleFowardRewind('rewind') : null}
unmute={muted ? { p: 'ativar som', onUnmute: () => handleUnmute() } : null}
autoPlay={true}
muted={true}
>
<ChildrenToIncludeIntoFullscreen>
</ReactPlayer>
)}
</div>
</div>
)
}
Library | DASH | HLS | WORKING |
---|---|---|---|
React | Y | Y | - |
React Native | - | - | Y |
Essas são as props principais do componente:
Props | Optional | Description | Type |
---|---|---|---|
src | Não | MPD ou HLS para reprodução. | string |
adsRequest | Sim | Responsável por receber AdsRequest do Google IMA SDK . Referência: Google IMA SDK. |
{google.ima.AdsRequest} => func |
adsTagUrl | Sim | Responsável por receber o assetUri com o conteúdo do Advertisement a ser reproduzido pelo adsRequest. | string |
className | Sim | string do nome de classe de sobreposição da interface do usuário. | string |
children | Sim | Qualquer item ou componente - comumente usado para controles externos aparecerem durante o fullscreen. | any |
startTime | Sim | Define onde o conteúdo deve começar a ser reproduzido. | number |
label | Sim | Define o espaço reservado para botões personalizados. | boolean |
autoplay | Sim | Define se o conteúdo iniciará automaticamente. | boolean |
muted | Sim | Define se o conteúdo iniciará com ou sem audio. | boolean |
superConfig | Sim | As configurações especiais para Streaming ou VOD. Iremos adicionar mais superConfig em breve. |
string ("STREAMING" / "VOD") |
config | Sim | Altera as configurações do Shaka Player. Referência: shaka.extern.PlayerConfiguration. Esta configuração substituirá superConfig . |
object: superConfig.player |
uiConfig | Sim | Altera as definições de configuração dos elementos da interface do usuário. Referência: shaka.extern.UIConfiguration. Esta configuração substituirá superConfig . |
object: superConfig.ui |
onLoad | Sim | Captura Shaka.Player , Shaka.ui.Overlay e HTMLVideoElement para o uso manual ou melhoria da configuração. Ver: PlayerRefs. |
object: PlayerRefs => func |
onClick | Sim | Captura clique em Events para os botões Ativar som, Avançar e Retroceder. Referência: OnClick Events. |
Event => func |
onBuffering | Sim | Captura o status onBuffering durante a reprodução. |
bool => func |
onPlayerError | Sim | Captura error durante a reprodução. Referência: Shaka.Player.ErrorEvent. |
{Shaka.extern.Error} => func |
onStatsChanged | Sim | Captura stats durante a reprodução do vídeo, incluindo currentTime (posição de busca atual) e currentEndTime (duração do vídeo se VOD) (em segundos) do elemento do reprodutor de mídia [IStats ]. Referência: IStats & Shaka.extern.Stats. |
{Shaka.extern.Stats} => func |
onTimeUpdate | Sim | Captura time durante a reprodução do vídeo. Normalmente usado para controlar o fade dos controles shaka. Referência: MDN Events. |
event => func |
onUiInteraction | Sim | Captura UI Interactions Events quando reproduzindo, pausado, fechando, procurando (seek), terminando o vídeo. Referência: MDN Events. |
event => func |
onFoward | Sim | Método responsável por mostrar o botão de avançar 10 segundo o conteúdo. | event => func |
onRewind | Sim | Método responsável por mostrar o botão de retroceder 10 segundo o conteúdo. | event => func |
unmute | Sim | Método responsável por mostrar o botão de desmutar o conteúdo. | object: {p: string onUnmute: func} |
withPostMessage | Sim | Define se a UIListener enviará eventos via postMessage ou não. | boolean |
- Shaka Repository
- Shaka Demo
- Shaka API documentation
- Shaka Tutorials
- Shaka CSS - ClassNames
- Google IMA SDK
- Problemas e Bugs Issues
Pull requests são bem vindos. Para mudanças mais complexas, por gentileza abra uma issue primeiro para discutirmos a melhor forma de realizar a alteração.
Por gentileza, garanta que as mudanças sejam acompanhadas de testes apropriadamente.
Se for necessária a mudança direta de uma estilização, ou o não uso das props superConfig
, pode-se conferir todas as classes** que usamos de forma resumida no arquivo
CSS-Classes. Basta copiar o conteúdo e colar no .css do projeto a ser usado.
**podem haver mais
Observação: Pretendemos comentar cada classe para fácil identificação de suas responsabilidades!
- Guilherme Silva Oliveira
- PIX: 10411373625