Closed develocode777 closed 6 months ago
When I run the app in Visual studio it shows me this error:
I have found a workaround, if I set _localUserJoined = false
before calling engine.release()
then it does not crash anymore:
_localUserJoined ? SizedBox( width: 180, height: 120, child: AgoraVideoView( controller: VideoViewController( rtcEngine: _engine, canvas: VideoCanvas(uid: 0), ), ), ) : const CircularProgressIndicator(),
Thanks for your reporting, can you provide a reproducible demo for this case so that we can investigate this issue more easily?
flutter_window.cpp:
#include "flutter_window.h"
#include <optional>
#include "flutter/generated_plugin_registrant.h"
#include "desktop_multi_window/desktop_multi_window_plugin.h"
#include <agora_rtc_engine/agora_rtc_engine_plugin.h>
#include <iris_method_channel/iris_method_channel_plugin_c_api.h>
FlutterWindow::FlutterWindow(const flutter::DartProject &project)
: project_(project) {}
FlutterWindow::~FlutterWindow() {}
bool FlutterWindow::OnCreate()
{
if (!Win32Window::OnCreate())
{
return false;
}
RECT frame = GetClientArea();
flutter_controller_ = std::make_unique<flutter::FlutterViewController>(
frame.right - frame.left, frame.bottom - frame.top, project_);
if (!flutter_controller_->engine() || !flutter_controller_->view())
{
return false;
}
RegisterPlugins(flutter_controller_->engine());
DesktopMultiWindowSetWindowCreatedCallback([](void *controller)
{
auto *flutter_view_controller =
reinterpret_cast<flutter::FlutterViewController *>(controller);
auto *registry = flutter_view_controller->engine();
AgoraRtcEnginePluginRegisterWithRegistrar(
registry->GetRegistrarForPlugin("AgoraRtcEnginePlugin"));
IrisMethodChannelPluginCApiRegisterWithRegistrar(
registry->GetRegistrarForPlugin("IrisMethodChannelPluginCApi")); });
SetChildContent(flutter_controller_->view()->GetNativeWindow());
flutter_controller_->engine()->SetNextFrameCallback([&]()
{ this->Show(); });
flutter_controller_->ForceRedraw();
return true;
}
void FlutterWindow::OnDestroy()
{
if (flutter_controller_)
{
flutter_controller_ = nullptr;
}
Win32Window::OnDestroy();
}
LRESULT
FlutterWindow::MessageHandler(HWND hwnd, UINT const message,
WPARAM const wparam,
LPARAM const lparam) noexcept
{
if (flutter_controller_)
{
std::optional<LRESULT> result =
flutter_controller_->HandleTopLevelWindowProc(hwnd, message, wparam,
lparam);
if (result)
{
return *result;
}
}
switch (message)
{
case WM_FONTCHANGE:
flutter_controller_->engine()->ReloadSystemFonts();
break;
}
return Win32Window::MessageHandler(hwnd, message, wparam, lparam);
}
main.dart:
import 'package:agora_rtc_engine/agora_rtc_engine.dart';
import 'package:desktop_multi_window/desktop_multi_window.dart';
import 'package:flutter/material.dart';
void main(List<String> args) {
if (args.firstOrNull == 'multi_window') {
runApp(AgoraApp());
} else {
runApp(const MainApp());
}
}
class MainApp extends StatelessWidget {
const MainApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: Center(
child: ElevatedButton(
onPressed: () async {
final window =
await DesktopMultiWindow.createWindow(jsonEncode({
'args1': 'Sub window',
'args2': 100,
'args3': true,
'bussiness': 'bussiness_test',
}));
window
..setFrame(const Offset(0, 0) & const Size(1280, 720))
..center()
..setTitle('Another window')
..show();
},
child: Text('open window')),
),
),
);
}
}
class AgoraApp extends StatefulWidget {
const AgoraApp({super.key});
@override
State<AgoraApp> createState() => _AgoraAppState();
}
class _AgoraAppState extends State<AgoraApp> {
final String channel = 'test';
bool _localUserJoined = false;
late RtcEngine _engine;
@override
void initState() {
super.initState();
initAgora();
}
Future<void> initAgora() async {
_engine = createAgoraRtcEngine();
await _engine.initialize(RtcEngineContext(
appId: '',
channelProfile: ChannelProfileType.channelProfileLiveBroadcasting,
));
_engine.registerEventHandler(RtcEngineEventHandler(
onError: (err, msg) {
print(err);
print(msg);
},
onJoinChannelSuccess: (RtcConnection connection, int elapsed) {
debugPrint("local user ${connection.localUid} joined");
setState(() {
_localUserJoined = true;
});
},
onUserJoined: (RtcConnection connection, int rUid, int elapsed) {
debugPrint("remote user $rUid joined");
},
onUserOffline:
(RtcConnection connection, int rUid, UserOfflineReasonType reason) {
debugPrint("remote user $rUid left channel");
},
onTokenPrivilegeWillExpire: (RtcConnection connection, String token) {
debugPrint(
'[onTokenPrivilegeWillExpire] connection: ${connection.toJson()}, token: $token');
},
));
await _engine.setClientRole(role: ClientRoleType.clientRoleBroadcaster);
await _engine.enableVideo();
await _engine.startPreview();
await _engine.joinChannel(
token:
'',
channelId: channel,
uid: 0,
options: const ChannelMediaOptions(),
);
_localUserJoined = true;
setState(() {});
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
_localUserJoined
? SizedBox(
width: 180,
height: 120,
child: AgoraVideoView(
controller: VideoViewController(
rtcEngine: _engine,
canvas: VideoCanvas(uid: 0),
),
),
)
: const CircularProgressIndicator(),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
ElevatedButton(
onPressed: () async {
await _engine.leaveChannel();
await _engine.release();
},
child: Text('leave channel and release engine'))
],
),
],
),
),
);
}
}
if I close the window by pressing the x in the upper right the whole flutter app crashes without giving an error message, this happens only if I call _engine.release() before closing.
Based on your code, does it mean you click the "leave channel and release engine" button, and then click the x of the window?
Yes
This thread has been automatically locked since there has not been any recent activity after it was closed. If you are still experiencing a similar issue, please raise a new issue.
Hello,
I use desktop_multi_window to run agora in a secondary window, if I close the window by pressing the x in the upper right the whole flutter app crashes without giving an error message, this happens only if I call
_engine.release()
before closing. On macos there is no problem.