Mídia

Este guia apresenta uma visão geral dos formatos de vídeo e áudio suportados, descreve como controlar o áudio, obter informações sobre as câmaras Web e microfones disponíveis e outras funcionalidades.

Codecs

O Google Chrome e o Chromium diferem em vários aspectos, incluindo os conjuntos de codecs de áudio e vídeo que suportam.

A tabela abaixo mostra quais os codecs suportados pela base de código dos navegadores correspondentes.

  Chromium Google Chrome
AAC não sim
AV1 sim sim
FLAC sim sim
H.264 não sim
HEVC não sim
MP3 sim sim
Opus sim sim
Theora sim sim
Vorbis sim sim
VP8 sim sim
VP9 sim sim
WAV sim sim


Como pode ver na tabela acima, o Google Chrome suporta determinados codecs e o Chromium não. O motivo é porque estes codecs são proprietários e não podem ser utilizados num projeto de código aberto ou comercial sem a obtenção de licenças dos titulares das patentes correspondentes.

Diferentes codecs têm diferentes detentores de patentes. Por exemplo, para utilizar o H.264, as empresas devem adquirir a licença da empresa Via LA. Você pode ler mais sobre os termos da licença no site Web.

Codecs proprietários

Os detentores de patentes não licenciam codecs para o software que representa apenas uma parte do produto final implementado para os usuários finais, por exemplo, bibliotecas como o DotNetBrowser.

Para suportar H.264, HEVC e AAC nos seus produtos, é necessário adquirir as licenças adequadas e ativar as seguintes funcionalidades proprietárias:

engine = EngineFactory.Create(new EngineOptions.Builder
{
    RenderingMode = RenderingMode.HardwareAccelerated,
    ProprietaryFeatures = ProprietaryFeatures.H264 |
                          ProprietaryFeatures.Aac |
                          ProprietaryFeatures.Hevc
}.Build());
engine = EngineFactory.Create(New EngineOptions.Builder With 
{
    .RenderingMode = RenderingMode.HardwareAccelerated,
    .ProprietaryFeatures = ProprietaryFeatures.H264 Or
                           ProprietaryFeatures.Aac Or
                           ProprietaryFeatures.Hevc
}.Build())

Depois de fornecer as informações da licença e ativar as funcionalidades proprietárias, você pode carregar páginas Web com os formatos AAC, H.264 e HEVC reproduzir arquivos de áudio e vídeo, tal como no Google Chrome. Por padrão, os codecs proprietários estão desativados.

Os codecs H.264, HEVC e AAC são os componentes proprietários. Ao ativar estes codecs, o usuário declara ter conhecimento de que o H.264, HEVC e o AAC são componentes proprietários e que você deve ter uma licença para os utilizar. Para mais informações, pode contatar os titulares das patentes: Via Licensing e MPEG LA. A TeamDev não será responsável pela sua utilização dos codecs H.264, HEVC e AAC.

Vídeo

O DotNetBrowser suporta totalmente o elemento HTML5 <video> e pode reproduzir vídeo nos formatos suportados.

Se a biblioteca não puder reproduzir um vídeo, ou se um formato de vídeo não for suportado, o DotNetBrowser sugere o download do arquivo de vídeo. Para mais informações, consulte a seção Downloads que contém as instruções sobre como gerir os downloads.

Vídeo HTML5

Áudio

Controlando o áudio

Utilizando o IAudioController é possível saber se o áudio está sendo reproduzido na página Web carregada:

bool audioPlaying = browser.Audio.IsPlaying;
Dim audioPlaying As Boolean = browser.Audio.IsPlaying

Se necessário, você pode mutar ou desmutar o áudio na página Web carregada:

browser.Audio.Muted = true;
browser.Audio.Muted = false;
browser.Audio.Muted = True
browser.Audio.Muted = False

Para verificar se o áudio está silenciado, utilize o seguinte código:

bool audioMuted = browser.Audio.Muted;
Dim audioMuted As Boolean = browser.Audio.Muted

Eventos de áudio

Para saber se o áudio começou/parou de ser reproduzido na página Web carregada, você pode se inscrever nos seguintes eventos:

browser.Audio.AudioPlaybackStarted += (s, e) => { };
browser.Audio.AudioPlaybackStopped += (s, e) => { };
AddHandler browser.Audio.AudioPlaybackStarted, Sub(s, e)
End Sub
AddHandler browser.Audio.AudioPlaybackStopped, Sub(s, e)
End Sub

DRM

Widevine

Os serviços Web como Netflix ou Amazon Prime utilizam Widevine para distribuir os seus conteúdos codificados por DRM. O Widevine é um componente proprietário da Google e está desativado por padrão. Para o ativar e reproduzir o conteúdo codificado por DRM, utilize o exemplo de código abaixo:

engine = EngineFactory.Create(new EngineOptions.Builder
{
    RenderingMode = RenderingMode.HardwareAccelerated,
    ProprietaryFeatures = ProprietaryFeatures.Widevine
}.Build());
engine = EngineFactory.Create(New EngineOptions.Builder With 
{
    .RenderingMode = RenderingMode.HardwareAccelerated,
    .ProprietaryFeatures = ProprietaryFeatures.Widevine
}.Build())

O Widevine é um componente de propriedade da Google, regido pelos seus próprios termos de utilização. Para mais informações, consulte Widevine.

Câmara e microfone

O DotNetBrowser suporta uma câmara Web e um microfone. Você pode obter informações sobre todos os dispositivos de stream multimídia disponíveis utilizando o exemplo de código abaixo:

IMediaDevices mediaDevices = engine.MediaDevices;

// Obter todos os dispositivos de vídeo disponíveis, por exemplo, câmara web.
IEnumerable<MediaDevice> videoDevices = mediaDevices.VideoCaptureDevices;

// Obter todos os dispositivos de áudio disponíveis, por exemplo, o microfone.
IEnumerable<MediaDevice> audioDevices = mediaDevices.AudioCaptureDevices;
Dim mediaDevices As IMediaDevices = engine.MediaDevices

' Obter todos os dispositivos de vídeo disponíveis, por exemplo, câmara web.
Dim videoDevices As IEnumerable(Of MediaDevice) = mediaDevices.VideoCaptureDevices

' Obter todos os dispositivos de áudio disponíveis, por exemplo, o microfone.
Dim audioDevices As IEnumerable(Of MediaDevice) = mediaDevices.AudioCaptureDevices

É possível detectar quando a captura de mídia começa ou para utilizando estes eventos:

Browser.MediaStreamCaptureStarted += (sender, args) =>
{
    Console.WriteLine($"Iniciou a captura {args.MediaStreamType}"); 
};

Browser.MediaStreamCaptureStopped += (sender, args) =>
{
    Console.WriteLine($"Parou de capturar {args.MediaStreamType}");
};
AddHandler Browser.MediaStreamCaptureStarted, Sub(sender, args)
    Console.WriteLine($"Iniciou a captura {args.MediaStreamType}")
End Sub

AddHandler Browser.MediaStreamCaptureStopped, Sub(sender, args)
    Console.WriteLine($"Parou de capturar {args.MediaStreamType}")
End Sub

Selecionando um dispositivo multimídia

Você pode ter várias webcams e microfones no seu ambiente. Quando uma página Web pretende utilizar um deles, você pode utilizar SelectMediaDeviceHandler para indicar à página Web qual o dispositivo utilizar.

O exemplo de código abaixo demonstra como selecionar o primeiro dispositivo da lista de dispositivos disponíveis:

mediaDevices.SelectMediaDeviceHandler = 
    new Handler<SelectMediaDeviceParameters, SelectMediaDeviceResponse>(p =>
    {
        return SelectMediaDeviceResponse.Select(p.Devices.FirstOrDefault());
    });
mediaDevices.SelectMediaDeviceHandler = 
    New Handler(Of SelectMediaDeviceParameters, SelectMediaDeviceResponse)(Function(p)
        Return SelectMediaDeviceResponse.Select(p.Devices.FirstOrDefault())
    End Function)

O manipulador não será invocado se não existirem dispositivos de entrada multimídia do tipo solicitado.

Se pretender restringir o acesso ao microfone ou à Webcam para uma determinada página Web, você pode utilizar RequestPermissionHandler, tal como mostrado no exemplo de código abaixo:

engine.Profiles.Default.Permissions.RequestPermissionHandler = 
    new Handler<RequestPermissionParameters, RequestPermissionResponse>(p => 
    {
        if (p.Type == PermissionType.AudioCapture || p.Type == PermissionType.VideoCapture)
        {
            return RequestPermissionResponse.Deny();
        }
        return RequestPermissionResponse.Grant();
    });
engine.Profiles.Default.Permissions.RequestPermissionHandler =
    New Handler(Of RequestPermissionParameters, RequestPermissionResponse)(Function(p)
        Dim type = p.Type
        If type = PermissionType.AudioCapture OrElse type = PermissionType.VideoCapture Then
            Return RequestPermissionResponse.Deny()
        End If
        Return RequestPermissionResponse.Grant()
    End Function)

Transmissão

O Chromium tem uma funcionalidade integrada que permite a transmissão de conteúdos multimídia para dispositivos que suportam diferentes tecnologias sem fios, como Chromecast, Miracast, DLNA, AirPlay ou similares. Podem ser smart TVs, projetores e outros dispositivos.

O Diagrama Cast

Etapa preliminar

Por padrão, desativamos o Chromium de procurar dispositivos multimídia na sua rede. Para ativar e permitir que o Chromium encontre os potenciais receptores, utilize a opção do engine:

EngineOptions options = new EngineOptions.Builder
{
    MediaRoutingEnabled = true
}.Build();
IEngine engine = EngineFactory.Create(options);
Dim options As EngineOptions = New EngineOptions.Builder With 
        {
            .MediaRoutingEnabled = True
        }.Build()
Dim engine As IEngine = EngineFactory.Create(options)

Receptores multimédia

Para começar a transmitir conteúdos multimídia para um receptor, é necessário obter um. Para este efeito, o DotNetBrowser fornece um serviço de perfil separado IMediaReceivers que pode ser obtido desta forma:

IMediaReceivers mediaReceivers = profile.MediaCasting.Receivers;
Dim mediaReceivers As IMediaReceivers = profile.MediaCasting.Receivers

Para saber quando um novo receptor foi descoberto, o DotNetBrowser fornece o evento IMediaReceivers.Discovered:

IMediaReceivers mediaReceivers = profile.MediaCasting.Receivers;
mediaReceivers.Discovered += (sender, args) =>
{
    IMediaReceiver receiver = args.MediaReceiver;
};
Dim mediaReceivers As IMediaReceivers = profile.MediaCasting.Receivers
AddHandler mediaReceivers.Discovered, Sub(sender, args)
    Dim receiver As IMediaReceiver = args.MediaReceiver
End Sub

Para sua conveniência, o DotNetBrowser mantém um registro dos receptores descobertos. Se desejar obter a lista de receptores multimídia descobertos atualmente, utilize o properiedade IMediaReceivers.AllAvailable:

IMediaReceivers mediaReceivers = profile.MediaCasting.Receivers;
IReadOnlyList<IMediaReceiver> availableReceivers = mediaReceivers.AllAvailable;
Dim mediaReceivers As IMediaReceivers = profile.MediaCasting.Receivers
Dim availableReceivers As IReadOnlyList(Of IMediaReceiver) = mediaReceivers.AllAvailable

Se estiver à procura de um receptor específico, você pode obtê-lo através do método de conveniência IMediaReceivers.RetrieveAsync(Predicate<IMediaReceiver>). É executado de forma assíncrona até que o primeiro recetor que corresponde ao predicado seja descoberto e devolvido.

IMediaReceivers mediaReceivers = profile.MediaCasting.Receivers;
IMediaReceiver receiver =
        await mediaReceivers.RetrieveAsync(it => it.Name.Equals("Samsung"));
Dim mediaReceivers As IMediaReceivers = profile.MediaCasting.Receivers
Dim receiver As IMediaReceiver =
        Await mediaReceivers.RetrieveAsync(Function(it) it.Name.Equals("Samsung"))

Para detectar que o receptor multimídia foi desconectado, ou seja, desligado ou desconectado da rede, utilize o evento IMediaReceiver.Disconnected:

receiver.Disconnected += (sender, args) =>
{
    IMediaReceiver mediaReceiver = args.MediaReceiver;
};
AddHandler receiver.Disconnected, Sub(sender, args)
    Dim mediaReceiver As IMediaReceiver = args.MediaReceiver
End Sub

Transmitindo conteúdo

A API DotNetBrowser permite a conversão de conteúdos de navegadores, telas e apresentação utilizando a API de apresentação JavaScript.

Os receptores de multimídia podem suportar diferentes fontes de multimídia. Uma fonte multimídia representa um tipo de conteúdo que pode ser transmitido a um receptor multimídia. Antes de iniciar a transmissão, certifique-se de que o receptor multimídia selecionado suporta a fonte multimídia correspondente.

Casting de conteúdos do browser

Para começar a transmitir o conteúdo do navegador, utilize o método IBrowser.Cast.CastContent(IMediaReceiver):

IMediaReceiver receiver =
        await mediaReceivers.RetrieveAsync(it => it.Name.Contains("Samsung"));
if (receiver.Supports(CastMode.Browser))
{
    ICastSession castSession = await browser.Cast.CastContent(receiver);
}
Dim receiver As IMediaReceiver =
        Await mediaReceivers.RetrieveAsync(Function(it) it.Name.Contains("Samsung"))
If receiver.Supports(CastMode.Browser) Then
    Dim castSession As ICastSession = Await browser.Cast.CastContent(receiver)
End If

Cada sessão de transmissão de conteúdo multimédia para um recetor multimédia é representada por uma instância de ICastSession.

Pedido de apresentação padrão

Se a página da Web contiver o default PresentationRequest, o navegador começará a transmitir o conteúdo especificado nesse pedido em vez do conteúdo do navegador.

Para verificar se o navegador contém o PresentationRequest padrão, use:

IMediaReceiver receiver =
        await mediaReceivers.RetrieveAsync(it => it.Name.Contains("Samsung"));
PresentationRequest presentationRequest = browser.Cast.DefaultPresentationRequest();
if (receiver.Supports(CastMode.Presentation, presentationRequest))
{
    ICastSession castSession = await browser.Cast.CastContent(receiver);
}
Dim receiver As IMediaReceiver =
        Await mediaReceivers.RetrieveAsync(Function(it) it.Name.Contains("Samsung"))
Dim presentationRequest As PresentationRequest = browser.Cast.DefaultPresentationRequest()
If receiver.Supports(CastMode.Presentation, presentationRequest) Then
    Dim castSession As ICastSession = Await browser.Cast.CastContent(receiver)
End If

Transmitindo uma tela

Para iniciar a transmissão do conteúdo da tela, utilize IBrowser.Cast.CastScreen(IMediaReceiver). Este método mostra uma caixa de diálogo padrão do Chromium para escolher a tela a transmitir.

IMediaReceiver receiver =
        await mediaReceivers.RetrieveAsync(it => it.Name.Contains("Samsung"));
if (receiver.Supports(CastMode.Screen))
{
    ICastSession castSession = await browser.Cast.CastScreen(receiver);
}
Dim receiver As IMediaReceiver =
        Await mediaReceivers.RetrieveAsync(Function(it) it.Name.Contains("Samsung"))
If receiver.Supports(CastMode.Screen) Then
    Dim castSession As ICastSession = Await browser.Cast.CastScreen(receiver)
End If

Se pretender selecionar o ecrã de forma programática, utilize o método IBrowser.Cast.CastScreen(IMediaReceiver, ScreenCastOptions). Localize o ecrã de que necessita utilizando o serviço IScreens:

IMediaReceiver receiver =
        await mediaReceivers.RetrieveAsync(it => it.Name.Contains("Samsung"));
Screen screen = profile.MediaCasting.Screens.DefaultScreen;
ScreenCastOptions options = new ScreenCastOptions()
{
    Screen = screen,
    AudioMode = AudioMode.Cast
};
if (receiver.Supports(CastMode.Screen))
{
    ICastSession castSession = await browser.Cast.CastScreen(receiver, options);
}
Dim receiver As IMediaReceiver =
        Await mediaReceivers.RetrieveAsync(Function(it) it.Name.Contains("Samsung"))
Dim screen As Screen = profile.MediaCasting.Screens.DefaultScreen
Dim options As New ScreenCastOptions() With {
        .Screen = screen,
        .AudioMode = AudioMode.Cast
        }
If receiver.Supports(CastMode.Screen) Then
    Dim castSession As ICastSession = Await browser.Cast.CastScreen(receiver, options)
End If

Por enquanto, o Chromium suporta a transmissão de áudio apenas no Windows. Por isso, activá-lo no macOS/Linux através de ScreenCastOptions.AudioMode.Cast não é uma opção. No Windows, ao selecionar a tela na caixa de diálogo do seletor, o Chromium fornece uma caixa de verificação separada para selecionar a transmissão de áudio.

API de apresentação

O DotNetBrowser permite trabalhar com JavaScript Presentation API.

Quando o método PresentationRequest.start() é chamado do lado do JavaScript, o DotNetBrowser invoca o StartPresentationHandler onde você pode decidir iniciar ou cancelar a apresentação.

Para iniciar a apresentação a um recetor, utilizar o método StartPresentationResponse.Start(IMediaReceiver):

browser.Cast.StartPresentationHandler =
    new AsyncHandler<StartPresentationParameters, StartPresentationResponse>(async p =>
{
    IMediaReceiver receiver =
            await mediaReceivers.RetrieveAsync(it => it.Name.Contains("Samsung"));
    if (receiver.Supports(CastMode.Presentation, p.PresentationRequest))
    {
        return StartPresentationResponse.Start(receiver);
    }
    else
    {
        return StartPresentationResponse.Cancel();
    }
});
browser.Cast.StartPresentationHandler =
    New AsyncHandler(Of StartPresentationParameters,
                        StartPresentationResponse)(Async Function(p)

    Dim receiver As IMediaReceiver = 
            Await mediaReceivers.RetrieveAsync(Function(it) it.Name.Contains("Samsung"))
    If receiver.Supports(CastMode.Presentation, p.PresentationRequest) Then
        Return StartPresentationResponse.Start(receiver)
    Else
        Return StartPresentationResponse.Cancel()
    End If
End Function)

Descobrindo sessões de cast

Para ser notificado quando uma sessão de cast foi descoberta, o DotNetBrowser fornece o evento ICastSessions.Discovered:

profile.MediaCasting.CastSessions.Discovered += (o, args) =>
{
    ICastSession castSession = args.CastSession;
};
AddHandler profile.MediaCasting.CastSessions.Discovered, Sub(o, args)
    Dim castSession As ICastSession = args.CastSession
End Sub

O Chromium pode descobrir sessões iniciadas por outras aplicações ou instâncias do Chromium. Para indicar que a sessão de cast foi iniciada por este perfil, o DotNetBrowser fornece a propriedade ICastSession.IsLocal. Assim, se uma sessão de transmissão for iniciada por outro perfil ou mesmo outro processo do Chromium, a propriedade retornará false.

Interrompendo sessões de transmissão

Para parar uma sessão de transmissão, utilize o método ICastSession.Stop(). Se desejar ser notificado quando uma sessão de transmissão tiver sido interrompida, utilize o evento ICastSession.Stopped:

ICastSession session = profile.MediaCasting.CastSessions.AllAlive.FirstOrDefault();
session.Stopped += (o, args) =>
{
    // Faz alguma coisa
};
...
session.Stop();
Dim session As ICastSession = profile.MediaCasting.CastSessions.AllAlive.FirstOrDefault()
AddHandler session.Stopped, Sub(o, args)
    ' Faz alguma coisa
End Sub
...
session.Stop()

A sessão pode ser interrompida por outras aplicações ou instâncias do Chromium, ou seja Google Chrome. Google Chrome. Neste caso, o evento também será invocado.

Falhas

Por vezes, o Chromium pode não conseguir iniciar uma nova sessão de transmissão, ou seja, se o receptor multimídia não for encontrado ou se o tiver sido subitamente desconectado. Para detectar isso, use o evento ICastSessions.StartFailed:

IMediaReceiver receiver =
        await mediaReceivers.RetrieveAsync(it => it.Name.Contains("Samsung"));
profile.MediaCasting.CastSessions.StartFailed += (o, args) =>
{
    string errorMessage = args.ErrorMessage;
};

ICastSession castSession = await browser.Cast.CastContent(receiver);
Dim receiver As IMediaReceiver =
        Await mediaReceivers.RetrieveAsync(Function(it) it.Name.Contains("Samsung"))
AddHandler profile.MediaCasting.CastSessions.StartFailed, Sub(o, args)
    Dim errorMessage As String = args.ErrorMessage
End Sub

Dim castSession As ICastSession = Await browser.Cast.CastContent(receiver)

Trata-se de um acontecimento intencional devido à natureza assíncrona da transmissão de mídia.

Como os métodos Browser.Cast.CastXxx() retornam Task<ICastSession>, é possível detetar que o início da sessão de cast falhou. Neste caso, o DotNetBrowser lança a CastSessionStartFailedException:

try
{
    ICastSession castSession = await browser.Cast.CastContent(receiver);
}
catch (CastSessionStartFailedException ex)
{
    string errorMessage = ex.Message;
}
Try
    Dim castSession As ICastSession = Await browser.Cast.CastContent(receiver)
Catch ex As CastSessionStartFailedException
    Dim errorMessage As String = ex.Message
End Try

Go Top