From 0736345acdc2a72569532c0469f394cbce4e7aed Mon Sep 17 00:00:00 2001 From: youngq Date: Mon, 9 Dec 2024 16:40:12 +0800 Subject: [PATCH] 1 --- .../Converters/AspectRatioConverter.cs | 39 +++++ .../Converters/BooleanInverseConverter.cs | 23 +++ Demo.Common/Demo.Common.csproj | 16 ++ Demo.Common/Dtos/BaseApiResult.cs | 15 ++ Demo.Common/Dtos/LoginApiResponse.cs | 18 +++ .../Events/AudioVolumeIndicationEvent.cs | 14 ++ Demo.Common/Events/UserJoinEvent.cs | 14 ++ Demo.Common/Events/UserLeaveEvent.cs | 14 ++ Demo.Common/Extensions/RestClientExtension.cs | 33 ++++ Demo.Common/Helpers/AgoraHelper.cs | 123 +++++++++++++++ Demo.Common/Helpers/RtcEngineEventHandler.cs | 58 +++++++ Demo.Common/Models/User.cs | 48 ++++++ Demo.Common/Models/UserInfo.cs | 15 -- Demo.Common/TestCredentials.cs | 13 ++ .../Demo.Services.Interfaces.csproj | 10 ++ .../IAgoraConfigService.cs | 13 ++ .../IAgoraEngineService.cs | 12 ++ Demo.Services.Interfaces/IAuthService.cs | 13 ++ Demo.Services.Interfaces/IBaseService.cs | 11 ++ Demo.Services/AgoraConfigService.cs | 38 +++++ Demo.Services/AgoraEngineService.cs | 20 +++ Demo.Services/AuthService.cs | 29 ++++ Demo.Services/BaseService.cs | 17 +++ Demo.Services/Demo.Services.csproj | 19 +++ Meeting.V2.Demo.sln | 46 ++++-- Meeting.V2.Demo/Meeting.V2.Demo/App.xaml | 1 + Meeting.V2.Demo/Meeting.V2.Demo/App.xaml.cs | 23 ++- .../Configure/ConfigureService.cs | 26 +++- .../Configure/IConfigureService.cs | 3 +- .../Meeting.V2.Demo/Meeting.V2.Demo.csproj | 7 +- .../ViewModels/MainWindowViewModel.cs | 105 ++++++++++++- .../ViewModels/VideoAreaViewModel.cs | 143 +++++++++++++----- .../ViewModels/VideoViewModel.cs | 84 ++++++++-- .../Meeting.V2.Demo/Views/MainWindow.xaml | 54 ++++++- .../Meeting.V2.Demo/Views/VideoAreaView.xaml | 64 +++++++- .../Views/VideoAreaView.xaml.cs | 4 +- .../Meeting.V2.Demo/Views/VideoView.xaml | 24 ++- .../Meeting.V2.Demo/Views/VideoView.xaml.cs | 128 +++++++--------- .../IMessageService.cs | 7 - ...Meeting.V2.Demo.Services.Interfaces.csproj | 4 + .../IAgoraConfigService.cs | 12 ++ .../Meeting.V2.Demo.Services/IBaseService.cs | 11 ++ .../Meeting.V2.Demo.Services.csproj | 1 + .../MessageService.cs | 12 -- 44 files changed, 1172 insertions(+), 212 deletions(-) create mode 100644 Demo.Common/Converters/AspectRatioConverter.cs create mode 100644 Demo.Common/Converters/BooleanInverseConverter.cs create mode 100644 Demo.Common/Dtos/BaseApiResult.cs create mode 100644 Demo.Common/Dtos/LoginApiResponse.cs create mode 100644 Demo.Common/Events/AudioVolumeIndicationEvent.cs create mode 100644 Demo.Common/Events/UserJoinEvent.cs create mode 100644 Demo.Common/Events/UserLeaveEvent.cs create mode 100644 Demo.Common/Extensions/RestClientExtension.cs create mode 100644 Demo.Common/Helpers/AgoraHelper.cs create mode 100644 Demo.Common/Helpers/RtcEngineEventHandler.cs create mode 100644 Demo.Common/Models/User.cs delete mode 100644 Demo.Common/Models/UserInfo.cs create mode 100644 Demo.Common/TestCredentials.cs create mode 100644 Demo.Services.Interfaces/Demo.Services.Interfaces.csproj create mode 100644 Demo.Services.Interfaces/IAgoraConfigService.cs create mode 100644 Demo.Services.Interfaces/IAgoraEngineService.cs create mode 100644 Demo.Services.Interfaces/IAuthService.cs create mode 100644 Demo.Services.Interfaces/IBaseService.cs create mode 100644 Demo.Services/AgoraConfigService.cs create mode 100644 Demo.Services/AgoraEngineService.cs create mode 100644 Demo.Services/AuthService.cs create mode 100644 Demo.Services/BaseService.cs create mode 100644 Demo.Services/Demo.Services.csproj delete mode 100644 Meeting.V2.Demo/Services/Meeting.V2.Demo.Services.Interfaces/IMessageService.cs create mode 100644 Meeting.V2.Demo/Services/Meeting.V2.Demo.Services/IAgoraConfigService.cs create mode 100644 Meeting.V2.Demo/Services/Meeting.V2.Demo.Services/IBaseService.cs delete mode 100644 Meeting.V2.Demo/Services/Meeting.V2.Demo.Services/MessageService.cs diff --git a/Demo.Common/Converters/AspectRatioConverter.cs b/Demo.Common/Converters/AspectRatioConverter.cs new file mode 100644 index 0000000..8c79474 --- /dev/null +++ b/Demo.Common/Converters/AspectRatioConverter.cs @@ -0,0 +1,39 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Data; + +namespace Demo.Common.Converters +{ + public class AspectRatioConverter : IMultiValueConverter + { + private readonly double ratio = 1.777; + + public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture) + { + if (values.Length == 2 && values[0] is double height && values[1] is double maxWidth) + { + Console.WriteLine($@"height {height} maxWidth {maxWidth}"); + var controlWidth = height * ratio; + return controlWidth > maxWidth ? maxWidth : controlWidth; + } + //else if (values.Length == 4 && values[0] is double stackHeight + // && values[1] is double stackWidth && values[2] is int userPageSize + // && values[3] is Thickness margin) + //{ + // var controlWidth = stackHeight * ratio; + //} + return 0; + } + + public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture) + { + throw new NotImplementedException(); + } + } +} + diff --git a/Demo.Common/Converters/BooleanInverseConverter.cs b/Demo.Common/Converters/BooleanInverseConverter.cs new file mode 100644 index 0000000..fda79da --- /dev/null +++ b/Demo.Common/Converters/BooleanInverseConverter.cs @@ -0,0 +1,23 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Data; + +namespace Demo.Common.Converters +{ + public class BooleanInverseConverter : IValueConverter + { + public object Convert(object value, Type targetType, object parameter, CultureInfo culture) + { + return value is bool boolValue ? !boolValue : false; + } + + public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) + { + return value is bool boolValue ? !boolValue : false; + } + } +} diff --git a/Demo.Common/Demo.Common.csproj b/Demo.Common/Demo.Common.csproj index 89541cf..2e71b64 100644 --- a/Demo.Common/Demo.Common.csproj +++ b/Demo.Common/Demo.Common.csproj @@ -5,6 +5,22 @@ enable true enable + AnyCPU;x64 + false + + + + + + + + + + + PreserveNewest + + + diff --git a/Demo.Common/Dtos/BaseApiResult.cs b/Demo.Common/Dtos/BaseApiResult.cs new file mode 100644 index 0000000..b72b0f4 --- /dev/null +++ b/Demo.Common/Dtos/BaseApiResult.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Demo.Common.Dtos +{ + public class BaseApiResult + { + public int code { get; set; } + public string message { get; set; } + public T Data { get; set; } + } +} diff --git a/Demo.Common/Dtos/LoginApiResponse.cs b/Demo.Common/Dtos/LoginApiResponse.cs new file mode 100644 index 0000000..a6d1523 --- /dev/null +++ b/Demo.Common/Dtos/LoginApiResponse.cs @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Demo.Common.Dtos +{ + public class LoginApiResponse + { + public string token { get; set; } + public string refresh_token { get; set; } + + public string userName { get; set; } + public int expire { get; set; } + public string uid { get; set; } + } +} diff --git a/Demo.Common/Events/AudioVolumeIndicationEvent.cs b/Demo.Common/Events/AudioVolumeIndicationEvent.cs new file mode 100644 index 0000000..de719ed --- /dev/null +++ b/Demo.Common/Events/AudioVolumeIndicationEvent.cs @@ -0,0 +1,14 @@ +using Agora.Rtc; +using Prism.Events; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Demo.Common.Events +{ + public class AudioVolumeIndicationEvent : PubSubEvent + { + } +} diff --git a/Demo.Common/Events/UserJoinEvent.cs b/Demo.Common/Events/UserJoinEvent.cs new file mode 100644 index 0000000..83910bf --- /dev/null +++ b/Demo.Common/Events/UserJoinEvent.cs @@ -0,0 +1,14 @@ +using Demo.Common.Models; +using Prism.Events; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Demo.Common.Events +{ + public class UserJoinEvent : PubSubEvent + { + } +} diff --git a/Demo.Common/Events/UserLeaveEvent.cs b/Demo.Common/Events/UserLeaveEvent.cs new file mode 100644 index 0000000..c4f3400 --- /dev/null +++ b/Demo.Common/Events/UserLeaveEvent.cs @@ -0,0 +1,14 @@ +using Demo.Common.Models; +using Prism.Events; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Demo.Common.Events +{ + public class UserLeaveEvent : PubSubEvent + { + } +} diff --git a/Demo.Common/Extensions/RestClientExtension.cs b/Demo.Common/Extensions/RestClientExtension.cs new file mode 100644 index 0000000..a4e5fa6 --- /dev/null +++ b/Demo.Common/Extensions/RestClientExtension.cs @@ -0,0 +1,33 @@ +using Demo.Common.Dtos; +using Newtonsoft.Json.Linq; +using RestSharp; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Runtime.CompilerServices; +using System.Text; +using System.Text.RegularExpressions; +using System.Threading.Tasks; +using System.Windows; +using DataFormat = RestSharp.DataFormat; + +namespace Demo.Common.Extensions +{ + public static class RestClientExtension + { + public static async Task PostAsync(this RestClient client, TBody body) where TResult : class where TBody : class + { + RestRequest request = new RestRequest(); + request.Method = Method.Post; + request.RequestFormat = DataFormat.Json; + request.AddOrUpdateHeader("Authorization", $"Bearer {Application.Current.Properties["token"]}"); + request.AddJsonBody(body); + var result = await client.PostAsync>(request); + if (result.code != 200) + { + return result.Data; + } + return null; + } + } +} diff --git a/Demo.Common/Helpers/AgoraHelper.cs b/Demo.Common/Helpers/AgoraHelper.cs new file mode 100644 index 0000000..6f48fc2 --- /dev/null +++ b/Demo.Common/Helpers/AgoraHelper.cs @@ -0,0 +1,123 @@ +using Agora.Rtc; +using Masuit.Tools.Systems; +using System; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Demo.Common.Helpers +{ + public class AgoraHelper : IRtcEngineEventHandler + { + private static uint _localUId; + public static IRtcEngine _RtcEngineInstance; + public static int Init(string appId, uint localUid = 0) + { + if (null == _RtcEngineInstance) + { + _RtcEngineInstance = RtcEngine.CreateAgoraRtcEngine(); + } + RtcEngineContext rtc_engine_ctx = new RtcEngineContext(); + rtc_engine_ctx.appId = appId; + var ret = _RtcEngineInstance.Initialize(rtc_engine_ctx); + + ret = _RtcEngineInstance.InitEventHandler(new RtcEngineEventHandler()); + + _localUId = localUid; + return ret; + } + + public static int UnInit() + { + if (null != _RtcEngineInstance) + { + // Dispose engine + _RtcEngineInstance.Dispose(); + _RtcEngineInstance = null; + } + + return 0; + } + + /// + /// 渲染用户视频 + /// + /// + /// + /// + public static int SetupUserVideo(uint uid, long controlHandle) + { + if (_localUId == uid) + { + // 本地用户 + return _RtcEngineInstance.SetupLocalVideo(new VideoCanvas + { + view = controlHandle, + renderMode = RENDER_MODE_TYPE.RENDER_MODE_HIDDEN, + mirrorMode = VIDEO_MIRROR_MODE_TYPE.VIDEO_MIRROR_MODE_DISABLED, + uid = uid, + setupMode = VIDEO_VIEW_SETUP_MODE.VIDEO_VIEW_SETUP_ADD + }); + } + else + { + return _RtcEngineInstance.SetupRemoteVideo(new VideoCanvas + { + view = controlHandle, + renderMode = RENDER_MODE_TYPE.RENDER_MODE_HIDDEN, + mirrorMode = VIDEO_MIRROR_MODE_TYPE.VIDEO_MIRROR_MODE_DISABLED, + uid = uid, + setupMode = VIDEO_VIEW_SETUP_MODE.VIDEO_VIEW_SETUP_ADD + }); + } + } + + /// + /// 清除已渲染的用户视频 + /// + /// + /// + /// + public static int ClearUserVideo(uint uid, long controlHandle) + { + if (_localUId == uid) + { + // 本地用户 + // 删除用户渲染 + return _RtcEngineInstance.SetupLocalVideo(new VideoCanvas + { + view = controlHandle, + uid = uid, + setupMode = VIDEO_VIEW_SETUP_MODE.VIDEO_VIEW_SETUP_REMOVE + }); + } + else + { + return _RtcEngineInstance.SetupRemoteVideo(new VideoCanvas + { + view = controlHandle, + uid = uid, + setupMode = VIDEO_VIEW_SETUP_MODE.VIDEO_VIEW_SETUP_REMOVE + }); + } + } + + /// + /// 渲染用户视频 + /// + /// + /// + /// + /// + public static int SetupUserVideo(uint uid, long controlHandle, uint delUid = 0) + { + if (delUid > 0) + { + ClearUserVideo(delUid, controlHandle); + } + return SetupUserVideo(uid, controlHandle); + } + } +} diff --git a/Demo.Common/Helpers/RtcEngineEventHandler.cs b/Demo.Common/Helpers/RtcEngineEventHandler.cs new file mode 100644 index 0000000..f75435d --- /dev/null +++ b/Demo.Common/Helpers/RtcEngineEventHandler.cs @@ -0,0 +1,58 @@ +using Agora.Rtc; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Prism.Ioc; +using Prism.Events; +using Demo.Common.Events; +using Masuit.Tools; + +namespace Demo.Common.Helpers +{ + public class RtcEngineEventHandler : IRtcEngineEventHandler + { + private readonly IEventAggregator aggregator; + public RtcEngineEventHandler() + { + aggregator = ContainerLocator.Container.Resolve(); + } + + public override void OnUserJoined(RtcConnection connection, uint remoteUid, int elapsed) + { + //base.OnUserJoined(connection, remoteUid, elapsed); + Console.WriteLine($@"新用户加入: channelId:{connection.channelId} localuid: {connection.localUid} remoteuid:{remoteUid} elapsed: {elapsed}"); + + + //var aggregator = ContainerLocator.Container.Resolve(); + aggregator.GetEvent().Publish(new Models.User + { + Id = remoteUid, + UserName = remoteUid.ToString(), + IsManager = true, + IsLocal = false + }); + } + + + public override void OnUserOffline(RtcConnection connection, uint remoteUid, USER_OFFLINE_REASON_TYPE reason) + { + //var aggregator = ContainerLocator.Container.Resolve(); + aggregator.GetEvent().Publish(new Models.User + { + Id = remoteUid, + UserName = remoteUid.ToString(), + IsManager = true, + IsLocal = false + }); + } + + public override void OnAudioVolumeIndication(RtcConnection connection, AudioVolumeInfo[] speakers, uint speakerNumber, int totalVolume) + { + + //aggregator.GetEvent().Publish(); + } + + } +} diff --git a/Demo.Common/Models/User.cs b/Demo.Common/Models/User.cs new file mode 100644 index 0000000..620218c --- /dev/null +++ b/Demo.Common/Models/User.cs @@ -0,0 +1,48 @@ +using Prism.Mvvm; +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Demo.Common.Models +{ + public class User : BindableBase + { + private long id; + public long Id + { + get { return id; } + set { SetProperty(ref id, value); } + } + + private string userName; + public string UserName + { + get { return userName; } + set { SetProperty(ref userName, value); } + } + private bool isManager; + public bool IsManager + { + get { return isManager; } + set { SetProperty(ref isManager, value); } + } + + + private bool isLocal; + public bool IsLocal + { + get { return isLocal; } + set { SetProperty(ref isLocal, value); } + } + + //private bool isMain; + //public bool IsMain + //{ + // get { return isMain; } + // set { SetProperty(ref isMain, value); } + //} + } +} diff --git a/Demo.Common/Models/UserInfo.cs b/Demo.Common/Models/UserInfo.cs deleted file mode 100644 index 1706a69..0000000 --- a/Demo.Common/Models/UserInfo.cs +++ /dev/null @@ -1,15 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace Demo.Common.Models -{ - public class UserInfo - { - public long Id { get; set; } - public string UserName { get; set; } - public bool IsManager { get; set; } - } -} diff --git a/Demo.Common/TestCredentials.cs b/Demo.Common/TestCredentials.cs new file mode 100644 index 0000000..372a3c5 --- /dev/null +++ b/Demo.Common/TestCredentials.cs @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Demo.Common +{ + public static class TestCredentials + { + public static string Token { get; set; } + } +} diff --git a/Demo.Services.Interfaces/Demo.Services.Interfaces.csproj b/Demo.Services.Interfaces/Demo.Services.Interfaces.csproj new file mode 100644 index 0000000..5ad0915 --- /dev/null +++ b/Demo.Services.Interfaces/Demo.Services.Interfaces.csproj @@ -0,0 +1,10 @@ + + + + net6.0-windows net6.0 + enable + enable + AnyCPU;x64 + + + diff --git a/Demo.Services.Interfaces/IAgoraConfigService.cs b/Demo.Services.Interfaces/IAgoraConfigService.cs new file mode 100644 index 0000000..0597504 --- /dev/null +++ b/Demo.Services.Interfaces/IAgoraConfigService.cs @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Threading.Tasks; + +namespace Demo.Services.Interfaces +{ + public interface IAgoraConfigService : IBaseService + { + Task GetAgoraConfigAsync(); + Task GetRtcTokenAsync(); + } +} diff --git a/Demo.Services.Interfaces/IAgoraEngineService.cs b/Demo.Services.Interfaces/IAgoraEngineService.cs new file mode 100644 index 0000000..a2789b0 --- /dev/null +++ b/Demo.Services.Interfaces/IAgoraEngineService.cs @@ -0,0 +1,12 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Demo.Services.Interfaces +{ + public interface IAgoraEngineService + { + } +} diff --git a/Demo.Services.Interfaces/IAuthService.cs b/Demo.Services.Interfaces/IAuthService.cs new file mode 100644 index 0000000..ea54010 --- /dev/null +++ b/Demo.Services.Interfaces/IAuthService.cs @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Demo.Services.Interfaces +{ + public interface IAuthService : IBaseService + { + Task LoginAsync(); + } +} diff --git a/Demo.Services.Interfaces/IBaseService.cs b/Demo.Services.Interfaces/IBaseService.cs new file mode 100644 index 0000000..0740f2f --- /dev/null +++ b/Demo.Services.Interfaces/IBaseService.cs @@ -0,0 +1,11 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace Demo.Services.Interfaces +{ + public interface IBaseService + { + + } +} diff --git a/Demo.Services/AgoraConfigService.cs b/Demo.Services/AgoraConfigService.cs new file mode 100644 index 0000000..df27610 --- /dev/null +++ b/Demo.Services/AgoraConfigService.cs @@ -0,0 +1,38 @@ +using Demo.Common.Dtos; +using Demo.Services.Interfaces; +using RestSharp; +using System.Windows; + +namespace Demo.Services +{ + public class AgoraConfigService : BaseService, IAgoraConfigService + { + public async Task GetAgoraConfigAsync() + { + RestRequest request = new RestRequest("home/agora-conf"); + var result = await BaseRestClient.ExecuteAsync>(request); + if (!result.IsSuccessful || result.Data == null) + { + MessageBox.Show(result.ErrorMessage); + return string.Empty; + } + return result.Data.Data; + } + + public async Task GetRtcTokenAsync() + { + var request = new RestRequest("room/tk/rtc?roomNum=999").AddHeader("Authorization", "Bearer " + Application.Current.Properties["token"]); + var result = await BaseRestClient.ExecuteAsync>(request); + + if (result == null || result.Data == null) + { + MessageBox.Show("token 获取失败"); + return string.Empty; + } + + //return result.Data.Data; + + return result.Data.Data; + } + } +} diff --git a/Demo.Services/AgoraEngineService.cs b/Demo.Services/AgoraEngineService.cs new file mode 100644 index 0000000..ab82af3 --- /dev/null +++ b/Demo.Services/AgoraEngineService.cs @@ -0,0 +1,20 @@ +using Agora.Rtc; +using Demo.Services.Interfaces; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Demo.Services +{ + public class AgoraEngineService : IAgoraEngineService + { + private IRtcEngine _rtcEngine; + + public AgoraEngineService() + { + + } + } +} diff --git a/Demo.Services/AuthService.cs b/Demo.Services/AuthService.cs new file mode 100644 index 0000000..db60e86 --- /dev/null +++ b/Demo.Services/AuthService.cs @@ -0,0 +1,29 @@ +using Demo.Common; +using Demo.Common.Dtos; +using Demo.Services.Interfaces; +using RestSharp; +using System.Windows; + +namespace Demo.Services +{ + public class AuthService : BaseService, IAuthService + { + public async Task LoginAsync() + { + var restRequest = new RestRequest("auth/login"); + restRequest.AddBody(new + { + account = "2", + pwd = "c81e728d9d4c2f636f067f89cc14862c" + }); + var response = await BaseRestClient.ExecutePostAsync>(restRequest); + if (!response.IsSuccessful || response.Data == null || response.Data.code != 200) + { + MessageBox.Show("登录失败"); + return string.Empty; + } + return response.Data.Data.token; + } + + } +} diff --git a/Demo.Services/BaseService.cs b/Demo.Services/BaseService.cs new file mode 100644 index 0000000..6a40cd0 --- /dev/null +++ b/Demo.Services/BaseService.cs @@ -0,0 +1,17 @@ +using Demo.Common; +using Demo.Services.Interfaces; +using RestSharp; +using System.Windows; + +namespace Demo.Services +{ + public class BaseService : IBaseService + { + protected RestClient BaseRestClient; + public BaseService(RestClient client = null) + { + BaseRestClient = client ?? new RestClient(new Uri($@"http://192.168.2.9:5192")); + } + + } +} diff --git a/Demo.Services/Demo.Services.csproj b/Demo.Services/Demo.Services.csproj new file mode 100644 index 0000000..645b28b --- /dev/null +++ b/Demo.Services/Demo.Services.csproj @@ -0,0 +1,19 @@ + + + + net6.0-windows + enable + enable + AnyCPU;x64 + + + + + + + + + + + + diff --git a/Meeting.V2.Demo.sln b/Meeting.V2.Demo.sln index 3bada02..499abe7 100644 --- a/Meeting.V2.Demo.sln +++ b/Meeting.V2.Demo.sln @@ -5,42 +5,60 @@ VisualStudioVersion = 17.12.35506.116 MinimumVisualStudioVersion = 10.0.40219.1 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Services", "Services", "{13DA16E8-EB84-4F95-B120-F4CC4B0162E4}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Meeting.V2.Demo.Services", "Meeting.V2.Demo\Services\Meeting.V2.Demo.Services\Meeting.V2.Demo.Services.csproj", "{A4A5CAFF-287C-4833-98B6-D074132ED8BF}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Meeting.V2.Demo.Services.Interfaces", "Meeting.V2.Demo\Services\Meeting.V2.Demo.Services.Interfaces\Meeting.V2.Demo.Services.Interfaces.csproj", "{A4FC67BC-E1AE-48A3-A312-3BBB3FB1BAEB}" -EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Meeting.V2.Demo", "Meeting.V2.Demo\Meeting.V2.Demo\Meeting.V2.Demo.csproj", "{ED1004D9-097A-4AB6-BA74-BD5CB40D9984}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Demo.Common", "Demo.Common\Demo.Common.csproj", "{B8ACCBD2-1C4D-4CF5-BBBD-C0A62DB64C31}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Demo.Services", "Demo.Services\Demo.Services.csproj", "{F1C3D513-854E-447B-B0C8-306963706E85}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Demo.Services.Interfaces", "Demo.Services.Interfaces\Demo.Services.Interfaces.csproj", "{AAB9554E-AF4A-4B94-BFEC-B239DC9DD2A6}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU + Debug|x64 = Debug|x64 Release|Any CPU = Release|Any CPU + Release|x64 = Release|x64 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution - {A4A5CAFF-287C-4833-98B6-D074132ED8BF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {A4A5CAFF-287C-4833-98B6-D074132ED8BF}.Debug|Any CPU.Build.0 = Debug|Any CPU - {A4A5CAFF-287C-4833-98B6-D074132ED8BF}.Release|Any CPU.ActiveCfg = Release|Any CPU - {A4A5CAFF-287C-4833-98B6-D074132ED8BF}.Release|Any CPU.Build.0 = Release|Any CPU - {A4FC67BC-E1AE-48A3-A312-3BBB3FB1BAEB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {A4FC67BC-E1AE-48A3-A312-3BBB3FB1BAEB}.Debug|Any CPU.Build.0 = Debug|Any CPU - {A4FC67BC-E1AE-48A3-A312-3BBB3FB1BAEB}.Release|Any CPU.ActiveCfg = Release|Any CPU - {A4FC67BC-E1AE-48A3-A312-3BBB3FB1BAEB}.Release|Any CPU.Build.0 = Release|Any CPU {ED1004D9-097A-4AB6-BA74-BD5CB40D9984}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {ED1004D9-097A-4AB6-BA74-BD5CB40D9984}.Debug|Any CPU.Build.0 = Debug|Any CPU + {ED1004D9-097A-4AB6-BA74-BD5CB40D9984}.Debug|x64.ActiveCfg = Debug|x64 + {ED1004D9-097A-4AB6-BA74-BD5CB40D9984}.Debug|x64.Build.0 = Debug|x64 {ED1004D9-097A-4AB6-BA74-BD5CB40D9984}.Release|Any CPU.ActiveCfg = Release|Any CPU {ED1004D9-097A-4AB6-BA74-BD5CB40D9984}.Release|Any CPU.Build.0 = Release|Any CPU + {ED1004D9-097A-4AB6-BA74-BD5CB40D9984}.Release|x64.ActiveCfg = Release|x64 + {ED1004D9-097A-4AB6-BA74-BD5CB40D9984}.Release|x64.Build.0 = Release|x64 {B8ACCBD2-1C4D-4CF5-BBBD-C0A62DB64C31}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {B8ACCBD2-1C4D-4CF5-BBBD-C0A62DB64C31}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B8ACCBD2-1C4D-4CF5-BBBD-C0A62DB64C31}.Debug|x64.ActiveCfg = Debug|x64 + {B8ACCBD2-1C4D-4CF5-BBBD-C0A62DB64C31}.Debug|x64.Build.0 = Debug|x64 {B8ACCBD2-1C4D-4CF5-BBBD-C0A62DB64C31}.Release|Any CPU.ActiveCfg = Release|Any CPU {B8ACCBD2-1C4D-4CF5-BBBD-C0A62DB64C31}.Release|Any CPU.Build.0 = Release|Any CPU + {B8ACCBD2-1C4D-4CF5-BBBD-C0A62DB64C31}.Release|x64.ActiveCfg = Release|x64 + {B8ACCBD2-1C4D-4CF5-BBBD-C0A62DB64C31}.Release|x64.Build.0 = Release|x64 + {F1C3D513-854E-447B-B0C8-306963706E85}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F1C3D513-854E-447B-B0C8-306963706E85}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F1C3D513-854E-447B-B0C8-306963706E85}.Debug|x64.ActiveCfg = Debug|x64 + {F1C3D513-854E-447B-B0C8-306963706E85}.Debug|x64.Build.0 = Debug|x64 + {F1C3D513-854E-447B-B0C8-306963706E85}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F1C3D513-854E-447B-B0C8-306963706E85}.Release|Any CPU.Build.0 = Release|Any CPU + {F1C3D513-854E-447B-B0C8-306963706E85}.Release|x64.ActiveCfg = Release|x64 + {F1C3D513-854E-447B-B0C8-306963706E85}.Release|x64.Build.0 = Release|x64 + {AAB9554E-AF4A-4B94-BFEC-B239DC9DD2A6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {AAB9554E-AF4A-4B94-BFEC-B239DC9DD2A6}.Debug|Any CPU.Build.0 = Debug|Any CPU + {AAB9554E-AF4A-4B94-BFEC-B239DC9DD2A6}.Debug|x64.ActiveCfg = Debug|x64 + {AAB9554E-AF4A-4B94-BFEC-B239DC9DD2A6}.Debug|x64.Build.0 = Debug|x64 + {AAB9554E-AF4A-4B94-BFEC-B239DC9DD2A6}.Release|Any CPU.ActiveCfg = Release|Any CPU + {AAB9554E-AF4A-4B94-BFEC-B239DC9DD2A6}.Release|Any CPU.Build.0 = Release|Any CPU + {AAB9554E-AF4A-4B94-BFEC-B239DC9DD2A6}.Release|x64.ActiveCfg = Release|x64 + {AAB9554E-AF4A-4B94-BFEC-B239DC9DD2A6}.Release|x64.Build.0 = Release|x64 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection GlobalSection(NestedProjects) = preSolution - {A4A5CAFF-287C-4833-98B6-D074132ED8BF} = {13DA16E8-EB84-4F95-B120-F4CC4B0162E4} - {A4FC67BC-E1AE-48A3-A312-3BBB3FB1BAEB} = {13DA16E8-EB84-4F95-B120-F4CC4B0162E4} + {F1C3D513-854E-447B-B0C8-306963706E85} = {13DA16E8-EB84-4F95-B120-F4CC4B0162E4} + {AAB9554E-AF4A-4B94-BFEC-B239DC9DD2A6} = {13DA16E8-EB84-4F95-B120-F4CC4B0162E4} EndGlobalSection EndGlobal diff --git a/Meeting.V2.Demo/Meeting.V2.Demo/App.xaml b/Meeting.V2.Demo/Meeting.V2.Demo/App.xaml index 366ccd7..6865043 100644 --- a/Meeting.V2.Demo/Meeting.V2.Demo/App.xaml +++ b/Meeting.V2.Demo/Meeting.V2.Demo/App.xaml @@ -2,6 +2,7 @@ x:Class="Meeting.V2.Demo.App" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" + xmlns:cnt="clr-namespace:Demo.Common.Converters;assembly=Demo.Common" xmlns:local="clr-namespace:Meeting.V2.Demo" xmlns:prism="http://prismlibrary.com/"> diff --git a/Meeting.V2.Demo/Meeting.V2.Demo/App.xaml.cs b/Meeting.V2.Demo/Meeting.V2.Demo/App.xaml.cs index 33a2bc2..bfd78ee 100644 --- a/Meeting.V2.Demo/Meeting.V2.Demo/App.xaml.cs +++ b/Meeting.V2.Demo/Meeting.V2.Demo/App.xaml.cs @@ -1,9 +1,14 @@ -using Meeting.V2.Demo.Services; +using Demo.Common.Helpers; +using Demo.Services; +using Demo.Services.Interfaces; +using Meeting.V2.Demo.Services; using Meeting.V2.Demo.Services.Interfaces; using Meeting.V2.Demo.ViewModels; using Meeting.V2.Demo.Views; +using Prism.Events; using Prism.Ioc; using Prism.Modularity; +using System; using System.Windows; namespace Meeting.V2.Demo @@ -21,9 +26,12 @@ namespace Meeting.V2.Demo protected override void RegisterTypes(IContainerRegistry containerRegistry) { containerRegistry.RegisterSingleton(); + containerRegistry.RegisterSingleton(); + containerRegistry.RegisterSingleton(); containerRegistry.RegisterForNavigation(); containerRegistry.RegisterForNavigation(); + containerRegistry.RegisterSingleton(); } protected override void ConfigureModuleCatalog(IModuleCatalog moduleCatalog) @@ -32,15 +40,24 @@ namespace Meeting.V2.Demo //moduleCatalog.AddModule(); } - protected override void OnInitialized() + protected override async void OnInitialized() { base.OnInitialized(); var config = Container.Resolve(); if (config != null) { - config.Init(); + await config.Init(); } } + + protected override void OnExit(ExitEventArgs e) + { + AgoraHelper.UnInit(); + Console.WriteLine("推出了!"); + base.OnExit(e); + + } + } } diff --git a/Meeting.V2.Demo/Meeting.V2.Demo/Configure/ConfigureService.cs b/Meeting.V2.Demo/Meeting.V2.Demo/Configure/ConfigureService.cs index a8a7ace..6b66df8 100644 --- a/Meeting.V2.Demo/Meeting.V2.Demo/Configure/ConfigureService.cs +++ b/Meeting.V2.Demo/Meeting.V2.Demo/Configure/ConfigureService.cs @@ -1,23 +1,39 @@ -using Demo.Common; +using AngleSharp.Io; +using Demo.Common; +using Demo.Common.Helpers; +using Demo.Services.Interfaces; using Meeting.V2.Demo.Views; using Prism.Regions; using System; using System.Collections.Generic; using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; namespace Meeting.V2.Demo.Services.Interfaces { public class ConfigureService : IConfigureService { - private readonly IRegionManager _regionManager; + private readonly IRegionManager _regionManager; + private readonly IAuthService _authService; - public ConfigureService(IRegionManager regionManager) + public ConfigureService(IRegionManager regionManager, IAuthService authService) { - this._regionManager = regionManager; + this._regionManager = regionManager; + this._authService = authService; } - public void Init() + public async Task Init() { _regionManager.RegisterViewWithRegion(RegionNames.VideoRegion); + var token = await _authService.LoginAsync(); + if (string.IsNullOrWhiteSpace(token) ) + { + MessageBox.Show("登录失败"); + return; + + } + System.Windows.Application.Current.Properties["token"] = token; + //var appid = await _agoraConfigService.GetAgoraConfigAsync(); } } } diff --git a/Meeting.V2.Demo/Meeting.V2.Demo/Configure/IConfigureService.cs b/Meeting.V2.Demo/Meeting.V2.Demo/Configure/IConfigureService.cs index c73691c..a3cfdf4 100644 --- a/Meeting.V2.Demo/Meeting.V2.Demo/Configure/IConfigureService.cs +++ b/Meeting.V2.Demo/Meeting.V2.Demo/Configure/IConfigureService.cs @@ -1,11 +1,12 @@ using System; using System.Collections.Generic; using System.Text; +using System.Threading.Tasks; namespace Meeting.V2.Demo.Services.Interfaces { public interface IConfigureService { - void Init(); + Task Init(); } } diff --git a/Meeting.V2.Demo/Meeting.V2.Demo/Meeting.V2.Demo.csproj b/Meeting.V2.Demo/Meeting.V2.Demo/Meeting.V2.Demo.csproj index c0b61a3..e09d979 100644 --- a/Meeting.V2.Demo/Meeting.V2.Demo/Meeting.V2.Demo.csproj +++ b/Meeting.V2.Demo/Meeting.V2.Demo/Meeting.V2.Demo.csproj @@ -4,12 +4,15 @@ net6.0-windows true True + AnyCPU;x64 + false + @@ -17,8 +20,8 @@ - - + + diff --git a/Meeting.V2.Demo/Meeting.V2.Demo/ViewModels/MainWindowViewModel.cs b/Meeting.V2.Demo/Meeting.V2.Demo/ViewModels/MainWindowViewModel.cs index 8159fdc..f0bc04c 100644 --- a/Meeting.V2.Demo/Meeting.V2.Demo/ViewModels/MainWindowViewModel.cs +++ b/Meeting.V2.Demo/Meeting.V2.Demo/ViewModels/MainWindowViewModel.cs @@ -1,19 +1,118 @@ -using Prism.Mvvm; +using Agora.Rtc; +using Demo.Common.Events; +using Demo.Common.Helpers; +using Demo.Common.Models; +using Demo.Services.Interfaces; +using HandyControl.Controls; +using HandyControl.Data; +using Masuit.Tools; +using Prism.Commands; +using Prism.Events; +using Prism.Mvvm; +using System; +using System.Windows; namespace Meeting.V2.Demo.ViewModels { public class MainWindowViewModel : BindableBase { + public MainWindowViewModel(IEventAggregator aggregator, IAgoraConfigService agoraConfigService) + { + this._aggregator = aggregator; + this._agoraConfigService = agoraConfigService; + } + private string _title = "Prism Application"; + private readonly IEventAggregator _aggregator; + private readonly IAgoraConfigService _agoraConfigService; + public string Title { get { return _title; } set { SetProperty(ref _title, value); } } - public MainWindowViewModel() + private long uid = (DateTime.Now.Ticks % 100000).ToString("D5").ToInt64(); + public long UId { - + get { return uid; } + set { SetProperty(ref uid, value); } } + + private bool isJoin; + public bool IsJoin + { + get { return isJoin; } + set { SetProperty(ref isJoin, value); } + } + + + + public DelegateCommand JoinChannelCommand => new DelegateCommand(JoinChannel); + async void JoinChannel() + { + AgoraHelper.Init("4a4f7be64fa1404ebda74784fe9ac381", (uint)UId); + + var rtcToken = await _agoraConfigService.GetRtcTokenAsync(); + if (!string.IsNullOrWhiteSpace(rtcToken)) + Application.Current.Properties["rtctoken"] = rtcToken; + + var result = AgoraHelper._RtcEngineInstance.EnableVideo(); + Console.WriteLine($@"{nameof(JoinChannel)}-EnableVideo : {result}"); + + result = AgoraHelper._RtcEngineInstance.StartPreview(VIDEO_SOURCE_TYPE.VIDEO_SOURCE_CAMERA_PRIMARY); + Console.WriteLine($@"{nameof(JoinChannel)}-StartPreview : {result}"); + + ChannelMediaOptions options = new ChannelMediaOptions(); + options.channelProfile.SetValue(CHANNEL_PROFILE_TYPE.CHANNEL_PROFILE_LIVE_BROADCASTING); + options.clientRoleType.SetValue(CLIENT_ROLE_TYPE.CLIENT_ROLE_BROADCASTER); + // 发布麦克风采集的音频流 + options.publishMicrophoneTrack.SetValue(true); + // 发布摄像头采集的视频流 + options.publishCameraTrack.SetValue(true); + // 自动订阅所有音频流 + options.autoSubscribeAudio.SetValue(true); + // 自动订阅所有视频流 + options.autoSubscribeVideo.SetValue(true); + + AgoraHelper._RtcEngineInstance.JoinChannel(System.Windows.Application.Current.Properties["rtctoken"].ToString(), "999", (uint)UId, options); + + ///启用用户音量提示。 + AgoraHelper._RtcEngineInstance.EnableAudioVolumeIndication(200, 5, false); + + _aggregator.GetEvent().Publish(new User + { + Id = UId, + UserName = UId.ToString(), + IsManager = true, + IsLocal = true + }); + + IsJoin = !IsJoin; + Growl.Success("加入频道成功"); + } + + public DelegateCommand LeavelChannelCommand => new DelegateCommand(LeavelChannel); + void LeavelChannel() + { + AgoraHelper._RtcEngineInstance.LeaveChannel(); + AgoraHelper._RtcEngineInstance.StopPreview(); + AgoraHelper._RtcEngineInstance.DisableVideo(); + + + _aggregator.GetEvent().Publish(new User + { + Id = UId, + UserName = UId.ToString(), + IsManager = true, + IsLocal = true + }); + + IsJoin = !IsJoin; + + Growl.Success("离开频道成功"); + } + + } } diff --git a/Meeting.V2.Demo/Meeting.V2.Demo/ViewModels/VideoAreaViewModel.cs b/Meeting.V2.Demo/Meeting.V2.Demo/ViewModels/VideoAreaViewModel.cs index 2b2e01b..6356239 100644 --- a/Meeting.V2.Demo/Meeting.V2.Demo/ViewModels/VideoAreaViewModel.cs +++ b/Meeting.V2.Demo/Meeting.V2.Demo/ViewModels/VideoAreaViewModel.cs @@ -1,77 +1,140 @@ -using Demo.Common.Models; +using Demo.Common.Events; using Meeting.V2.Demo.Core.Mvvm; using Prism.Commands; +using Prism.Events; using Prism.Regions; using System; -using System.Collections.Generic; using System.Collections.ObjectModel; -using System.Linq; -using System.Text; -using System.Threading.Tasks; using System.Windows; +using System.Windows.Controls; +using System.Windows.Threading; +using User = Demo.Common.Models.User; namespace Meeting.V2.Demo.ViewModels { public class VideoAreaViewModel : RegionViewModelBase { - public VideoAreaViewModel(IRegionManager regionManager) : base(regionManager) + public VideoAreaViewModel(IRegionManager regionManager, + IEventAggregator aggregator) : base(regionManager) { - UserInfos.Add(new UserInfo() { Id = 1, UserName = "张三", IsManager = true }); - UserInfos.Add(new UserInfo() { Id = 2, UserName = "李四", IsManager = false }); + this.aggregator = aggregator; - UinfoProp = new UserInfo + aggregator.GetEvent().Subscribe((a) => Application.Current.Dispatcher.BeginInvoke(() => { - Id = 111, - UserName = "王五", - IsManager = false - }; + + UserInfos.Add(a); + })); + aggregator.GetEvent().Subscribe((a) => + { + Application.Current.Dispatcher.BeginInvoke(() => + { + if (a.IsLocal) + { + UserInfos.Clear(); + FocusUser = null; + return; + } + for (int i = 0; i < UserInfos.Count; i++) + { + if (UserInfos[i].Id == a.Id) + { + UserInfos.RemoveAt(i); + return; + } + } + }); + + }); + //UserInfos.Add(new UserInfo() { Id = 1, UserName = "张三", IsManager = true }); + //UserInfos.Add(new UserInfo() { Id = 2, UserName = "李四", IsManager = false }); + //UserInfos.Add(new UserInfo() { Id = 3, UserName = "李四", IsManager = false }); + //UserInfos.Add(new UserInfo() { Id = 4, UserName = "李四", IsManager = false }); + //UserInfos.Add(new UserInfo() { Id = 4, UserName = "李四", IsManager = false }); + //UserInfos.Add(new UserInfo() { Id = 4, UserName = "李四", IsManager = false }); } - private ObservableCollection userInfos = new(); + private ObservableCollection userInfos = new(); /// /// 用户列表 /// - public ObservableCollection UserInfos + public ObservableCollection UserInfos { get { return userInfos; } set { SetProperty(ref userInfos, value); } } - private string fieldName = "卧槽"; - public string PropertyNameAA + private int userPageSize = 6; + /// + /// 每页用户数 + /// + public int UserPageSize { - get { return fieldName; } - set { SetProperty(ref fieldName, value); } - } - - private UserInfo Uinfo; - public UserInfo UinfoProp - { - get { return Uinfo; } - set { SetProperty(ref Uinfo, value); } + get { return userPageSize; } + set { SetProperty(ref userPageSize, value); } } - public override void OnNavigatedTo(NavigationContext navigationContext) - { - //base.OnNavigatedTo(navigationContext); + private User focusUser; + private readonly IEventAggregator aggregator; - Init(); - } - - private void Init() + /// + /// 焦点用户 + /// + public User FocusUser { - UserInfos.Add(new UserInfo() { Id = 3, UserName = "王五", IsManager = true }); - UserInfos.Add(new UserInfo() { Id = 4, UserName = "李2", IsManager = false }); + get { return focusUser; } + set { SetProperty(ref focusUser, value); } } - public DelegateCommand TestCommand => new DelegateCommand(ExecuteCommandName); - - void ExecuteCommandName() + /// + /// 选择焦点用户 + /// + public DelegateCommand SelectedUserCommand => new DelegateCommand((u) => { - MessageBox.Show($@"{UserInfos.Count} Id:{string.Join(',', UserInfos.Select(x => x.Id))}"); - } + if (FocusUser != u || FocusUser.Id != u.Id) + { + FocusUser = u; + } + }); + + ///// + ///// 选择焦点用户 + ///// + //public DelegateCommand SelectedUserCommand => new DelegateCommand(() => + //{ + // Console.WriteLine("2222222222222222222222222222"); + //}); + + + + /// + /// 用户列表尺寸大小改变事件 + /// + public DelegateCommand UserStackPanelSizeChangeCommand => new DelegateCommand((e) => + { + if (e is StackPanel control) + { + Console.WriteLine($@"hei:{control.ActualHeight} widht:{control.ActualWidth}"); + var width = ((control.ActualHeight - 6) * 1.777); + + UserPageSize = (int)Math.Floor(control.ActualWidth / width); + if (UserPageSize < UserInfos.Count && UserPageSize > 0) + { + while (UserInfos.Count != UserPageSize) + { + UserInfos.RemoveAt(UserInfos.Count - 1); + + } + } + + + } + }); + + + + } } diff --git a/Meeting.V2.Demo/Meeting.V2.Demo/ViewModels/VideoViewModel.cs b/Meeting.V2.Demo/Meeting.V2.Demo/ViewModels/VideoViewModel.cs index d672c8c..820e1fe 100644 --- a/Meeting.V2.Demo/Meeting.V2.Demo/ViewModels/VideoViewModel.cs +++ b/Meeting.V2.Demo/Meeting.V2.Demo/ViewModels/VideoViewModel.cs @@ -1,39 +1,93 @@ -using Demo.Common.Models; +using Agora.Rtc; +using Demo.Common.Events; +using Demo.Common.Helpers; +using Demo.Common.Models; +using Masuit.Tools; using Meeting.V2.Demo.Core.Mvvm; +using Meeting.V2.Demo.Views; using Prism.Commands; -using Prism.Regions; +using Prism.Events; using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; using System.Windows; +using System.Windows.Forms; namespace Meeting.V2.Demo.ViewModels { - public class VideoViewModel : RegionViewModelBase + public class VideoViewModel : ViewModelBase { - public VideoViewModel(IRegionManager regionManager) : base(regionManager) + + private VideoView _view; + + public VideoViewModel() { + //aggregator.GetEvent().Subscribe(RenderVideoView); } - private UserInfo userInfo; + public DelegateCommand LoadedCommand => new DelegateCommand((u) => + { + if (u == null) + return; + Console.WriteLine($@"LoadedCoommand 被执行了!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"); + this._view = u; + RenderVideoView(); + }); + + /// + /// 上一次渲染的用户信息 + /// + private User oldUserInfo; + private User userInfo; /// /// 用户信息 /// - public UserInfo UserInfo + public User UserInfo { get { return userInfo; } - set { SetProperty(ref userInfo, value); } + set + { + oldUserInfo = userInfo.DeepClone(); + SetProperty(ref userInfo, value); + RenderVideoView(); + } } + + public DelegateCommand OperClickCommand => new DelegateCommand(() => { - MessageBox.Show($@"id:{userInfo.Id} userName:{userInfo.UserName} isManager:{userInfo.IsManager}"); + Console.WriteLine($@"id:{UserInfo.Id} userName:{UserInfo.UserName} isManager:{UserInfo.IsManager}"); + UserInfo.IsManager = !UserInfo.IsManager; + userInfo.UserName = DateTime.Now.ToString(); + Console.WriteLine($@"id:{UserInfo.Id} userName:{UserInfo.UserName} isManager:{UserInfo.IsManager}"); + //MessageBox.Show($@"id:{Id} userName:{UserName} isManager:{IsManager}"); }); - - - + + public void RenderVideoView() + { + if (_view == null || UserInfo == null || UserInfo.Id <= 0) + { + if (_view != null) + { + //_view.pic_frame.Invoke(() => + //{ + // _view.pic_frame.Refresh(); + //}); + + if (oldUserInfo != null) + { + AgoraHelper.ClearUserVideo((uint)(oldUserInfo.Id), (long)_view.pic_frame.Handle); + _view.pic_frame.Invoke(() => + { + _view.pic_frame.Refresh(); + }); + } + } + return; + } + + AgoraHelper.SetupUserVideo((uint)UserInfo.Id, (long)_view.pic_frame.Handle, (uint)(oldUserInfo == null ? 0 : oldUserInfo.Id)); + } + } } diff --git a/Meeting.V2.Demo/Meeting.V2.Demo/Views/MainWindow.xaml b/Meeting.V2.Demo/Meeting.V2.Demo/Views/MainWindow.xaml index 2e68170..6692c73 100644 --- a/Meeting.V2.Demo/Meeting.V2.Demo/Views/MainWindow.xaml +++ b/Meeting.V2.Demo/Meeting.V2.Demo/Views/MainWindow.xaml @@ -3,14 +3,17 @@ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:cmn="clr-namespace:Demo.Common;assembly=Demo.Common" + xmlns:cnt="clr-namespace:Demo.Common.Converters;assembly=Demo.Common" xmlns:hc="https://handyorg.github.io/handycontrol" xmlns:intertop="clr-namespace:Microsoft.DwayneNeed.Interop;assembly=MahApps.Microsoft.DwayneNeed" xmlns:local="clr-namespace:Meeting.V2.Demo.Views" xmlns:prism="http://prismlibrary.com/" xmlns:wfc="clr-namespace:System.Windows.Forms;assembly=System.Windows.Forms" xmlns:wfh="clr-namespace:System.Windows.Forms.Integration;assembly=WindowsFormsIntegration" - Width="960" - Height="640" + Width="962" + Height="642" + MinWidth="1050" + MinHeight="642" prism:ViewModelLocator.AutoWireViewModel="True" Background="#252525" CloseButtonForeground="Red" @@ -18,16 +21,55 @@ NonClientAreaForeground="White" OtherButtonForeground="White" WindowStartupLocation="CenterScreen"> + + + + - - - - + + + + + + + + + + + + + diff --git a/Meeting.V2.Demo/Meeting.V2.Demo/Views/VideoAreaView.xaml b/Meeting.V2.Demo/Meeting.V2.Demo/Views/VideoAreaView.xaml index 9972295..89ad0c7 100644 --- a/Meeting.V2.Demo/Meeting.V2.Demo/Views/VideoAreaView.xaml +++ b/Meeting.V2.Demo/Meeting.V2.Demo/Views/VideoAreaView.xaml @@ -2,38 +2,86 @@ x:Class="Meeting.V2.Demo.Views.VideoAreaView" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" + xmlns:cnt="clr-namespace:Demo.Common.Converters;assembly=Demo.Common" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" + xmlns:i="http://schemas.microsoft.com/xaml/behaviors" xmlns:local="clr-namespace:Meeting.V2.Demo.Views" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:prism="http://prismlibrary.com/" + x:Name="root" d:DesignHeight="530" d:DesignWidth="960" prism:ViewModelLocator.AutoWireViewModel="True" mc:Ignorable="d"> + + + - + - + + + Background="#2D3033" + Orientation="Horizontal"> + + - + + + + + + + + + + + + - - + + + + + + + + -