Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@

# Changelog

[1.0.13] - 2025-10-28
* Exposed `eventStream` in `MediaDevices`.
* [Android] Sends event when screen capture ends.

[1.0.12] - 2025-09-30
* [Android] Changed the configuration used when creating EGL rendering context to one that supports alpha channel to fix an issue with Impeller blending background with video texture on some devices.
* [Android] Migrate from onSurfaceDestroyed to onSurfaceCleanup for SurfaceProducer.Callback.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ public class GetUserMediaImpl {
private static final int DEFAULT_HEIGHT = 720;
private static final int DEFAULT_FPS = 30;

private static final String EVENT_DISPLAY_MEDIA_STOPPED = "screenSharingStopped";
private static final String PERMISSION_AUDIO = Manifest.permission.RECORD_AUDIO;
private static final String PERMISSION_VIDEO = Manifest.permission.CAMERA;
private static final String PERMISSION_SCREEN = "android.permission.MediaProjection";
Expand Down Expand Up @@ -519,19 +520,24 @@ private void getDisplayMedia(final Result result, final MediaStream mediaStream,
/* Create ScreenCapture */
VideoTrack displayTrack = null;
VideoCapturer videoCapturer = null;
videoCapturer =
new OrientationAwareScreenCapturer(
applicationContext,
mediaProjectionData,
new MediaProjection.Callback() {
@Override
public void onStop() {
super.onStop();
// After Huawei P30 and Android 10 version test, the onstop method is called, which will not affect the next process,
// and there is no need to call the resulterror method
//resultError("MediaProjection.Callback()", "User revoked permission to capture the screen.", result);
}
});
String trackId = stateProvider.getNextTrackUUID();

videoCapturer = new OrientationAwareScreenCapturer(
applicationContext,
mediaProjectionData,
new MediaProjection.Callback() {
@Override
public void onStop() {
super.onStop();

ConstraintsMap params = new ConstraintsMap();
params.putString("event", EVENT_DISPLAY_MEDIA_STOPPED);
params.putString("trackId", trackId);
FlutterWebRTCPlugin.sharedSingleton.sendEvent(params.toMap());
}
}
);

if (videoCapturer == null) {
resultError("screenRequestPermissions", "GetDisplayMediaFailed, User revoked permission to capture the screen.", result);
return;
Expand Down Expand Up @@ -563,7 +569,6 @@ public void onStop() {
videoCapturer.startCapture(info.width, info.height, info.fps);
Log.d(TAG, "OrientationAwareScreenCapturer.startCapture: " + info.width + "x" + info.height + "@" + info.fps);

String trackId = stateProvider.getNextTrackUUID();
mVideoCapturers.put(trackId, info);
mVideoSources.put(trackId, videoSource);

Expand Down
2 changes: 2 additions & 0 deletions common/darwin/Classes/FlutterWebRTCPlugin.h
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,8 @@ typedef void (^CapturerStopHandler)(CompletionHandler _Nonnull handler);
- (RTCRtpSender* _Nullable)getRtpSenderById:(RTCPeerConnection* _Nonnull)peerConnection
Id:(NSString* _Nonnull)Id;

- (void)postEventWithName:(NSString* _Nonnull)eventName data:(NSDictionary* _Nullable)data;

+ (FlutterWebRTCPlugin* _Nullable)sharedSingleton;

@end
15 changes: 15 additions & 0 deletions common/darwin/Classes/FlutterWebRTCPlugin.m
Original file line number Diff line number Diff line change
Expand Up @@ -2503,4 +2503,19 @@ - (FlutterRTCVideoRenderer *)findRendererByTrackId:(NSString *)trackId {
}
return nil;
}

#pragma mark - Event Posting Helper

- (void)postEventWithName:(NSString*)eventName data:(NSDictionary*)data {
if (!self.eventSink) {
return;
}

NSMutableDictionary* eventData = [NSMutableDictionary dictionaryWithObject:eventName forKey:@"event"];
if (data) {
[eventData addEntriesFromDictionary:data];
}

postEvent(self.eventSink, eventData);
}
@end
2 changes: 1 addition & 1 deletion ios/stream_webrtc_flutter.podspec
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
#
Pod::Spec.new do |s|
s.name = 'stream_webrtc_flutter'
s.version = '1.0.12'
s.version = '1.0.13'
s.summary = 'Flutter WebRTC plugin for iOS.'
s.description = <<-DESC
A new flutter plugin project.
Expand Down
3 changes: 3 additions & 0 deletions lib/src/native/factory_impl.dart
Original file line number Diff line number Diff line change
Expand Up @@ -187,3 +187,6 @@ DesktopCapturer get desktopCapturer => DesktopCapturerNative.instance;
MediaDevices get mediaDevices => MediaDeviceNative.instance;

FrameCryptorFactory get frameCryptorFactory => FrameCryptorFactoryImpl.instance;

Stream<Map<String, dynamic>> get eventStream =>
MediaDeviceNative.instance.eventStream;
3 changes: 3 additions & 0 deletions lib/src/native/mediadevices_impl.dart
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ class MediaDeviceNative extends MediaDevices {

static final MediaDeviceNative instance = MediaDeviceNative._internal();

Stream<Map<String, dynamic>> get eventStream =>
FlutterWebRTCEventChannel.instance.handleEvents.stream;

void handleEvent(String event, final Map<dynamic, dynamic> map) async {
switch (map['event']) {
case 'onDeviceChange':
Expand Down
2 changes: 2 additions & 0 deletions lib/src/web/factory_impl.dart
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,5 @@ Future<void> handleCallInterruptionCallbacks(
throw UnimplementedError(
'handleCallInterruptionCallbacks() is not supported on web');
}

Stream<Map<String, dynamic>> get eventStream => Stream.empty();
2 changes: 1 addition & 1 deletion macos/stream_webrtc_flutter.podspec
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
#
Pod::Spec.new do |s|
s.name = 'stream_webrtc_flutter'
s.version = '1.0.12'
s.version = '1.0.13'
s.summary = 'Flutter WebRTC plugin for macOS.'
s.description = <<-DESC
A new flutter plugin project.
Expand Down
2 changes: 1 addition & 1 deletion pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name: stream_webrtc_flutter
description: Flutter WebRTC plugin for iOS/Android/Destkop/Web, based on GoogleWebRTC.
version: 1.0.12
version: 1.0.13
homepage: https://github.com/GetStream/webrtc-flutter
environment:
sdk: ">=3.6.0 <4.0.0"
Expand Down