媒体

本指南概述了支持的视频和音频格式,介绍了如何控制音频、获取有关可用网络摄像头和麦克风的信息以及其他功能。

编解码器

Google Chrome 和 Chromium 在几个方面有所不同,包括它们支持的音频和视频编解码器集。

下表显示了相应浏览器的代码库支持的编解码器。

  Chromium Google Chrome
AAC no yes
AV1 yes yes
FLAC yes yes
H.264 no yes
HEVC no yes
MP3 yes yes
Opus yes yes
Theora yes yes
Vorbis yes yes
VP8 yes yes
VP9 yes yes
WAV yes yes


如上表所示,Google Chrome 浏览器支持某些编解码器,而 Chromium 浏览器则不支持。原因是这些编解码器是专有的,未经相应专利持有者的许可不能用于开源或商业项目。

不同的编解码器有不同的专利持有者。例如,要使用 H.264,公司必须获得 Via LA 公司的许可。您可以在网站上阅读有关其许可条款的更多信息。

专有编解码器

专利持有者不会将编解码器许可给仅代表部署给终端用户的最终产品的一部分的软件,例如,像 DotNetBrowser 这样的库。

要在您的产品中支持 H.264,HEVC 和 AAC,您需要购买相应的许可证并启用以下专有功能:

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())

提供许可证信息并启用专有功能后,您就可以像在 Google Chrome 浏览器中一样,使用 AAC、H.264 和 HEVC 格式加载网页,播放音频和视频文件。默认情况下,专有编解码器被禁用。

H.264,HEVC 和 AAC 编解码器是专有组件。启用这些编解码器即表明您知道 H.264、HEVC 和 AAC 是专有组件,您必须获得许可才能使用它们。欲了解更多信息,您可以联系专利持有者:Via Licensing 和 MPEG LA。TeamDev 对您使用 H.264、HEVC 和 AAC 编解码器不承担任何责任。

视频

DotNetBrowser 完全支持 HTML5 <video> 元素,可以播放支持格式的视频。

如果库无法播放视频,或者不支持视频格式,DotNetBrowser 会建议下载视频文件。有关详细信息,请参阅包含管理下载说明的下载部分。

HTML5 Video

音频

控制音频

使用 IAudioController,您可以了解加载的网页是否正在播放音频:

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

如有需要,您可以在加载的网页上将音频静音或取消静音:

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

要检查音频是否静音,请使用以下代码:

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

音频事件

要了解音频是否已在加载的网页上开始/停止播放,您可以订阅以下事件:

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

NetflixAmazon Prime 等网络服务使用 Widevine 分发其 DRM 编码内容。Widevine 是 Google 专有组件,默认情况下处于禁用状态。要启用它并播放 DRM 编码的内容,请使用下面的代码示例:

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())

Widevine 是谷歌的专有组件,受其自身使用条款的约束。更多信息,请参阅 Widevine

摄像头和麦克风

DotNetBrowser 支持网络摄像头和麦克风。您可以使用下面的代码示例获取所有可用媒体流设备的信息:

IMediaDevices mediaDevices = engine.MediaDevices;

// 获取所有可用的视频设备,例如 网络摄像头。
IEnumerable<MediaDevice> videoDevices = mediaDevices.VideoCaptureDevices;

// 获取所有可用的音频设备,例如 麦克风。
IEnumerable<MediaDevice> audioDevices = mediaDevices.AudioCaptureDevices;
Dim mediaDevices As IMediaDevices = engine.MediaDevices

' 获取所有可用的视频设备,例如网络摄像头。
Dim videoDevices As IEnumerable(Of MediaDevice) = mediaDevices.VideoCaptureDevices

' 获取所有可用的音频设备,例如麦克风。
Dim audioDevices As IEnumerable(Of MediaDevice) = mediaDevices.AudioCaptureDevices

您可以使用以下事件检测媒体捕捉何时开始或停止:

Browser.MediaStreamCaptureStarted += (sender, args) =>
{
    Console.WriteLine($"Started capturing {args.MediaStreamType}"); 
};

Browser.MediaStreamCaptureStopped += (sender, args) =>
{
    Console.WriteLine($"Stopped capturing {args.MediaStreamType}");  
};
AddHandler Browser.MediaStreamCaptureStarted, Sub(sender, args)
    Console.WriteLine($"Started capturing {args.MediaStreamType}")
End Sub

AddHandler Browser.MediaStreamCaptureStopped, Sub(sender, args)
    Console.WriteLine($"Stopped capturing {args.MediaStreamType}")
End Sub

选择媒体设备

您的环境中可以有多个网络摄像头和麦克风。当网页想要使用其中一个设备时,可以使用 SelectMediaDeviceHandler 来指示网页使用哪个设备。

下面的代码示例演示了如何从可用设备列表中选择第一个设备:

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)

如果没有所请求类型的媒体输入设备,处理程序不会被调用

如果您想限制特定网页对麦克风或网络摄像头的访问,您可以使用 RequestPermissionHandler,如下面的代码示例所示:

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)

投射

Chromium 内置了允许将媒体内容投射到支持不同无线技术的设备上的功能,如 Chromecast、Miracast、DLNA、AirPlay 或类似技术。这些设备可以是智能电视、投影仪和其他设备。

投射示意图

预备步骤

默认情况下,我们禁止 Chromium 扫描您的网络以查找媒体设备。要启用此功能并让 Chromium 找到潜在的接收设备,请使用引擎选项:

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)

媒体接收设备

要将媒体内容投射到接收设备上,您需要获得一个接收设备。为此,DotNetBrowser 提供了一个单独的 IMediaReceivers 配置文件服务,您可以通过以下方式获取它:

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

为了了解何时发现新的接收设备,DotNetBrowser 提供了 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

为了方便起见,DotNetBrowser 会跟踪已发现的接收设备。如果您想获取当前已发现的媒体接收设备列表,请使用 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

如果您正在寻找特定的接收设备,您可以通过 IMediaReceivers.RetrieveAsync(Predicate<IMediaReceiver>) 便捷方法获取它。此方法会异步执行,直到发现第一个与特定条件匹配的接收设备,然后将其返回。

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"))

要检测媒体接收设备是否已断开连接,即是否被拔掉或已从网络中断开,请使用 IMediaReceiver.Disconnected 事件:

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

投射内容

DotNetBrowser API 允许使用 JavaScript Presentation API 投射浏览器、屏幕和演示文稿的内容。

媒体接收设备可以支持不同的媒体源。媒体源代表可以投射到媒体接收设备的内容类型。在开始投射之前,请确保所选的媒体接收设备支持相应的媒体源。

投射浏览器内容

要开始投射浏览器内容,请使用 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

每个将媒体内容投射到媒体接收设备的会话都由 ICastSession 实例表示。

默认演示请求

如果网页包含默认的 PresentationRequest, 浏览器将开始投射该请求中指定的内容,而不是浏览器的内容。

要检查浏览器是否包含默认的 PresentationRequest,请使用:

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

投射屏幕

要开始投射屏幕内容,请使用 IBrowser.Cast.CastScreen(IMediaReceiver)。此方法将显示一个标准的 Chromium 对话框,用于选择要投射的屏幕。

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

如果您想以编程方式选择屏幕,请使用 IBrowser.Cast.CastScreen(IMediaReceiver, ScreenCastOptions) 方法。使用 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

目前,Chromium 仅在 Windows 上支持音频投射。因此,在 macOS/Linux 上通过 ScreenCastOptions.AudioMode.Cast 启用音频投射是没有任何效果的。在 Windows 上,当在选取器对话框中选择屏幕时,Chromium 提供了一个单独的复选框用于选择音频投射。

演示 API(Presentation API)

DotNetBrowser 允许使用 JavaScript Presentation API

当在 JavaScript 端调用 PresentationRequest.start() 方法时,DotNetBrowser 会调用 StartPresentationHandler,您可以在其中决定是否开始或取消演示。

要将演示文稿投射到接收设备,请使用 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)

发现投射会话

为了在发现投射会话时收到通知,DotNetBrowser 提供了 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

可以发现由其他应用程序或 Chromium 实例启动的会话。为了指示该投射会话是由此配置文件启动的,DotNetBrowser 提供了 ICastSession.IsLocal 属性。因此,如果投射会话是由另一个配置文件或甚至另一个 Chromium 进程启动的,该属性将返回 false

停止投射会话

要停止投射会话,请使用 ICastSession.Stop() 方法。如果您想在投射会话停止时收到通知,请使用 ICastSession.Stopped 事件:

ICastSession session = profile.MediaCasting.CastSessions.AllAlive.FirstOrDefault();
session.Stopped += (o, args) =>
{
    // 执行一些操作
};
...
session.Stop();
Dim session As ICastSession = profile.MediaCasting.CastSessions.AllAlive.FirstOrDefault()
AddHandler session.Stopped, Sub(o, args)
    ' Do something
End Sub
...
session.Stop()

会话可以被其他应用程序或 Chromium 的实例(例如 Google Chrome)停止。在这种情况下,事件也会被触发。

失败情况

有时,Chromium 可能无法启动新的投射会话,例如媒体接收器未找到或突然断开连接。为了检测这种情况,请使用 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)

这是媒体投射异步性质故意造成的一个事件。

由于 Browser.Cast.CastXxx() 方法返回 Task<ICastSession>, 您可以检测到投射会话的启动失败。在这种情况下,DotNetBrowser 会抛出 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