Skip to content

Commit

Permalink
Merge pull request #57 from videosdk-live/fix/screenShare
Browse files Browse the repository at this point in the history
fix screenShare thumbnail issue for desktop app
  • Loading branch information
ishabodiwala authored Apr 23, 2024
2 parents 03b9da1 + c8dddb1 commit 06cecdf
Show file tree
Hide file tree
Showing 4 changed files with 100 additions and 23 deletions.
2 changes: 1 addition & 1 deletion lib/screens/conference-call/conference_meeting_screen.dart
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ class _ConfereneceMeetingScreenState extends State<ConfereneceMeetingScreen> {
camEnabled: widget.camEnabled,
maxResolution: 'hd',
multiStream: true,
defaultCameraIndex: kIsWeb ? 0 : 1,
defaultCameraIndex: kIsWeb ? 0 : (Platform.isAndroid || Platform.isIOS) ? 1 : 0,
notification: const NotificationInfo(
title: "Video SDK",
message: "Video SDK is sharing screen in the meeting",
Expand Down
2 changes: 1 addition & 1 deletion lib/screens/one-to-one/one_to_one_meeting_screen.dart
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ class _OneToOneMeetingScreenState extends State<OneToOneMeetingScreen> {
camEnabled: widget.camEnabled,
maxResolution: 'hd',
multiStream: false,
defaultCameraIndex: kIsWeb ? 0 : 1,
defaultCameraIndex: kIsWeb ? 0 : (Platform.isAndroid || Platform.isIOS) ? 1 : 0,
notification: const NotificationInfo(
title: "Video SDK",
message: "Video SDK is sharing screen in the meeting",
Expand Down
83 changes: 66 additions & 17 deletions lib/widgets/common/screen_share/screen_select_dialog.dart
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import 'dart:async';

import 'package:flutter/material.dart';
import 'package:flutter_webrtc/flutter_webrtc.dart';
import 'package:videosdk/videosdk.dart';
Expand All @@ -7,28 +9,76 @@ import 'thumbnail_widget.dart';
// ignore: must_be_immutable
class ScreenSelectDialog extends Dialog {
ScreenSelectDialog({Key? key, required this.meeting}) : super(key: key) {
meeting.getScreenShareSources().then((value) => _setSources(value));
_getSources();
_subscriptions.add(desktopCapturer.onAdded.stream.listen((source) {
_sources[source.id] = source;
_stateSetter?.call(() {});
}));

_subscriptions.add(desktopCapturer.onRemoved.stream.listen((source) {
_sources.remove(source.id);
_stateSetter?.call(() {});
}));

_subscriptions
.add(desktopCapturer.onThumbnailChanged.stream.listen((source) {
_stateSetter?.call(() {});
}));
}



void _setSources(List<DesktopCapturerSource> source) {
_sources = source;
source.forEach((element) {
_sources[element.id] = element;
});

_stateSetter?.call(() {});
}

List<DesktopCapturerSource> _sources = [];
final Map<String, DesktopCapturerSource> _sources = {};
SourceType _sourceType = SourceType.Screen;
DesktopCapturerSource? _selected_source;
final List<StreamSubscription<DesktopCapturerSource>> _subscriptions = [];
StateSetter? _stateSetter;
Timer? _timer;
final Room meeting;

void _ok(context) async {
_timer?.cancel();
for (var element in _subscriptions) {
element.cancel();
}
Navigator.pop<DesktopCapturerSource>(context, _selected_source);
}

void _cancel(context) async {
_timer?.cancel();
for (var element in _subscriptions) {
element.cancel();
}
Navigator.pop<DesktopCapturerSource>(context, null);
}

Future<void> _getSources() async {
try {
var sources = await desktopCapturer.getSources(types: [_sourceType]);
_timer?.cancel();
_timer = Timer.periodic(Duration(seconds: 3), (timer) {
desktopCapturer.updateSources(types: [_sourceType]);
});
_sources.clear();
sources.forEach((element) {
_sources[element.id] = element;
});
_stateSetter?.call(() {});
return;
} catch (e) {
print(e.toString());
}
}


@override
Widget build(BuildContext context) {
return Material(
Expand Down Expand Up @@ -83,9 +133,12 @@ class ScreenSelectDialog extends Dialog {
const BoxConstraints.expand(height: 24),
child: TabBar(
indicatorColor: purple,
onTap: (value) => _sourceType = value == 0
? SourceType.Screen
: SourceType.Window,
onTap: (value) => Future.delayed(Duration.zero, () {
_sourceType = value == 0
? SourceType.Screen
: SourceType.Window;
_getSources();
}),
tabs: const [
Tab(
child: Text(
Expand All @@ -111,12 +164,10 @@ class ScreenSelectDialog extends Dialog {
child: GridView.count(
crossAxisSpacing: 8,
crossAxisCount: 2,
children: _sources
.asMap()
.entries
children: _sources.entries
.where((element) =>
element.value.type ==
SourceType.Screen)
element.value.type ==
SourceType.Screen)
.map((e) => ThumbnailWidget(
onTap: (source) {
if (context.mounted) {
Expand All @@ -136,12 +187,10 @@ class ScreenSelectDialog extends Dialog {
child: GridView.count(
crossAxisSpacing: 8,
crossAxisCount: 3,
children: _sources
.asMap()
.entries
.where((element) =>
element.value.type ==
SourceType.Window)
children: _sources.entries
.where((element) =>
element.value.type ==
SourceType.Window)
.map((e) => ThumbnailWidget(
onTap: (source) {
if (context.mounted) {
Expand Down
36 changes: 32 additions & 4 deletions lib/widgets/common/screen_share/thumbnail_widget.dart
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
import 'dart:async';
import 'dart:typed_data';

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

Expand All @@ -19,6 +22,30 @@ class ThumbnailWidget extends StatefulWidget {
}

class _ThumbnailWidgetState extends State<ThumbnailWidget> {
final List<StreamSubscription> _subscriptions = [];
Uint8List? _thumbnail;
@override
void initState() {
super.initState();
_thumbnail = widget.source.thumbnail;
_subscriptions.add(widget.source.onThumbnailChanged.stream.listen((event) {
setState(() {
_thumbnail = event;
});
}));
_subscriptions.add(widget.source.onNameChanged.stream.listen((event) {
setState(() {});
}));
}

@override
void deactivate() {
for (var element in _subscriptions) {
element.cancel();
}
super.deactivate();
}

@override
Widget build(BuildContext context) {
return Column(
Expand All @@ -32,13 +59,14 @@ class _ThumbnailWidgetState extends State<ThumbnailWidget> {
onTap: () {
widget.onTap(widget.source);
},
child: widget.source.thumbnail != null
? Image.memory(
widget.source.thumbnail!,
child: _thumbnail == null || _thumbnail!.isEmpty
? Container() :
Image.memory(
_thumbnail!,
gaplessPlayback: true,
alignment: Alignment.center,
)
: Container(),
,
),
)),
Text(
Expand Down

0 comments on commit 06cecdf

Please sign in to comment.