android screenshare example and touch ups (#31)
This commit is contained in:
@@ -1,13 +1,17 @@
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="io.livekit.example">
|
||||
|
||||
<uses-feature android:name="android.hardware.camera" />
|
||||
<uses-feature android:name="android.hardware.camera.autofocus" />
|
||||
|
||||
<uses-permission android:name="android.permission.CAMERA" />
|
||||
<uses-permission android:name="android.permission.RECORD_AUDIO" />
|
||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
||||
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
|
||||
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
|
||||
<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
|
||||
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
|
||||
<uses-permission android:name="android.permission.WAKE_LOCK" />
|
||||
<uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS" />
|
||||
<application
|
||||
android:label="LiveKit Example"
|
||||
android:icon="@mipmap/livekit_ic_launcher">
|
||||
@@ -40,6 +44,11 @@
|
||||
<category android:name="android.intent.category.LAUNCHER"/>
|
||||
</intent-filter>
|
||||
</activity>
|
||||
<service
|
||||
android:name="de.julianassmann.flutter_background.IsolateHolderService"
|
||||
android:enabled="true"
|
||||
android:exported="false"
|
||||
android:foregroundServiceType="mediaProjection" />
|
||||
<!-- Don't delete the meta-data below.
|
||||
This is used by the Flutter tool to generate GeneratedPluginRegistrant.java -->
|
||||
<meta-data
|
||||
|
||||
@@ -3,6 +3,7 @@ import 'dart:convert';
|
||||
import 'package:collection/collection.dart';
|
||||
import 'package:eva_icons_flutter/eva_icons_flutter.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_background/flutter_background.dart';
|
||||
import 'package:livekit_client/livekit_client.dart';
|
||||
|
||||
import '../exts.dart';
|
||||
@@ -114,7 +115,6 @@ class _ControlsWidgetState extends State<ControlsWidget> {
|
||||
}
|
||||
|
||||
void _shareScreen() async {
|
||||
//
|
||||
final lp = widget.room.localParticipant;
|
||||
|
||||
for (final track in lp.videoTracks) {
|
||||
@@ -122,6 +122,17 @@ class _ControlsWidgetState extends State<ControlsWidget> {
|
||||
}
|
||||
|
||||
try {
|
||||
// Required for android screenshare.
|
||||
const androidConfig = FlutterBackgroundAndroidConfig(
|
||||
notificationTitle: 'Screen Sharing',
|
||||
notificationText: 'LiveKit Example is sharing the screen.',
|
||||
notificationImportance: AndroidNotificationImportance.Default,
|
||||
notificationIcon:
|
||||
AndroidResource(name: 'livekit_ic_launcher', defType: 'mipmap'),
|
||||
);
|
||||
await FlutterBackground.initialize(androidConfig: androidConfig);
|
||||
await FlutterBackground.enableBackgroundExecution();
|
||||
|
||||
final screenTrack =
|
||||
await LocalVideoTrack.createScreenTrack(); // Defaults to camera
|
||||
await widget.room.localParticipant.publishVideoTrack(
|
||||
@@ -132,6 +143,17 @@ class _ControlsWidgetState extends State<ControlsWidget> {
|
||||
}
|
||||
}
|
||||
|
||||
void _unshareScreen() async {
|
||||
final lp = widget.room.localParticipant;
|
||||
|
||||
try {
|
||||
await lp.setScreenShareEnabled(false);
|
||||
await FlutterBackground.disableBackgroundExecution();
|
||||
} catch (e) {
|
||||
print('error disabling screen share: $e');
|
||||
}
|
||||
}
|
||||
|
||||
void _onTapDisconnect() async {
|
||||
final result = await context.showDisconnectDialog();
|
||||
if (result == true) await widget.room.disconnect();
|
||||
@@ -156,8 +178,12 @@ class _ControlsWidgetState extends State<ControlsWidget> {
|
||||
// mute audio
|
||||
final canMute = participant.hasAudio && !participant.isMuted;
|
||||
|
||||
final videoPub = participant.videoTracks.firstOrNull;
|
||||
final videoPub =
|
||||
participant.getTrackPublicationBySource(TrackSource.camera);
|
||||
final videoEnabled = videoPub != null && !videoPub.muted;
|
||||
final screenSharePub =
|
||||
participant.getTrackPublicationBySource(TrackSource.screenShareVideo);
|
||||
final screenShareEnabled = screenSharePub != null && !screenSharePub.muted;
|
||||
|
||||
return Padding(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
@@ -205,11 +231,18 @@ class _ControlsWidgetState extends State<ControlsWidget> {
|
||||
onPressed: () => _toggleCamera(),
|
||||
tooltip: 'toggle camera',
|
||||
),
|
||||
IconButton(
|
||||
icon: const Icon(EvaIcons.monitor),
|
||||
onPressed: () => _shareScreen(),
|
||||
tooltip: 'share screen (experimental)',
|
||||
),
|
||||
if (screenShareEnabled)
|
||||
IconButton(
|
||||
icon: const Icon(EvaIcons.monitorOutline),
|
||||
onPressed: () => _unshareScreen(),
|
||||
tooltip: 'unshare screen (experimental)',
|
||||
)
|
||||
else
|
||||
IconButton(
|
||||
icon: const Icon(EvaIcons.monitor),
|
||||
onPressed: () => _shareScreen(),
|
||||
tooltip: 'share screen (experimental)',
|
||||
),
|
||||
IconButton(
|
||||
onPressed: _onTapDisconnect,
|
||||
icon: const Icon(EvaIcons.closeCircle),
|
||||
|
||||
+26
-5
@@ -90,6 +90,13 @@ packages:
|
||||
description: flutter
|
||||
source: sdk
|
||||
version: "0.0.0"
|
||||
flutter_background:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: flutter_background
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.0.2+2"
|
||||
flutter_lints:
|
||||
dependency: "direct dev"
|
||||
description:
|
||||
@@ -218,6 +225,20 @@ packages:
|
||||
name: path_provider
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.0.7"
|
||||
path_provider_android:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: path_provider_android
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.0.6"
|
||||
path_provider_ios:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: path_provider_ios
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.0.6"
|
||||
path_provider_linux:
|
||||
dependency: transitive
|
||||
@@ -225,7 +246,7 @@ packages:
|
||||
name: path_provider_linux
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.1.0"
|
||||
version: "2.1.1"
|
||||
path_provider_macos:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -246,7 +267,7 @@ packages:
|
||||
name: path_provider_windows
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.0.3"
|
||||
version: "2.0.4"
|
||||
petitparser:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -302,7 +323,7 @@ packages:
|
||||
name: shared_preferences_linux
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.0.2"
|
||||
version: "2.0.3"
|
||||
shared_preferences_macos:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -330,7 +351,7 @@ packages:
|
||||
name: shared_preferences_windows
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.0.2"
|
||||
version: "2.0.3"
|
||||
sky_engine:
|
||||
dependency: transitive
|
||||
description: flutter
|
||||
@@ -419,7 +440,7 @@ packages:
|
||||
name: win32
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.2.10"
|
||||
version: "2.3.0"
|
||||
xdg_directories:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
||||
@@ -11,6 +11,7 @@ dependencies:
|
||||
flutter:
|
||||
sdk: flutter
|
||||
|
||||
flutter_background: 1.0.2+2
|
||||
provider: ^6.0.1
|
||||
logging: ^1.0.1
|
||||
shared_preferences: ^2.0.7
|
||||
|
||||
Reference in New Issue
Block a user