O ApsaraVideo Live oferece suporte a co-streaming na web. Um espectador pode se tornar um co-streamer para interagir com o streamer em páginas web, eliminando a necessidade de instalar aplicativos adicionais. Este tópico descreve como implementar co-streaming na web e fornece código de exemplo relevante.
Visão geral da implementação de co-streaming
O Push SDK implementa co-streaming com base no ApsaraVideo Real-time Communication (ARTC). Isso ajuda os usuários a iniciar transmissões interativas que engajam mais pessoas com latência ultrabaixa.
Antes do co-streaming: O streamer usa uma URL de ingestão para co-streaming baseado em ARTC para ingerir um stream, e o espectador extrai o stream do CDN.
Durante o co-streaming: O espectador se torna um co-streamer. O co-streamer usa uma URL de ingestão para co-streaming baseado em ARTC para ingerir um stream e usa uma URL de streaming para co-streaming baseado em ARTC para extrair o stream do streamer com latência ultrabaixa. O streamer usa uma URL de streaming para co-streaming baseado em ARTC para extrair o stream do co-streamer com latência ultrabaixa.
Após o co-streaming: O co-streamer se torna um espectador comum. A ingestão e extração de stream baseadas em ARTC pelo espectador são interrompidas. O espectador extrai o stream do CDN novamente.
Notas de uso
No modo de co-streaming, o streamer e o co-streamer podem usar apenas o objeto AlivcLivePlayer para reproduzir o stream um do outro. O objeto AlivcLivePlayer suporta apenas streams cuja URL começa com
artc://live.aliyun.com/play/.A seção a seguir descreve como usar o recurso de co-streaming na web. Para mais informações sobre como integrar o SDK de co-streaming para web, consulte Integrar o SDK de co-streaming para web.
ImportanteUma atualização do SDK de co-streaming para web foi lançada em 15 de março de 2024, permitindo que o SDK seja compatível com a nova versão do Google Chrome. Os usuários que estão usando o SDK antigo precisam atualizar o SDK o mais rápido possível para evitar problemas de disponibilidade. Para mais informações sobre como integrar a versão mais recente do SDK, consulte Integrar o SDK de co-streaming para web.
Etapa 1: Ativar o recurso de co-streaming
Para usar o recurso de co-streaming, crie um aplicativo de co-streaming e configure o domínio de streaming dos espectadores. Para mais informações, consulte Início rápido para co-streaming.
Etapa 2: Gerar URLs de ingestão e streaming para co-streaming
Gere URLs de ingestão e streaming do streamer e do co-streamer e a URL de streaming CDN dos espectadores usando o console do ApsaraVideo Live, ou construa essas URLs usando as regras de concatenação.
Método 1: Gerar as URLs usando o console
Use o gerador de URL no console do ApsaraVideo Live para gerar as URLs de ingestão e streaming do streamer e do co-streamer e a URL de streaming CDN dos espectadores. Para mais informações, consulte Gerador de URL de co-streaming.
Método 2: Construir as URLs
Os tokens nas URLs de ingestão e streaming do streamer e do co-streamer geradas pelo console são temporários e geralmente usados para testes. Se você precisar de URLs de ingestão e streaming para fins comerciais, construa as URLs usando as regras de concatenação por razões de segurança. Os tokens nas URLs que você constrói usando as regras de concatenação são calculados com base no SdkAppID, AppKey, ID da sala, UserID e timestamp usando o algoritmo de criptografia SHA-256. Esses tokens oferecem maior segurança. Para mais informações, consulte URLs de ingestão e streaming de streamers e co-streamers em cenários de co-streaming e URLs de streaming CDN de espectadores.
Etapa 3: Criar objetos relacionados à ingestão de stream
Esta etapa é necessária tanto no lado do streamer quanto no lado do co-streamer.
Criar um objeto AlivcLivePusher
Crie um objeto AlivcLivePusher como instância de ingestão de stream e configure os callbacks relevantes.
const pusher = new window.AlivcLivePush.AlivcLivePusher();
await pusher.init({
resolution: window.AlivcLivePush.AlivcResolutionEnum.RESOLUTION_540P,
fps: window.AlivcLivePush.AlivcFpsEnum.FPS_30,
// audioOnly: true, Only for scenarios in which audio-only streams are ingested.
});
pusher.info.on('pushstatistics', _stat => {
// TODO... Process stream ingest statistics data.
// console.log(_stat);
});
pusher.error.on('system', error => {
console.log(error);
});
pusher.network.on('connectionlost', () => {
console.log('connectionlost');
});
Iniciar ingestão de stream no modo de co-streaming
Use uma URL de ingestão para co-streaming para ingerir um stream.
await pusher.startPreview(videoElement);
await pusher.startPush("artc://live.aliyun.com/push/6375?timestamp=1661596947&token=XXX&userId=7135&sdkAppId=XXX"); // The ingest URL of the streamer or co-streamer.Tanto startPreview quanto startPush são métodos assíncronos. Para garantir a ordem das chamadas, use a palavra-chave await ou um objeto Promise.
Para implementar co-streaming entre um cliente nativo no Android ou iOS e a web, o modo de compatibilidade HTML5 deve ser ativado no cliente nativo. Caso contrário, os usuários na web verão uma tela preta enviada pelos usuários no cliente nativo. Para ativar o modo de compatibilidade HTML5, chame AlivcLivePushConfig#setH5CompatibleMode no cliente nativo. Para mais informações, consulte a referência de API do SDK nativo.
Etapa 4: Criar um objeto AliPlayer para reprodução via CDN
Esta etapa é necessária no lado do espectador.
Para usar um objeto AliPlayer para reprodução via CDN, obtenha primeiro a URL de streaming CDN dos espectadores. Para mais informações, consulte Etapa 2: Gerar URLs de ingestão e streaming para co-streaming.
Recomendamos usar uma URL de streaming no formato HTTP-FLV em vez de uma URL de streaming no protocolo RTMP (Real-Time Messaging Protocol). Ao usar o console do ApsaraVideo Live para gerar URLs, são geradas URLs nos formatos RTMP e HTTP-FLV. Uma URL no formato RTMP e uma URL no formato HTTP-FLV contêm o mesmo conteúdo de dados, mas usam protocolos diferentes. HTTP é o protocolo principal para transmissão de informações pela Internet. As conexões pelo protocolo HTTP, como as conexões entre o Alibaba Cloud CDN, provedores de serviços de Internet (ISPs) e dispositivos intermediários, são altamente otimizadas. A porta padrão do protocolo HTTP é 80 e a porta padrão do protocolo HTTPS é 443. Na maioria dos casos, as portas são adicionadas à lista de permissões e não podem ser desativadas. RTMP é um protocolo desatualizado e usa 1935 como porta padrão. A porta 1935 pode ser bloqueada pelo firewall, o que pode causar erros. Comparado com RTMP, o HTTP-FLV é mais estável e oferece melhor desempenho. Por exemplo, a reprodução de vídeo via HTTP-FLV tem uma taxa de interrupção menor e menor latência do que o RTMP.
const player = new window.Aliplayer(
{
id: videoId, // video element ID
source: url, // The streaming URL, which can be a third-party streaming URL or a streaming URL from ApsaraVideo Live.
isLive: true, // Specify whether the content that you want to play is a live stream.
},
function (player: any) {
console.log('The player is created.', player);
}
);Etapa 5: Iniciar o co-streaming
Streamer A ingere um stream baseado em ARTC
O Streamer A usa o objeto AlivcLivePusher para iniciar a ingestão de stream. Código de exemplo:
await pusher.startPreview(videoElement); // You can use methods of the Document interface (such as getElementById) to obtain the videoElement object.
await pusher.startPush("artc://live.aliyun.com/push/6375?timestamp=1661596947&token=XXX&userId=7135&sdkAppId=XXX"); // The ingest URL of the streamer or co-streamer.Os espectadores usam uma URL de streaming CDN para reproduzir o stream do Streamer A
Todos os espectadores usam o objeto AliPlayer para reproduzir o stream do Streamer A. Código de exemplo:
const player = new window.Aliplayer(
{
id: videoId, // video element ID
source: 'rtmp://test.alivecdn.com/live/streamId?auth_key=XXX', // The streaming URL, which can be a third-party streaming URL or a streaming URL from ApsaraVideo Live.
isLive: true, // Specify whether the content that you want to play is a live stream.
},
function (player: any) {
console.log('The player is created.', player);
}
);O Espectador D inicia o co-streaming
O Espectador D cria um objeto AlivcLivePusher e usa uma URL de ingestão para co-streaming para ingerir um stream. Nesse caso, o Espectador D se torna um co-streamer. Código de exemplo:
const pusher = new window.AlivcLivePush.AlivcLivePusher(); pusher.init({ resolution: window.AlivcLivePush.AlivcResolutionEnum.RESOLUTION_540P, fps: window.AlivcLivePush.AlivcFpsEnum.FPS_30, // audioOnly: true, Only for scenarios in which audio-only streams are ingested. }); pusher.info.on('pushstatistics', _stat => { // TODO... Process stream ingest statistics data. // console.log(_stat); }); pusher.error.on('system', error => { console.log(error); }); pusher.network.on('connectionlost', () => { console.log('connectionlost'); }); await pusher.startPreview(videoElement); // You can use methods of the Document interface (such as getElementById) to obtain the videoElement object. await pusher.startPush("artc://live.aliyun.com/push/6375?timestamp=1661596947&token=XXX&userId=7135&sdkAppId=XXX"); // The ingest URL of the streamer or co-streamer.O Streamer A obtém a URL de streaming para co-streaming do Co-streamer D e cria um objeto AlivcLivePlayer para extrair o stream do Co-streamer D em tempo real. Código de exemplo:
const player = new window.AlivcLivePush.AlivcLivePlayer(); // Specify the streaming URL of Co-streamer D, which starts with artc://. const playInfo = await player.startPlay("artc://live.aliyun.com/play/6375?timestamp=1661596947&token=XXX&userId=7135&sdkAppId=XXX", videoElement); playInfo.on('userleft', () => { // Handle the event that is triggered when Co-streamer D leaves the room. }); playInfo.on('canplay', () => { // Handle the event that is triggered when the video is available for playback. }Ao mesmo tempo, o Co-streamer D obtém a URL de streaming para co-streaming do Streamer A e cria um objeto AlivcLivePlayer para extrair o stream do Streamer A em tempo real. Código de exemplo:
const player = new window.AlivcLivePush.AlivcLivePlayer(); // Specify the streaming URL of Streamer A, which starts with artc://. const playInfo = await player.startPlay("artc://live.aliyun.com/play/6375?timestamp=1661596947&token=XXX&userId=7135&sdkAppId=XXX", videoElement); playInfo.on('userleft', () => { // Handle the event that is triggered when Streamer A leaves the room. }); playInfo.on('canplay', () => { // Handle the event that is triggered when the video is available for playback. }
O Streamer A atualiza o stream misto após o co-streaming ser bem-sucedido
Para garantir que o Espectador B e o Espectador C (que não são co-streamers) possam assistir ao stream do Co-streamer D, o Streamer A deve realizar a operação de mixagem de streams. Dessa forma, os streams do Streamer A e do Co-streamer D podem ser combinados em um único stream, que os espectadores podem extrair do CDN para reprodução.
Especificamente, o Streamer A chama o método setLiveMixTranscodingConfig para iniciar uma tarefa de transcodificação de stream misto e especificar os streams a serem misturados. Parâmetros como a resolução e a taxa de quadros do stream misto são aqueles que o Streamer A configurou no AlivcLivePushConfig ao criar o objeto AlivcLivePusher. Por exemplo, se o Streamer A definiu a resolução como 720p no AlivcLivePushConfig ao criar o objeto AlivcLivePusher, a resolução do stream misto é 720p.
const resolution = pusher.getResolution();
const width = window.AlivcLivePush.AlivcResolution.GetResolutionWidth(resolution);
const height = window.AlivcLivePush.AlivcResolution.GetResolutionHeight(resolution);
const mixStreams = [];
const transcodingConfig = new window.AlivcLivePush.AlivcLiveTranscodingConfig();
const anchorMixStream = new window.AlivcLivePush.AlivcLiveMixStream(
userA, // Specify the user ID of Streamer A.
0,
0,
width,
height,
1
);
// Add the stream of Streamer A for mixing.
mixStreams.push(anchorMixStream);
const audienceMixStream = new window.AlivcLivePush.AlivcLiveMixStream(
userD, // Specify the user ID of Co-streamer D.
100,
200,
200,
300,
2
);
// Add the stream of Co-streamer D for mixing.
mixStreams.push(audienceMixStream);
transcodingConfig.mixStreams = mixStreams;
await pusher.setLiveMixTranscodingConfig(transcodingConfig);Os espectadores podem assistir ao stream misto do Streamer A e do Co-streamer D.
O Co-streamer D encerra o co-streaming
Para interromper o co-streaming, o Co-streamer D deve chamar o método usado para parar a ingestão de stream no AlivcLivePusher e, em seguida, destruir o AlivcLivePusher. Código de exemplo:
await pusher.destroy(); pusher = null;Ao mesmo tempo, o Co-streamer D também deve chamar o método usado para parar a reprodução no AlivcLivePlayer e, em seguida, destruir o AlivcLivePlayer. Código de exemplo:
await player.destroy(); player = null;O Co-streamer D se torna um espectador comum e pode extrair o stream do CDN. Para mais informações, consulte Etapa 4: Criar um objeto AliPlayer para reprodução via CDN.
O Streamer A precisa chamar o método usado para parar a reprodução no AlivcLivePlayer e, em seguida, destruir o AlivcLivePlayer. Código de exemplo:
await player.destroy(); player = null;Ao mesmo tempo, o Streamer A precisa chamar o método setLiveMixTranscodingConfig e passar um valor vazio. Dessa forma, a mixagem de streams é interrompida. Observe que sempre que os espectadores desejam assistir apenas ao stream do Streamer A, o Streamer A pode realizar as operações anteriores para interromper a mixagem de streams.
AvisoSe o streamer ainda estiver na sala, mas não precisar de mixagem de streams, certifique-se de que a mixagem de streams seja interrompida. Se a mixagem de streams não for interrompida, o módulo de mixagem de streams que continua em execução gerará cobranças desnecessárias.
pusher.setLiveMixTranscodingConfig();