Skip to content

Commit

Permalink
Merge pull request #131 from AgoraIO-Community/update-cloud-recording
Browse files Browse the repository at this point in the history
update to new cloud recording schema
  • Loading branch information
tadaspetra authored Apr 18, 2023
2 parents 279a812 + 3bf070e commit 2d1dd20
Show file tree
Hide file tree
Showing 9 changed files with 121 additions and 40 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
## 1.3.2

- Added callback for cloud recording destination URL
- Added loading state for cloud recording button
- Update to use new cloud recording schema

## 1.3.1

- BUG FIX: No longer shows cloud recording by default. Need to enable it with `cloudRecordingEnabled: true`
Expand Down
23 changes: 18 additions & 5 deletions lib/controllers/rtc_buttons.dart
Original file line number Diff line number Diff line change
Expand Up @@ -127,16 +127,29 @@ Future<void> _showRPSystemBroadcastPickerViewIfNeed() async {

/// Function to start and stop cloud recording
Future<void> toggleCloudRecording({required AgoraClient client}) async {
if (client.sessionController.value.isCloudRecording) {
if (client.sessionController.value.isCloudRecording ==
RecordingState.recording) {
//stop cloud recording
client.sessionController.value = client.sessionController.value.copyWith(
isCloudRecording: RecordingState.loading,
);
await client.sessionController
.stopCloudRecording(connectionData: client.agoraConnectionData);
} else {
client.sessionController.value = client.sessionController.value.copyWith(
isCloudRecording: RecordingState.off,
);
} else if (client.sessionController.value.isCloudRecording ==
RecordingState.off) {
//start cloud recording
client.sessionController.value = client.sessionController.value.copyWith(
isCloudRecording: RecordingState.loading,
);
await client.sessionController
.startCloudRecording(connectionData: client.agoraConnectionData);
client.sessionController.value = client.sessionController.value.copyWith(
isCloudRecording: RecordingState.recording,
);
} else {
//do nothing
}

client.sessionController.value = client.sessionController.value.copyWith(
isCloudRecording: !(client.sessionController.value.isCloudRecording));
}
29 changes: 18 additions & 11 deletions lib/controllers/session_controller.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import 'dart:async';
import 'dart:convert';
import 'dart:developer';
import 'dart:io';

import 'package:agora_rtc_engine/agora_rtc_engine.dart';
import 'package:agora_rtm/agora_rtm.dart';
Expand Down Expand Up @@ -288,13 +289,17 @@ class SessionController extends ValueNotifier<AgoraSettings> {
Future<void> startCloudRecording(
{required AgoraConnectionData connectionData}) async {
final response = await http.post(
Uri.parse('${connectionData.cloudRecordingUrl}/api/start/call'),
body: {"channel": connectionData.channelName},
Uri.parse(
'${connectionData.cloudRecordingUrl}/start-recording/${connectionData.channelName}'),
);

if (response.statusCode == 200) {
log('Recording Started', level: Level.warning.value);
value = value.copyWith(sid: jsonDecode(response.body)['data']['sid']);
if (response.statusCode == HttpStatus.ok) {
value = value.copyWith(
sid: jsonDecode(response.body)['sid'],
resourceId: jsonDecode(response.body)['resource_id'],
);
log('Recording Started with SID ${value.sid} and RESOURCE ID: ${value.resourceId}',
level: Level.warning.value);
} else {
log('Couldn\'t start the recording : ${response.statusCode}',
level: Level.error.value);
Expand All @@ -304,15 +309,17 @@ class SessionController extends ValueNotifier<AgoraSettings> {
Future<void> stopCloudRecording(
{required AgoraConnectionData connectionData}) async {
final response = await http.post(
Uri.parse('${connectionData.cloudRecordingUrl}/api/stop/call'),
body: {
"channel": connectionData.channelName,
"sid": value.sid,
},
Uri.parse(
'${connectionData.cloudRecordingUrl}/stop-recording/${connectionData.channelName}/${value.sid}/${value.resourceId}'),
);

if (response.statusCode == 200) {
if (response.statusCode == HttpStatus.ok) {
log('Recording Ended', level: Level.warning.value);
if (connectionData.cloudRecordingCallback != null) {
connectionData.cloudRecordingCallback!(
jsonDecode(response.body)['mp4_link'],
jsonDecode(response.body)['m3u8_link']);
}
} else {
log('Couldn\'t end the recording : ${response.statusCode}',
level: Level.error.value);
Expand Down
6 changes: 6 additions & 0 deletions lib/models/agora_connection_data.dart
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ class AgoraConnectionData {

final bool screenSharingEnabled;

final Function? cloudRecordingCallback;

AgoraConnectionData({
required this.appId,
required this.channelName,
Expand All @@ -55,6 +57,7 @@ class AgoraConnectionData {
this.rtmEnabled = true,
this.screenSharingUid = 1000,
this.screenSharingEnabled = true,
this.cloudRecordingCallback,
});

AgoraConnectionData copyWith({
Expand All @@ -72,6 +75,7 @@ class AgoraConnectionData {
bool? rtmEnabled,
int? screenSharingUid,
bool? screenSharingEnabled,
Function? cloudRecordingCallback,
}) {
return AgoraConnectionData(
appId: appId ?? this.appId,
Expand All @@ -88,6 +92,8 @@ class AgoraConnectionData {
rtmEnabled: rtmEnabled ?? this.rtmEnabled,
screenSharingUid: screenSharingUid ?? this.screenSharingUid,
screenSharingEnabled: screenSharingEnabled ?? this.screenSharingEnabled,
cloudRecordingCallback:
cloudRecordingCallback ?? this.cloudRecordingCallback,
);
}
}
2 changes: 1 addition & 1 deletion lib/models/agora_rtm_mute_request.dart
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ class AgoraUIKit {
String platform = platformStr();

String framework = "flutter";
String version = "1.3.1";
String version = "1.3.2";

AgoraUIKit.fromJson(Map<String, dynamic> json)
: platform = json['platform'],
Expand Down
10 changes: 7 additions & 3 deletions lib/models/agora_settings.dart
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,9 @@ class AgoraSettings {
final Map<int, String>? uidToUserIdMap;
final bool isScreenShared;
final bool turnOnScreenSharing;
final bool isCloudRecording;
final RecordingState isCloudRecording;
final String? sid;
final String? resourceId;

AgoraSettings({
this.engine,
Expand Down Expand Up @@ -66,8 +67,9 @@ class AgoraSettings {
this.uidToUserIdMap,
this.isScreenShared = false,
this.turnOnScreenSharing = false,
this.isCloudRecording = false,
this.isCloudRecording = RecordingState.off,
this.sid,
this.resourceId,
});

AgoraSettings copyWith({
Expand Down Expand Up @@ -99,8 +101,9 @@ class AgoraSettings {
Map<int, String>? uidToUserIdMap,
bool? isScreenShared,
bool? turnOnScreenSharing,
bool? isCloudRecording,
RecordingState? isCloudRecording,
String? sid,
String? resourceId,
}) {
return AgoraSettings(
engine: engine ?? this.engine,
Expand Down Expand Up @@ -134,6 +137,7 @@ class AgoraSettings {
turnOnScreenSharing: turnOnScreenSharing ?? this.turnOnScreenSharing,
isCloudRecording: isCloudRecording ?? this.isCloudRecording,
sid: sid ?? this.sid,
resourceId: resourceId ?? this.resourceId,
);
}
}
81 changes: 62 additions & 19 deletions lib/src/buttons/cloud_recording_button.dart
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import 'package:agora_uikit/agora_uikit.dart';
import 'package:agora_uikit/controllers/rtc_buttons.dart';
import 'package:flutter/material.dart';

import '../agora_client.dart';

class CloudRecordingButton extends StatelessWidget {
final Widget? child;
final AgoraClient client;
Expand All @@ -19,23 +18,67 @@ class CloudRecordingButton extends StatelessWidget {
onPressed: () => toggleCloudRecording(client: client),
child: child,
)
: RawMaterialButton(
onPressed: () => toggleCloudRecording(client: client),
child: Icon(
client.sessionController.value.isCloudRecording
? Icons.stop
: Icons.circle_outlined,
color: client.sessionController.value.isCloudRecording
? Colors.white
: Colors.blueAccent,
size: 20.0,
),
shape: CircleBorder(),
elevation: 2.0,
fillColor: client.sessionController.value.isCloudRecording
? Colors.blueAccent
: Colors.white,
padding: const EdgeInsets.all(12.0),
: RecordingStateButton(
client: client,
);
}
}

class RecordingStateButton extends StatelessWidget {
final AgoraClient client;
const RecordingStateButton({Key? key, required this.client})
: super(key: key);

@override
Widget build(BuildContext context) {
switch (client.sessionController.value.isCloudRecording) {
case RecordingState.off:
return RawMaterialButton(
onPressed: () => toggleCloudRecording(client: client),
child: Icon(
Icons.circle_outlined,
color: Colors.blueAccent,
size: 20.0,
),
shape: CircleBorder(),
elevation: 2.0,
fillColor: Colors.white,
padding: const EdgeInsets.all(12.0),
);
case RecordingState.loading:
return RawMaterialButton(
onPressed: () {},
child: Container(
height: 20,
width: 20,
padding: const EdgeInsets.all(2),
child: CircularProgressIndicator(
strokeWidth: 2,
),
),
shape: CircleBorder(),
elevation: 2.0,
fillColor: Colors.white,
padding: const EdgeInsets.all(12.0),
);
case RecordingState.recording:
return RawMaterialButton(
onPressed: () => toggleCloudRecording(client: client),
child: Icon(
Icons.stop,
color: Colors.white,
size: 20.0,
),
shape: CircleBorder(),
elevation: 2.0,
fillColor: Colors.blueAccent,
padding: const EdgeInsets.all(12.0),
);
default:
return RawMaterialButton(
onPressed: () {},
child: CircularProgressIndicator(),
);
}
}
}
2 changes: 2 additions & 0 deletions lib/src/enums.dart
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,5 @@ extension LevelExtension on Level {
}

enum Device { camera, mic }

enum RecordingState { off, loading, recording }
2 changes: 1 addition & 1 deletion pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name: agora_uikit
description: Flutter plugin to simply integrate Agora Video Calling or Live
Video Streaming to your app with just a few lines of code.
version: 1.3.1
version: 1.3.2
homepage: https://www.agora.io/en/
repository: https://github.com/AgoraIO-Community/VideoUIKit-Flutter

Expand Down

0 comments on commit 2d1dd20

Please sign in to comment.