Skip to content

Commit f57315d

Browse files
ArgoZhangSteelTeng
andauthored
refactor(IVideoDevice): add Apply method (#5949)
* chore: bump version 9.6.1-beta02 Co-Authored-By: SteelTeng <[email protected]> * doc: 微调样式 * feat: 增加 apply 实现方法 * doc: 更新示例 * test: 更新单元测试 --------- Co-authored-by: SteelTeng <[email protected]>
1 parent 94c27d8 commit f57315d

File tree

10 files changed

+87
-8
lines changed

10 files changed

+87
-8
lines changed

src/BootstrapBlazor.Server/Components/Samples/VideoDevices.razor

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,15 @@ private IBluetooth? BluetoothService { get; set; }</Pre>
1313
Name="Normal">
1414
<div class="row form-inline g-3">
1515
<div class="col-12">
16-
<Button Text="@Localizer["VideoDeviceRequestText"]" Icon="fa-solid fa-photo-film" OnClick="OnRequestDevice"></Button>
17-
<Button Text="@Localizer["VideoDeviceOpenText"]" Icon="fa-solid fa-play" OnClick="OnOpenVideo" IsDisabled="_isOpen || string.IsNullOrEmpty(_deviceId)" class="ms-2"></Button>
18-
<Button Text="@Localizer["VideoDeviceCloseText"]" Icon="fa-solid fa-stop" OnClick="OnCloseVideo" IsDisabled="!_isOpen" class="ms-2"></Button>
19-
<Button Text="@Localizer["VideoDeviceCaptureText"]" Icon="fa-solid fa-camera" OnClick="OnCapture" IsDisabled="!_isOpen" class="ms-2"></Button>
16+
<div class="bb-actions">
17+
<Button Text="@Localizer["VideoDeviceRequestText"]" Icon="fa-solid fa-photo-film" OnClick="OnRequestDevice"></Button>
18+
<Button Text="@Localizer["VideoDeviceOpenText"]" Icon="fa-solid fa-play" OnClick="OnOpenVideo" IsDisabled="_isOpen || string.IsNullOrEmpty(_deviceId)"></Button>
19+
<Button Text="@Localizer["VideoDeviceCloseText"]" Icon="fa-solid fa-stop" OnClick="OnCloseVideo" IsDisabled="!_isOpen"></Button>
20+
<Button Text="@Localizer["VideoDeviceCaptureText"]" Icon="fa-solid fa-camera" OnClick="OnCapture" IsDisabled="!_isOpen"></Button>
21+
<Button Text="QVGA" IsDisabled="!_isOpen" OnClickWithoutRender="() => OnApply(320, 240)"></Button>
22+
<Button Text="VGA" IsDisabled="!_isOpen" OnClickWithoutRender="() => OnApply(640, 480)"></Button>
23+
<Button Text="HD" IsDisabled="!_isOpen" OnClickWithoutRender="() => OnApply(1280, 960)"></Button>
24+
</div>
2025
</div>
2126
<div class="col-12">
2227
<Select Items="@_items" @bind-Value="_deviceId" DisplayText="Devices" ShowLabel="true"></Select>

src/BootstrapBlazor.Server/Components/Samples/VideoDevices.razor.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,8 @@ private async Task OnCapture()
6161
_previewUrl = await VideoDeviceService.GetPreviewUrl();
6262
}
6363

64+
private Task OnApply(int width, int height) => VideoDeviceService.Apply(new MediaTrackConstraints() { Width = width, Height = height });
65+
6466
private async Task DisposeAsync(bool disposing)
6567
{
6668
if (disposing)
Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,22 @@
1-
.bb-video {
1+
.bb-actions {
2+
display: flex;
3+
flex-wrap: wrap;
4+
gap: .5rem .5rem;
5+
}
6+
7+
.bb-video {
28
min-height: 240px;
39
height: auto;
410
width: auto;
5-
margin-top: 1rem;
11+
margin: 1rem;
612
display: block;
713
}
814

915
.bb-image {
1016
border: 1px solid var(--bs-border-color);
1117
border-radius: var(--bs-border-radius);
12-
margin-top: 1rem;
18+
margin: 1rem 1rem 0 1rem;
1319
display: block;
20+
width: calc(100% - 2rem);
21+
max-width: 640px;
1422
}

src/BootstrapBlazor/BootstrapBlazor.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<Project Sdk="Microsoft.NET.Sdk.Razor">
22

33
<PropertyGroup>
4-
<Version>9.6.1-beta01</Version>
4+
<Version>9.6.1-beta02</Version>
55
</PropertyGroup>
66

77
<ItemGroup>

src/BootstrapBlazor/Services/MediaDevices/DefaultMediaDevices.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,4 +44,10 @@ public async Task Capture()
4444
var module = await LoadModule();
4545
return await module.InvokeAsync<string?>("getPreviewUrl");
4646
}
47+
48+
public async Task<bool> Apply(MediaTrackConstraints constraints)
49+
{
50+
var module = await LoadModule();
51+
return await module.InvokeAsync<bool>("apply", constraints);
52+
}
4753
}

src/BootstrapBlazor/Services/MediaDevices/DefaultVideoDevice.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,4 +41,9 @@ public Task Capture()
4141
{
4242
return deviceService.GetPreviewUrl();
4343
}
44+
45+
public Task<bool> Apply(MediaTrackConstraints constraints)
46+
{
47+
return deviceService.Apply(constraints);
48+
}
4449
}

src/BootstrapBlazor/Services/MediaDevices/IMediaDevices.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,4 +41,11 @@ public interface IMediaDevices
4141
/// </summary>
4242
/// <returns></returns>
4343
Task<string?> GetPreviewUrl();
44+
45+
/// <summary>
46+
/// Apply the media track constraints.
47+
/// </summary>
48+
/// <param name="constraints"></param>
49+
/// <returns></returns>
50+
Task<bool> Apply(MediaTrackConstraints constraints);
4451
}

src/BootstrapBlazor/Services/MediaDevices/IVideoDevice.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,4 +53,11 @@ public interface IVideoDevice
5353
/// </summary>
5454
/// <returns></returns>
5555
Task<string?> GetPreviewUrl();
56+
57+
/// <summary>
58+
/// Apply the media track constraints.
59+
/// </summary>
60+
/// <param name="constraints"></param>
61+
/// <returns></returns>
62+
Task<bool> Apply(MediaTrackConstraints constraints);
5663
}

src/BootstrapBlazor/wwwroot/modules/media.js

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,41 @@ export async function close(videoSelector) {
7777
return ret;
7878
}
7979

80+
export async function apply(options) {
81+
let ret = false;
82+
try {
83+
const media = registerBootstrapBlazorModule("MediaDevices");
84+
const { stream } = media;
85+
if (stream && stream.active) {
86+
const tracks = stream.getVideoTracks();
87+
if (tracks) {
88+
const track = tracks[0];
89+
const settings = track.getSettings();
90+
const { aspectRatio } = settings;
91+
if (options.width) {
92+
settings.width = {
93+
exact: options.width,
94+
};
95+
settings.height = {
96+
exact: Math.floor(options.width / aspectRatio)
97+
};
98+
}
99+
if (options.facingMode) {
100+
settings.facingMode = {
101+
ideal: options.facingMode,
102+
}
103+
}
104+
console.log(settings);
105+
await track.applyConstraints(settings);
106+
}
107+
}
108+
}
109+
catch (err) {
110+
console.error("Error apply constraints media devices.", err);
111+
}
112+
return ret;
113+
}
114+
80115
export async function getPreviewUrl() {
81116
let url = null;
82117
const media = registerBootstrapBlazorModule("MediaDevices");

test/UnitTest/Services/VideoDeviceTest.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ public async Task Open_Ok()
2828
Context.JSInterop.Setup<string?>("getPreviewUrl").SetResult("blob:https://test-preview");
2929
Context.JSInterop.Setup<bool>("open", _ => true).SetResult(true);
3030
Context.JSInterop.Setup<bool>("close", _ => true).SetResult(true);
31+
Context.JSInterop.Setup<bool>("apply", _ => true).SetResult(true);
3132

3233
var service = Context.Services.GetRequiredService<IVideoDevice>();
3334
var options = new MediaTrackConstraints()
@@ -44,6 +45,9 @@ public async Task Open_Ok()
4445
var close = await service.Close(".bb-video");
4546
Assert.True(close);
4647

48+
var apply = await service.Apply(new MediaTrackConstraints() { Width = 640, Height = 480, VideoSelector = ".bb-video" });
49+
Assert.True(apply);
50+
4751
Assert.Equal("test-device-id", options.DeviceId);
4852
Assert.Equal("user", options.FacingMode);
4953
Assert.Equal(640, options.Height);

0 commit comments

Comments
 (0)