Skip to content

Commit

Permalink
feat: support FocusMode/ExposureMode for camera capture options.
Browse files Browse the repository at this point in the history
  • Loading branch information
cloudwebrtc committed Dec 16, 2024
1 parent a0ee074 commit 20f52b8
Show file tree
Hide file tree
Showing 2 changed files with 74 additions and 17 deletions.
14 changes: 14 additions & 0 deletions lib/src/track/options.dart
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@ enum CameraPosition {
back,
}

enum CameraFocusMode { auto, locked }

enum CameraExposureMode { auto, locked }

/// Convenience extension for [CameraPosition].
extension CameraPositionExt on CameraPosition {
/// Return a [CameraPosition] which front and back is switched.
Expand All @@ -41,8 +45,16 @@ class CameraCaptureOptions extends VideoCaptureOptions {
/// set to false to only toggle enabled instead of stop/replaceTrack for muting
final bool stopCameraCaptureOnMute;

/// The focus mode to use for the camera.
final CameraFocusMode focusMode;

/// The exposure mode to use for the camera.
final CameraExposureMode exposureMode;

const CameraCaptureOptions({
this.cameraPosition = CameraPosition.front,
this.focusMode = CameraFocusMode.auto,
this.exposureMode = CameraExposureMode.auto,
String? deviceId,
double? maxFrameRate,
VideoParameters params = VideoParametersPresets.h720_169,
Expand All @@ -55,6 +67,8 @@ class CameraCaptureOptions extends VideoCaptureOptions {

CameraCaptureOptions.from({required VideoCaptureOptions captureOptions})
: cameraPosition = CameraPosition.front,
focusMode = CameraFocusMode.auto,
exposureMode = CameraExposureMode.auto,
stopCameraCaptureOnMute = true,
super(
params: captureOptions.params,
Expand Down
77 changes: 60 additions & 17 deletions lib/src/widgets/video_track_renderer.dart
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
// See the License for the specific language governing permissions and
// limitations under the License.

import 'dart:math';

import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';

Expand Down Expand Up @@ -77,6 +79,25 @@ class _VideoTrackRendererState extends State<VideoTrackRenderer> {
return _renderer!;
}

void setZoom(double zoomLevel) async {
final videoTrack = _renderer?.srcObject!.getVideoTracks().first;
if (videoTrack == null) return;
await rtc.Helper.setZoom(videoTrack, zoomLevel);
}

void onViewFinderTap(TapDownDetails details, BoxConstraints constraints) {
final videoTrack = _renderer?.srcObject!.getVideoTracks().first;
if (videoTrack == null) return;

final point = Point<double>(
details.localPosition.dx / constraints.maxWidth,
details.localPosition.dy / constraints.maxHeight,
);

rtc.Helper.setFocusPoint(videoTrack, point);
rtc.Helper.setExposurePoint(videoTrack, point);
}

void disposeRenderer() {
try {
_renderer?.srcObject = null;
Expand Down Expand Up @@ -158,6 +179,28 @@ class _VideoTrackRendererState extends State<VideoTrackRenderer> {
},
);

Widget _videoRendererView() {
if (lkPlatformIs(PlatformType.iOS) &&
[VideoRenderMode.auto, VideoRenderMode.platformView]
.contains(widget.renderMode)) {
return rtc.RTCVideoPlatFormView(
mirror: _shouldMirror(),
objectFit: widget.fit,
onViewReady: (controller) {
_renderer = controller;
_renderer?.srcObject = widget.track.mediaStream;
_attach();
},
);
}
return rtc.RTCVideoView(
_renderer! as rtc.RTCVideoRenderer,
mirror: _shouldMirror(),
filterQuality: FilterQuality.medium,
objectFit: widget.fit,
);
}

Widget _videoViewForNative() => FutureBuilder(
future: _initializeRenderer(),
builder: (context, snapshot) {
Expand All @@ -172,24 +215,24 @@ class _VideoTrackRendererState extends State<VideoTrackRenderer> {
?.addPostFrameCallback((timeStamp) {
widget.track.onVideoViewBuild?.call(_internalKey);
});
if (lkPlatformIs(PlatformType.iOS) &&
[VideoRenderMode.auto, VideoRenderMode.platformView]
.contains(widget.renderMode)) {
return rtc.RTCVideoPlatFormView(
mirror: _shouldMirror(),
objectFit: widget.fit,
onViewReady: (controller) {
_renderer = controller;
_renderer?.srcObject = widget.track.mediaStream;
_attach();
},
);

if (!lkPlatformIsMobile() || widget.track is! LocalVideoTrack) {
return _videoRendererView();
}
return rtc.RTCVideoView(
_renderer! as rtc.RTCVideoRenderer,
mirror: _shouldMirror(),
filterQuality: FilterQuality.medium,
objectFit: widget.fit,
return LayoutBuilder(
builder: (BuildContext context, BoxConstraints constraints) {
return GestureDetector(
onScaleStart: (details) {},
onScaleUpdate: (details) {
if (details.scale != 1.0) {
setZoom(details.scale);
}
},
onTapDown: (TapDownDetails details) =>
onViewFinderTap(details, constraints),
child: _videoRendererView(),
);
},
);
},
);
Expand Down

0 comments on commit 20f52b8

Please sign in to comment.