This commit is contained in:
parent
ad8f3983c9
commit
0736345acd
|
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -5,6 +5,22 @@
|
||||||
<Nullable>enable</Nullable>
|
<Nullable>enable</Nullable>
|
||||||
<UseWPF>true</UseWPF>
|
<UseWPF>true</UseWPF>
|
||||||
<ImplicitUsings>enable</ImplicitUsings>
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
<Platforms>AnyCPU;x64</Platforms>
|
||||||
|
<ErrorOnDuplicatePublishOutputFiles>false</ErrorOnDuplicatePublishOutputFiles>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="agora_rtc_sdk" Version="4.2.1" />
|
||||||
|
<PackageReference Include="HandyControl" Version="3.5.1" />
|
||||||
|
<PackageReference Include="Masuit.Tools.Core" Version="2024.6.0" />
|
||||||
|
<PackageReference Include="Prism.DryIoc" Version="8.1.97" />
|
||||||
|
<PackageReference Include="RestSharp" Version="112.1.0" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<None Update="AgoraRtcWrapper.lib">
|
||||||
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
|
</None>
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|
|
||||||
|
|
@ -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<T>
|
||||||
|
{
|
||||||
|
public int code { get; set; }
|
||||||
|
public string message { get; set; }
|
||||||
|
public T Data { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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<AudioVolumeInfo>
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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<User>
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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<User>
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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<TResult> PostAsync<TResult, TBody>(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<BaseApiResult<TResult>>(request);
|
||||||
|
if (result.code != 200)
|
||||||
|
{
|
||||||
|
return result.Data;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 渲染用户视频
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="uid"></param>
|
||||||
|
/// <param name="controlHandle"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
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
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 清除已渲染的用户视频
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="uid"></param>
|
||||||
|
/// <param name="controlHandle"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
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
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 渲染用户视频
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="uid"></param>
|
||||||
|
/// <param name="controlHandle"></param>
|
||||||
|
/// <param name="delUid"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static int SetupUserVideo(uint uid, long controlHandle, uint delUid = 0)
|
||||||
|
{
|
||||||
|
if (delUid > 0)
|
||||||
|
{
|
||||||
|
ClearUserVideo(delUid, controlHandle);
|
||||||
|
}
|
||||||
|
return SetupUserVideo(uid, controlHandle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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<IEventAggregator>();
|
||||||
|
}
|
||||||
|
|
||||||
|
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<IEventAggregator>();
|
||||||
|
aggregator.GetEvent<UserJoinEvent>().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<IEventAggregator>();
|
||||||
|
aggregator.GetEvent<UserLeaveEvent>().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<AudioVolumeIndicationEvent>().Publish();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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); }
|
||||||
|
//}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -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; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,10 @@
|
||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFramework>net6.0-windows</TargetFramework> <TargetFramework>net6.0</TargetFramework>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
<Platforms>AnyCPU;x64</Platforms>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
</Project>
|
||||||
|
|
@ -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<string> GetAgoraConfigAsync();
|
||||||
|
Task<string> GetRtcTokenAsync();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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<string> LoginAsync();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace Demo.Services.Interfaces
|
||||||
|
{
|
||||||
|
public interface IBaseService
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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<string> GetAgoraConfigAsync()
|
||||||
|
{
|
||||||
|
RestRequest request = new RestRequest("home/agora-conf");
|
||||||
|
var result = await BaseRestClient.ExecuteAsync<BaseApiResult<string>>(request);
|
||||||
|
if (!result.IsSuccessful || result.Data == null)
|
||||||
|
{
|
||||||
|
MessageBox.Show(result.ErrorMessage);
|
||||||
|
return string.Empty;
|
||||||
|
}
|
||||||
|
return result.Data.Data;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<string> GetRtcTokenAsync()
|
||||||
|
{
|
||||||
|
var request = new RestRequest("room/tk/rtc?roomNum=999").AddHeader("Authorization", "Bearer " + Application.Current.Properties["token"]);
|
||||||
|
var result = await BaseRestClient.ExecuteAsync<BaseApiResult<string>>(request);
|
||||||
|
|
||||||
|
if (result == null || result.Data == null)
|
||||||
|
{
|
||||||
|
MessageBox.Show("token 获取失败");
|
||||||
|
return string.Empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
//return result.Data.Data;
|
||||||
|
|
||||||
|
return result.Data.Data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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<string> LoginAsync()
|
||||||
|
{
|
||||||
|
var restRequest = new RestRequest("auth/login");
|
||||||
|
restRequest.AddBody(new
|
||||||
|
{
|
||||||
|
account = "2",
|
||||||
|
pwd = "c81e728d9d4c2f636f067f89cc14862c"
|
||||||
|
});
|
||||||
|
var response = await BaseRestClient.ExecutePostAsync<BaseApiResult<LoginApiResponse>>(restRequest);
|
||||||
|
if (!response.IsSuccessful || response.Data == null || response.Data.code != 200)
|
||||||
|
{
|
||||||
|
MessageBox.Show("登录失败");
|
||||||
|
return string.Empty;
|
||||||
|
}
|
||||||
|
return response.Data.Data.token;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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"));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,19 @@
|
||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFramework>net6.0-windows</TargetFramework>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
<Platforms>AnyCPU;x64</Platforms>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="RestSharp" Version="112.1.0" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\Demo.Common\Demo.Common.csproj" />
|
||||||
|
<ProjectReference Include="..\Demo.Services.Interfaces\Demo.Services.Interfaces.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
||||||
|
|
@ -5,42 +5,60 @@ VisualStudioVersion = 17.12.35506.116
|
||||||
MinimumVisualStudioVersion = 10.0.40219.1
|
MinimumVisualStudioVersion = 10.0.40219.1
|
||||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Services", "Services", "{13DA16E8-EB84-4F95-B120-F4CC4B0162E4}"
|
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Services", "Services", "{13DA16E8-EB84-4F95-B120-F4CC4B0162E4}"
|
||||||
EndProject
|
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}"
|
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
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Demo.Common", "Demo.Common\Demo.Common.csproj", "{B8ACCBD2-1C4D-4CF5-BBBD-C0A62DB64C31}"
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Demo.Common", "Demo.Common\Demo.Common.csproj", "{B8ACCBD2-1C4D-4CF5-BBBD-C0A62DB64C31}"
|
||||||
EndProject
|
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
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|Any CPU = Debug|Any CPU
|
Debug|Any CPU = Debug|Any CPU
|
||||||
|
Debug|x64 = Debug|x64
|
||||||
Release|Any CPU = Release|Any CPU
|
Release|Any CPU = Release|Any CPU
|
||||||
|
Release|x64 = Release|x64
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
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.ActiveCfg = Debug|Any CPU
|
||||||
{ED1004D9-097A-4AB6-BA74-BD5CB40D9984}.Debug|Any CPU.Build.0 = 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.ActiveCfg = Release|Any CPU
|
||||||
{ED1004D9-097A-4AB6-BA74-BD5CB40D9984}.Release|Any CPU.Build.0 = 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.ActiveCfg = Debug|Any CPU
|
||||||
{B8ACCBD2-1C4D-4CF5-BBBD-C0A62DB64C31}.Debug|Any CPU.Build.0 = 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.ActiveCfg = Release|Any CPU
|
||||||
{B8ACCBD2-1C4D-4CF5-BBBD-C0A62DB64C31}.Release|Any CPU.Build.0 = 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
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(NestedProjects) = preSolution
|
GlobalSection(NestedProjects) = preSolution
|
||||||
{A4A5CAFF-287C-4833-98B6-D074132ED8BF} = {13DA16E8-EB84-4F95-B120-F4CC4B0162E4}
|
{F1C3D513-854E-447B-B0C8-306963706E85} = {13DA16E8-EB84-4F95-B120-F4CC4B0162E4}
|
||||||
{A4FC67BC-E1AE-48A3-A312-3BBB3FB1BAEB} = {13DA16E8-EB84-4F95-B120-F4CC4B0162E4}
|
{AAB9554E-AF4A-4B94-BFEC-B239DC9DD2A6} = {13DA16E8-EB84-4F95-B120-F4CC4B0162E4}
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
EndGlobal
|
EndGlobal
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@
|
||||||
x:Class="Meeting.V2.Demo.App"
|
x:Class="Meeting.V2.Demo.App"
|
||||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
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:local="clr-namespace:Meeting.V2.Demo"
|
||||||
xmlns:prism="http://prismlibrary.com/">
|
xmlns:prism="http://prismlibrary.com/">
|
||||||
<Application.Resources>
|
<Application.Resources>
|
||||||
|
|
|
||||||
|
|
@ -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.Services.Interfaces;
|
||||||
using Meeting.V2.Demo.ViewModels;
|
using Meeting.V2.Demo.ViewModels;
|
||||||
using Meeting.V2.Demo.Views;
|
using Meeting.V2.Demo.Views;
|
||||||
|
using Prism.Events;
|
||||||
using Prism.Ioc;
|
using Prism.Ioc;
|
||||||
using Prism.Modularity;
|
using Prism.Modularity;
|
||||||
|
using System;
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
|
|
||||||
namespace Meeting.V2.Demo
|
namespace Meeting.V2.Demo
|
||||||
|
|
@ -21,9 +26,12 @@ namespace Meeting.V2.Demo
|
||||||
protected override void RegisterTypes(IContainerRegistry containerRegistry)
|
protected override void RegisterTypes(IContainerRegistry containerRegistry)
|
||||||
{
|
{
|
||||||
containerRegistry.RegisterSingleton<IConfigureService, ConfigureService>();
|
containerRegistry.RegisterSingleton<IConfigureService, ConfigureService>();
|
||||||
|
containerRegistry.RegisterSingleton<IAgoraConfigService, AgoraConfigService>();
|
||||||
|
containerRegistry.RegisterSingleton<IAuthService, AuthService>();
|
||||||
|
|
||||||
containerRegistry.RegisterForNavigation<VideoView, VideoViewModel>();
|
containerRegistry.RegisterForNavigation<VideoView, VideoViewModel>();
|
||||||
containerRegistry.RegisterForNavigation<VideoAreaView, VideoAreaViewModel>();
|
containerRegistry.RegisterForNavigation<VideoAreaView, VideoAreaViewModel>();
|
||||||
|
containerRegistry.RegisterSingleton<IEventAggregator, EventAggregator>();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void ConfigureModuleCatalog(IModuleCatalog moduleCatalog)
|
protected override void ConfigureModuleCatalog(IModuleCatalog moduleCatalog)
|
||||||
|
|
@ -32,15 +40,24 @@ namespace Meeting.V2.Demo
|
||||||
//moduleCatalog.AddModule<ModuleNameModule>();
|
//moduleCatalog.AddModule<ModuleNameModule>();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void OnInitialized()
|
protected override async void OnInitialized()
|
||||||
{
|
{
|
||||||
base.OnInitialized();
|
base.OnInitialized();
|
||||||
|
|
||||||
var config = Container.Resolve<IConfigureService>();
|
var config = Container.Resolve<IConfigureService>();
|
||||||
if (config != null)
|
if (config != null)
|
||||||
{
|
{
|
||||||
config.Init();
|
await config.Init();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override void OnExit(ExitEventArgs e)
|
||||||
|
{
|
||||||
|
AgoraHelper.UnInit();
|
||||||
|
Console.WriteLine("推出了!");
|
||||||
|
base.OnExit(e);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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 Meeting.V2.Demo.Views;
|
||||||
using Prism.Regions;
|
using Prism.Regions;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Windows.Forms;
|
||||||
|
|
||||||
namespace Meeting.V2.Demo.Services.Interfaces
|
namespace Meeting.V2.Demo.Services.Interfaces
|
||||||
{
|
{
|
||||||
public class ConfigureService : IConfigureService
|
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<VideoAreaView>(RegionNames.VideoRegion);
|
_regionManager.RegisterViewWithRegion<VideoAreaView>(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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,12 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace Meeting.V2.Demo.Services.Interfaces
|
namespace Meeting.V2.Demo.Services.Interfaces
|
||||||
{
|
{
|
||||||
public interface IConfigureService
|
public interface IConfigureService
|
||||||
{
|
{
|
||||||
void Init();
|
Task Init();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,12 +4,15 @@
|
||||||
<TargetFramework>net6.0-windows</TargetFramework>
|
<TargetFramework>net6.0-windows</TargetFramework>
|
||||||
<UseWPF>true</UseWPF>
|
<UseWPF>true</UseWPF>
|
||||||
<UseWindowsForms>True</UseWindowsForms>
|
<UseWindowsForms>True</UseWindowsForms>
|
||||||
|
<Platforms>AnyCPU;x64</Platforms>
|
||||||
|
<ErrorOnDuplicatePublishOutputFiles>false</ErrorOnDuplicatePublishOutputFiles>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Remove="Assets\manager.svg" />
|
<None Remove="Assets\manager.svg" />
|
||||||
<None Remove="Assets\more.svg" />
|
<None Remove="Assets\more.svg" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<PackageReference Include="agora_rtc_sdk" Version="4.2.1" />
|
||||||
<PackageReference Include="HandyControl" Version="3.5.1" />
|
<PackageReference Include="HandyControl" Version="3.5.1" />
|
||||||
<PackageReference Include="MahApps.Microsoft.DwayneNeed" Version="1.0.1" />
|
<PackageReference Include="MahApps.Microsoft.DwayneNeed" Version="1.0.1" />
|
||||||
<PackageReference Include="Prism.DryIoc" Version="8.1.97" />
|
<PackageReference Include="Prism.DryIoc" Version="8.1.97" />
|
||||||
|
|
@ -17,8 +20,8 @@
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\..\Demo.Common\Demo.Common.csproj" />
|
<ProjectReference Include="..\..\Demo.Common\Demo.Common.csproj" />
|
||||||
<ProjectReference Include="..\Services\Meeting.V2.Demo.Services.Interfaces\Meeting.V2.Demo.Services.Interfaces.csproj" />
|
<ProjectReference Include="..\..\Demo.Services.Interfaces\Demo.Services.Interfaces.csproj" />
|
||||||
<ProjectReference Include="..\Services\Meeting.V2.Demo.Services\Meeting.V2.Demo.Services.csproj" />
|
<ProjectReference Include="..\..\Demo.Services\Demo.Services.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Resource Include="Assets\manager.svg" />
|
<Resource Include="Assets\manager.svg" />
|
||||||
|
|
|
||||||
|
|
@ -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
|
namespace Meeting.V2.Demo.ViewModels
|
||||||
{
|
{
|
||||||
public class MainWindowViewModel : BindableBase
|
public class MainWindowViewModel : BindableBase
|
||||||
{
|
{
|
||||||
|
public MainWindowViewModel(IEventAggregator aggregator, IAgoraConfigService agoraConfigService)
|
||||||
|
{
|
||||||
|
this._aggregator = aggregator;
|
||||||
|
this._agoraConfigService = agoraConfigService;
|
||||||
|
}
|
||||||
|
|
||||||
private string _title = "Prism Application";
|
private string _title = "Prism Application";
|
||||||
|
private readonly IEventAggregator _aggregator;
|
||||||
|
private readonly IAgoraConfigService _agoraConfigService;
|
||||||
|
|
||||||
public string Title
|
public string Title
|
||||||
{
|
{
|
||||||
get { return _title; }
|
get { return _title; }
|
||||||
set { SetProperty(ref _title, value); }
|
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<UserJoinEvent>().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<UserLeaveEvent>().Publish(new User
|
||||||
|
{
|
||||||
|
Id = UId,
|
||||||
|
UserName = UId.ToString(),
|
||||||
|
IsManager = true,
|
||||||
|
IsLocal = true
|
||||||
|
});
|
||||||
|
|
||||||
|
IsJoin = !IsJoin;
|
||||||
|
|
||||||
|
Growl.Success("离开频道成功");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,77 +1,140 @@
|
||||||
using Demo.Common.Models;
|
using Demo.Common.Events;
|
||||||
using Meeting.V2.Demo.Core.Mvvm;
|
using Meeting.V2.Demo.Core.Mvvm;
|
||||||
using Prism.Commands;
|
using Prism.Commands;
|
||||||
|
using Prism.Events;
|
||||||
using Prism.Regions;
|
using Prism.Regions;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Collections.ObjectModel;
|
using System.Collections.ObjectModel;
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
|
using System.Windows.Controls;
|
||||||
|
using System.Windows.Threading;
|
||||||
|
using User = Demo.Common.Models.User;
|
||||||
|
|
||||||
namespace Meeting.V2.Demo.ViewModels
|
namespace Meeting.V2.Demo.ViewModels
|
||||||
{
|
{
|
||||||
public class VideoAreaViewModel : RegionViewModelBase
|
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 });
|
this.aggregator = aggregator;
|
||||||
UserInfos.Add(new UserInfo() { Id = 2, UserName = "李四", IsManager = false });
|
|
||||||
|
|
||||||
UinfoProp = new UserInfo
|
aggregator.GetEvent<UserJoinEvent>().Subscribe((a) => Application.Current.Dispatcher.BeginInvoke(() =>
|
||||||
{
|
{
|
||||||
Id = 111,
|
|
||||||
UserName = "王五",
|
UserInfos.Add(a);
|
||||||
IsManager = false
|
}));
|
||||||
};
|
aggregator.GetEvent<UserLeaveEvent>().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<UserInfo> userInfos = new();
|
private ObservableCollection<User> userInfos = new();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 用户列表
|
/// 用户列表
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public ObservableCollection<UserInfo> UserInfos
|
public ObservableCollection<User> UserInfos
|
||||||
{
|
{
|
||||||
get { return userInfos; }
|
get { return userInfos; }
|
||||||
set { SetProperty(ref userInfos, value); }
|
set { SetProperty(ref userInfos, value); }
|
||||||
}
|
}
|
||||||
|
|
||||||
private string fieldName = "卧槽";
|
private int userPageSize = 6;
|
||||||
public string PropertyNameAA
|
/// <summary>
|
||||||
|
/// 每页用户数
|
||||||
|
/// </summary>
|
||||||
|
public int UserPageSize
|
||||||
{
|
{
|
||||||
get { return fieldName; }
|
get { return userPageSize; }
|
||||||
set { SetProperty(ref fieldName, value); }
|
set { SetProperty(ref userPageSize, value); }
|
||||||
}
|
|
||||||
|
|
||||||
private UserInfo Uinfo;
|
|
||||||
public UserInfo UinfoProp
|
|
||||||
{
|
|
||||||
get { return Uinfo; }
|
|
||||||
set { SetProperty(ref Uinfo, value); }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public override void OnNavigatedTo(NavigationContext navigationContext)
|
private User focusUser;
|
||||||
{
|
private readonly IEventAggregator aggregator;
|
||||||
//base.OnNavigatedTo(navigationContext);
|
|
||||||
|
|
||||||
Init();
|
/// <summary>
|
||||||
}
|
/// 焦点用户
|
||||||
|
/// </summary>
|
||||||
private void Init()
|
public User FocusUser
|
||||||
{
|
{
|
||||||
UserInfos.Add(new UserInfo() { Id = 3, UserName = "王五", IsManager = true });
|
get { return focusUser; }
|
||||||
UserInfos.Add(new UserInfo() { Id = 4, UserName = "李2", IsManager = false });
|
set { SetProperty(ref focusUser, value); }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public DelegateCommand TestCommand => new DelegateCommand(ExecuteCommandName);
|
/// <summary>
|
||||||
|
/// 选择焦点用户
|
||||||
void ExecuteCommandName()
|
/// </summary>
|
||||||
|
public DelegateCommand<User> SelectedUserCommand => new DelegateCommand<User>((u) =>
|
||||||
{
|
{
|
||||||
MessageBox.Show($@"{UserInfos.Count} Id:{string.Join(',', UserInfos.Select(x => x.Id))}");
|
if (FocusUser != u || FocusUser.Id != u.Id)
|
||||||
}
|
{
|
||||||
|
FocusUser = u;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
///// <summary>
|
||||||
|
///// 选择焦点用户
|
||||||
|
///// </summary>
|
||||||
|
//public DelegateCommand SelectedUserCommand => new DelegateCommand(() =>
|
||||||
|
//{
|
||||||
|
// Console.WriteLine("2222222222222222222222222222");
|
||||||
|
//});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 用户列表尺寸大小改变事件
|
||||||
|
/// </summary>
|
||||||
|
public DelegateCommand<object> UserStackPanelSizeChangeCommand => new DelegateCommand<object>((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);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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.Core.Mvvm;
|
||||||
|
using Meeting.V2.Demo.Views;
|
||||||
using Prism.Commands;
|
using Prism.Commands;
|
||||||
using Prism.Regions;
|
using Prism.Events;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
|
using System.Windows.Forms;
|
||||||
|
|
||||||
namespace Meeting.V2.Demo.ViewModels
|
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<UserJoinEvent>().Subscribe(RenderVideoView);
|
||||||
}
|
}
|
||||||
|
|
||||||
private UserInfo userInfo;
|
public DelegateCommand<VideoView> LoadedCommand => new DelegateCommand<VideoView>((u) =>
|
||||||
|
{
|
||||||
|
if (u == null)
|
||||||
|
return;
|
||||||
|
Console.WriteLine($@"LoadedCoommand 被执行了!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
|
||||||
|
this._view = u;
|
||||||
|
RenderVideoView();
|
||||||
|
});
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 上一次渲染的用户信息
|
||||||
|
/// </summary>
|
||||||
|
private User oldUserInfo;
|
||||||
|
private User userInfo;
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 用户信息
|
/// 用户信息
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public UserInfo UserInfo
|
public User UserInfo
|
||||||
{
|
{
|
||||||
get { return userInfo; }
|
get { return userInfo; }
|
||||||
set { SetProperty(ref userInfo, value); }
|
set
|
||||||
|
{
|
||||||
|
oldUserInfo = userInfo.DeepClone();
|
||||||
|
SetProperty(ref userInfo, value);
|
||||||
|
RenderVideoView();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public DelegateCommand OperClickCommand => new DelegateCommand(() =>
|
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));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,14 +3,17 @@
|
||||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
xmlns:cmn="clr-namespace:Demo.Common;assembly=Demo.Common"
|
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:hc="https://handyorg.github.io/handycontrol"
|
||||||
xmlns:intertop="clr-namespace:Microsoft.DwayneNeed.Interop;assembly=MahApps.Microsoft.DwayneNeed"
|
xmlns:intertop="clr-namespace:Microsoft.DwayneNeed.Interop;assembly=MahApps.Microsoft.DwayneNeed"
|
||||||
xmlns:local="clr-namespace:Meeting.V2.Demo.Views"
|
xmlns:local="clr-namespace:Meeting.V2.Demo.Views"
|
||||||
xmlns:prism="http://prismlibrary.com/"
|
xmlns:prism="http://prismlibrary.com/"
|
||||||
xmlns:wfc="clr-namespace:System.Windows.Forms;assembly=System.Windows.Forms"
|
xmlns:wfc="clr-namespace:System.Windows.Forms;assembly=System.Windows.Forms"
|
||||||
xmlns:wfh="clr-namespace:System.Windows.Forms.Integration;assembly=WindowsFormsIntegration"
|
xmlns:wfh="clr-namespace:System.Windows.Forms.Integration;assembly=WindowsFormsIntegration"
|
||||||
Width="960"
|
Width="962"
|
||||||
Height="640"
|
Height="642"
|
||||||
|
MinWidth="1050"
|
||||||
|
MinHeight="642"
|
||||||
prism:ViewModelLocator.AutoWireViewModel="True"
|
prism:ViewModelLocator.AutoWireViewModel="True"
|
||||||
Background="#252525"
|
Background="#252525"
|
||||||
CloseButtonForeground="Red"
|
CloseButtonForeground="Red"
|
||||||
|
|
@ -18,16 +21,55 @@
|
||||||
NonClientAreaForeground="White"
|
NonClientAreaForeground="White"
|
||||||
OtherButtonForeground="White"
|
OtherButtonForeground="White"
|
||||||
WindowStartupLocation="CenterScreen">
|
WindowStartupLocation="CenterScreen">
|
||||||
|
<Window.Resources>
|
||||||
|
<cnt:BooleanInverseConverter x:Key="BoolInverseConverter" />
|
||||||
|
</Window.Resources>
|
||||||
|
|
||||||
<Grid>
|
<Grid>
|
||||||
<Grid.RowDefinitions>
|
<Grid.RowDefinitions>
|
||||||
<RowDefinition />
|
<RowDefinition />
|
||||||
<RowDefinition Height="55" />
|
<RowDefinition Height="55" />
|
||||||
</Grid.RowDefinitions>
|
</Grid.RowDefinitions>
|
||||||
|
|
||||||
<ContentControl prism:RegionManager.RegionName="{x:Static cmn:RegionNames.VideoRegion}" />
|
<ContentControl Grid.Row="0" prism:RegionManager.RegionName="{x:Static cmn:RegionNames.VideoRegion}" />
|
||||||
<DockPanel Grid.Row="1" Background="#242424">
|
|
||||||
<Button Height="45">加入频道</Button>
|
<ScrollViewer
|
||||||
</DockPanel>
|
Grid.RowSpan="2"
|
||||||
|
HorizontalAlignment="Right"
|
||||||
|
VerticalScrollBarVisibility="Hidden">
|
||||||
|
<StackPanel Margin="0,10,10,10" VerticalAlignment="Top" />
|
||||||
|
</ScrollViewer>
|
||||||
|
<StackPanel
|
||||||
|
Grid.Row="1"
|
||||||
|
HorizontalAlignment="Center"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Background="#242424"
|
||||||
|
Orientation="Horizontal">
|
||||||
|
<hc:TextBox
|
||||||
|
x:Name="uid"
|
||||||
|
HorizontalAlignment="Center"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
hc:InfoElement.Placeholder="输入任意UID"
|
||||||
|
IsEnabled="{Binding IsJoin, Converter={StaticResource BoolInverseConverter}}"
|
||||||
|
Text="{Binding UId}" />
|
||||||
|
<Button
|
||||||
|
Height="45"
|
||||||
|
Margin="10"
|
||||||
|
Command="{Binding JoinChannelCommand}"
|
||||||
|
IsEnabled="{Binding IsJoin, Converter={StaticResource BoolInverseConverter}}">
|
||||||
|
加入频道
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
Height="45"
|
||||||
|
Margin="10"
|
||||||
|
Command="{Binding LeavelChannelCommand}"
|
||||||
|
IsEnabled="{Binding IsJoin}">
|
||||||
|
离开频道
|
||||||
|
</Button>
|
||||||
|
|
||||||
|
|
||||||
|
</StackPanel>
|
||||||
<!--<local:VideoView x:Name="videoVIew" />-->
|
<!--<local:VideoView x:Name="videoVIew" />-->
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|
||||||
</hc:Window>
|
</hc:Window>
|
||||||
|
|
|
||||||
|
|
@ -2,38 +2,86 @@
|
||||||
x:Class="Meeting.V2.Demo.Views.VideoAreaView"
|
x:Class="Meeting.V2.Demo.Views.VideoAreaView"
|
||||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
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: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:local="clr-namespace:Meeting.V2.Demo.Views"
|
||||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
xmlns:prism="http://prismlibrary.com/"
|
xmlns:prism="http://prismlibrary.com/"
|
||||||
|
x:Name="root"
|
||||||
d:DesignHeight="530"
|
d:DesignHeight="530"
|
||||||
d:DesignWidth="960"
|
d:DesignWidth="960"
|
||||||
prism:ViewModelLocator.AutoWireViewModel="True"
|
prism:ViewModelLocator.AutoWireViewModel="True"
|
||||||
mc:Ignorable="d">
|
mc:Ignorable="d">
|
||||||
|
<UserControl.Resources>
|
||||||
|
<cnt:AspectRatioConverter x:Key="AspectRatioConverter" />
|
||||||
|
</UserControl.Resources>
|
||||||
<Grid>
|
<Grid>
|
||||||
<Grid.RowDefinitions>
|
<Grid.RowDefinitions>
|
||||||
<RowDefinition Height="*" />
|
<RowDefinition Height="*" MaxHeight="155" />
|
||||||
<RowDefinition Height="5*" />
|
<RowDefinition Height="5*" />
|
||||||
</Grid.RowDefinitions>
|
</Grid.RowDefinitions>
|
||||||
|
|
||||||
<ItemsControl Padding="10" ItemsSource="{Binding UserInfos}">
|
|
||||||
|
<ItemsControl
|
||||||
|
x:Name="user_vid"
|
||||||
|
Grid.Row="0"
|
||||||
|
Padding="3"
|
||||||
|
ItemsSource="{Binding UserInfos}">
|
||||||
<ItemsControl.ItemsPanel>
|
<ItemsControl.ItemsPanel>
|
||||||
<ItemsPanelTemplate>
|
<ItemsPanelTemplate>
|
||||||
<StackPanel
|
<StackPanel
|
||||||
|
x:Name="stack_users"
|
||||||
HorizontalAlignment="Center"
|
HorizontalAlignment="Center"
|
||||||
VerticalAlignment="Center"
|
Background="#2D3033"
|
||||||
Orientation="Horizontal" />
|
Orientation="Horizontal">
|
||||||
|
<!--<i:Interaction.Triggers>
|
||||||
|
<i:EventTrigger EventName="SizeChanged">
|
||||||
|
<i:InvokeCommandAction Command="{Binding UserStackPanelSizeChangeCommand}" CommandParameter="{Binding ElementName=stack_users}" />
|
||||||
|
</i:EventTrigger>
|
||||||
|
</i:Interaction.Triggers>-->
|
||||||
|
</StackPanel>
|
||||||
</ItemsPanelTemplate>
|
</ItemsPanelTemplate>
|
||||||
</ItemsControl.ItemsPanel>
|
</ItemsControl.ItemsPanel>
|
||||||
<ItemsControl.ItemTemplate>
|
<ItemsControl.ItemTemplate>
|
||||||
<DataTemplate>
|
<DataTemplate>
|
||||||
<local:VideoView UserName="{Binding UserName}" />
|
<local:VideoView
|
||||||
|
Margin="3"
|
||||||
|
Command="{Binding DataContext.SelectedUserCommand, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Border}}"
|
||||||
|
CommandParameter="{Binding DataContext, RelativeSource={RelativeSource AncestorType=ContentPresenter}}"
|
||||||
|
UserInfo="{Binding DataContext, RelativeSource={RelativeSource AncestorType=ContentPresenter}}">
|
||||||
|
<local:VideoView.Width>
|
||||||
|
<MultiBinding Converter="{StaticResource AspectRatioConverter}">
|
||||||
|
<Binding ElementName="user_vid" Path="ActualHeight" />
|
||||||
|
<Binding ElementName="user_vid" Path="ActualWidth" />
|
||||||
|
<!--<Binding Path="DataContext.UserPageSize" RelativeSource="{RelativeSource AncestorType=UserControl}" />
|
||||||
|
<Binding Path="Margin" RelativeSource="{RelativeSource Mode=Self}" />-->
|
||||||
|
|
||||||
|
</MultiBinding>
|
||||||
|
</local:VideoView.Width>
|
||||||
|
|
||||||
|
|
||||||
|
</local:VideoView>
|
||||||
</DataTemplate>
|
</DataTemplate>
|
||||||
</ItemsControl.ItemTemplate>
|
</ItemsControl.ItemTemplate>
|
||||||
</ItemsControl>
|
</ItemsControl>
|
||||||
<!--<StackPanel Name="stack_user" Orientation="Horizontal" />-->
|
<Border
|
||||||
<local:VideoView x:Name="main_video" Grid.Row="1" />
|
x:Name="border_main"
|
||||||
|
Grid.Row="1"
|
||||||
|
Grid.RowSpan="2"
|
||||||
|
Background="#2D3033">
|
||||||
|
<local:VideoView x:Name="main_video" UserInfo="{Binding DataContext.FocusUser, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Border}}">
|
||||||
|
|
||||||
|
<!--<local:VideoView.Width>
|
||||||
|
<MultiBinding Converter="{StaticResource AspectRatioConverter}">
|
||||||
|
<Binding ElementName="border_main" Path="ActualHeight" />
|
||||||
|
<Binding ElementName="border_main" Path="ActualWidth" />
|
||||||
|
</MultiBinding>
|
||||||
|
</local:VideoView.Width>-->
|
||||||
|
|
||||||
|
</local:VideoView>
|
||||||
|
|
||||||
|
</Border>
|
||||||
|
|
||||||
<Button Command="{Binding TestCommand}" Content="测试按钮" />
|
|
||||||
</Grid>
|
</Grid>
|
||||||
</UserControl>
|
</UserControl>
|
||||||
|
|
|
||||||
|
|
@ -21,8 +21,10 @@ namespace Meeting.V2.Demo.Views
|
||||||
public partial class VideoAreaView : UserControl
|
public partial class VideoAreaView : UserControl
|
||||||
{
|
{
|
||||||
public VideoAreaView()
|
public VideoAreaView()
|
||||||
{
|
{
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@
|
||||||
xmlns:cnt="clr-namespace:Demo.Common.Converters;assembly=Demo.Common"
|
xmlns:cnt="clr-namespace:Demo.Common.Converters;assembly=Demo.Common"
|
||||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
xmlns:hc="https://handyorg.github.io/handycontrol"
|
xmlns:hc="https://handyorg.github.io/handycontrol"
|
||||||
|
xmlns:i="http://schemas.microsoft.com/xaml/behaviors"
|
||||||
xmlns:intertop="clr-namespace:Microsoft.DwayneNeed.Interop;assembly=MahApps.Microsoft.DwayneNeed"
|
xmlns:intertop="clr-namespace:Microsoft.DwayneNeed.Interop;assembly=MahApps.Microsoft.DwayneNeed"
|
||||||
xmlns:local="clr-namespace:Meeting.V2.Demo.Views"
|
xmlns:local="clr-namespace:Meeting.V2.Demo.Views"
|
||||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
|
|
@ -12,14 +13,22 @@
|
||||||
xmlns:svgc="http://sharpvectors.codeplex.com/svgc/"
|
xmlns:svgc="http://sharpvectors.codeplex.com/svgc/"
|
||||||
xmlns:wfc="clr-namespace:System.Windows.Forms;assembly=System.Windows.Forms"
|
xmlns:wfc="clr-namespace:System.Windows.Forms;assembly=System.Windows.Forms"
|
||||||
xmlns:wfh="clr-namespace:System.Windows.Forms.Integration;assembly=WindowsFormsIntegration"
|
xmlns:wfh="clr-namespace:System.Windows.Forms.Integration;assembly=WindowsFormsIntegration"
|
||||||
MinWidth="160"
|
x:Name="root"
|
||||||
MinHeight="90"
|
MinWidth="135"
|
||||||
d:DesignHeight="90"
|
MinHeight="75"
|
||||||
d:DesignWidth="160"
|
d:DesignHeight="1080"
|
||||||
|
d:DesignWidth="1920"
|
||||||
prism:ViewModelLocator.AutoWireViewModel="True"
|
prism:ViewModelLocator.AutoWireViewModel="True"
|
||||||
mc:Ignorable="d">
|
mc:Ignorable="d">
|
||||||
|
<i:Interaction.Triggers>
|
||||||
|
<i:EventTrigger EventName="Loaded">
|
||||||
|
<prism:InvokeCommandAction Command="{Binding LoadedCommand}" CommandParameter="{Binding RelativeSource={RelativeSource AncestorType=UserControl}}" />
|
||||||
|
</i:EventTrigger>
|
||||||
|
</i:Interaction.Triggers>
|
||||||
|
|
||||||
<UserControl.Resources>
|
<UserControl.Resources>
|
||||||
<cnt:BoolToVisibilityConverter x:Key="BoolToVisibilityConverter" />
|
<cnt:BoolToVisibilityConverter x:Key="BoolToVisibilityConverter" />
|
||||||
|
<cnt:AspectRatioConverter x:Key="AspectRatioConverter" />
|
||||||
</UserControl.Resources>
|
</UserControl.Resources>
|
||||||
|
|
||||||
<Grid>
|
<Grid>
|
||||||
|
|
@ -31,9 +40,10 @@
|
||||||
<WindowsFormsHost x:Name="gridHost">
|
<WindowsFormsHost x:Name="gridHost">
|
||||||
<wfc:PictureBox
|
<wfc:PictureBox
|
||||||
x:Name="pic_frame"
|
x:Name="pic_frame"
|
||||||
BackColor="#2d3033"
|
BackColor="#000000"
|
||||||
Dock="Fill"
|
Dock="Fill"
|
||||||
MouseEnter="pic_frame_MouseEnter"
|
MouseEnter="pic_frame_MouseEnter"
|
||||||
|
MouseDoubleClick="pic_frame_MouseDoubleClick"
|
||||||
MouseLeave="pic_frame_MouseLeave"
|
MouseLeave="pic_frame_MouseLeave"
|
||||||
SizeMode="StretchImage" />
|
SizeMode="StretchImage" />
|
||||||
</WindowsFormsHost>
|
</WindowsFormsHost>
|
||||||
|
|
@ -61,7 +71,7 @@
|
||||||
HorizontalAlignment="Left"
|
HorizontalAlignment="Left"
|
||||||
VerticalAlignment="Bottom"
|
VerticalAlignment="Bottom"
|
||||||
Orientation="Horizontal">
|
Orientation="Horizontal">
|
||||||
<Border Background="#ff801a" Visibility="{Binding UserInfo.IsManager, Converter={StaticResource BoolToVisibilityConverter}}">
|
<Border Background="#ff801a" Visibility="{Binding UserInfo.IsManager, Mode=TwoWay, Converter={StaticResource BoolToVisibilityConverter}}">
|
||||||
<svgc:SvgViewbox
|
<svgc:SvgViewbox
|
||||||
x:Name="icon_manager"
|
x:Name="icon_manager"
|
||||||
Margin="3"
|
Margin="3"
|
||||||
|
|
@ -76,7 +86,7 @@
|
||||||
VerticalAlignment="Center"
|
VerticalAlignment="Center"
|
||||||
FontSize="12"
|
FontSize="12"
|
||||||
Foreground="White"
|
Foreground="White"
|
||||||
Text="{Binding UserInfo.UserName}" />
|
Text="{Binding UserInfo.UserName, Mode=TwoWay}" />
|
||||||
</Border>
|
</Border>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
<!--#endregion-->
|
<!--#endregion-->
|
||||||
|
|
|
||||||
|
|
@ -1,20 +1,11 @@
|
||||||
using Demo.Common.Models;
|
using Demo.Common.Models;
|
||||||
using Meeting.V2.Demo.ViewModels;
|
using Meeting.V2.Demo.ViewModels;
|
||||||
|
using Prism.Events;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Runtime.CompilerServices;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
using System.Windows.Controls;
|
using System.Windows.Controls;
|
||||||
using System.Windows.Data;
|
|
||||||
using System.Windows.Documents;
|
|
||||||
using System.Windows.Input;
|
using System.Windows.Input;
|
||||||
using System.Windows.Media;
|
|
||||||
using System.Windows.Media.Imaging;
|
|
||||||
using System.Windows.Navigation;
|
|
||||||
using System.Windows.Shapes;
|
|
||||||
|
|
||||||
namespace Meeting.V2.Demo.Views
|
namespace Meeting.V2.Demo.Views
|
||||||
{
|
{
|
||||||
|
|
@ -23,87 +14,41 @@ namespace Meeting.V2.Demo.Views
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public partial class VideoView : UserControl
|
public partial class VideoView : UserControl
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
public VideoView()
|
public VideoView()
|
||||||
{
|
{
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
pic_frame.ImageLocation = $@"E:\桌面\Wall\wallhaven-j3m8v5.jpg";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public User UserInfo
|
||||||
|
|
||||||
//public UserInfo UserInfo
|
|
||||||
//{
|
|
||||||
// get { return (UserInfo)GetValue(UserInfoProperty); }
|
|
||||||
// set { SetValue(UserInfoProperty, value); }
|
|
||||||
//}
|
|
||||||
|
|
||||||
//// Using a DependencyProperty as the backing store for MyProperty. This enables animation, styling, binding, etc...
|
|
||||||
//public static readonly DependencyProperty UserInfoProperty =
|
|
||||||
// DependencyProperty.Register("UserInfo", typeof(UserInfo), typeof(VideoView), new FrameworkPropertyMetadata(null));
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public string UserName
|
|
||||||
{
|
{
|
||||||
get { return (string)GetValue(UserNameProperty); }
|
get { return (User)GetValue(UserInfoProperty); }
|
||||||
set {
|
set { SetValue(UserInfoProperty, value); }
|
||||||
SetValue(UserNameProperty, value); }
|
|
||||||
}
|
}
|
||||||
// Using a DependencyProperty as the backing store for UserName. This enables animation, styling, binding, etc...
|
|
||||||
public static readonly DependencyProperty UserNameProperty =
|
|
||||||
DependencyProperty.Register("UserName", typeof(string), typeof(VideoView), new PropertyMetadata("未知名称", new PropertyChangedCallback(OnUserNamePropertyChangedCallback)));
|
|
||||||
|
|
||||||
private static void OnUserNamePropertyChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
|
// Using a DependencyProperty as the backing store for MyProperty. This enables animation, styling, binding, etc...
|
||||||
|
public static readonly DependencyProperty UserInfoProperty =
|
||||||
|
DependencyProperty.Register("UserInfo", typeof(User), typeof(VideoView), new PropertyMetadata(null, new(OnUserInfoPropertyChangedCallback)));
|
||||||
|
|
||||||
|
private static void OnUserInfoPropertyChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
|
||||||
{
|
{
|
||||||
if (d is VideoView videoView)
|
if (d is VideoView videoView )
|
||||||
{
|
{
|
||||||
videoView.txt_uname.Text = (string)e.NewValue;
|
var viewDataContext = videoView.DataContext as VideoViewModel;
|
||||||
|
viewDataContext.UserInfo = e.NewValue as User;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//public bool IsManager
|
|
||||||
//{
|
|
||||||
// get { return (bool)GetValue(IsManagerProperty); }
|
|
||||||
// set { SetValue(IsManagerProperty, value); }
|
|
||||||
//}
|
|
||||||
|
|
||||||
//// Using a DependencyProperty as the backing store for IsManager. This enables animation, styling, binding, etc...
|
|
||||||
//public static readonly DependencyProperty IsManagerProperty =
|
|
||||||
// DependencyProperty.Register("IsManager", typeof(bool), typeof(VideoView), new PropertyMetadata(false, new(OnIsManagerPropertyChangedCallback)));
|
|
||||||
|
|
||||||
//private static void OnIsManagerPropertyChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
|
|
||||||
//{
|
|
||||||
// if (d is VideoView videoView)
|
|
||||||
// {
|
|
||||||
// if (e.NewValue is bool b)
|
|
||||||
// {
|
|
||||||
// var db = videoView.DataContext as VideoViewModel;
|
|
||||||
// db.UserInfo.IsManager = b;
|
|
||||||
// //if (b)
|
|
||||||
// //{
|
|
||||||
// // videoView.icon_manager.Visibility = Visibility.Visible;
|
|
||||||
// //}
|
|
||||||
// //else
|
|
||||||
// //{
|
|
||||||
// // videoView.icon_manager.Visibility = Visibility.Collapsed;
|
|
||||||
// //}
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#region 控制右上角操作按钮显示与消失
|
#region 控制右上角操作按钮显示与消失
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 控制操作按钮显示
|
/// 控制操作按钮显示
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private bool IsOperVisible = false;
|
private bool IsOperVisible = false;
|
||||||
|
|
||||||
private void pic_frame_MouseEnter(object sender, EventArgs e)
|
private void pic_frame_MouseEnter(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
btn_oper.Visibility = Visibility.Visible;
|
btn_oper.Visibility = Visibility.Visible;
|
||||||
|
|
@ -136,8 +81,45 @@ namespace Meeting.V2.Demo.Views
|
||||||
{
|
{
|
||||||
await Task.Delay(50).ConfigureAwait(false);
|
await Task.Delay(50).ConfigureAwait(false);
|
||||||
|
|
||||||
|
|
||||||
IsOperVisible = false;
|
IsOperVisible = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
#region 命令绑定
|
||||||
|
private void ExcuteCommand()
|
||||||
|
{
|
||||||
|
// 点击操作按钮,触发命令
|
||||||
|
Command?.Execute(CommandParameter);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 依赖属性定义
|
||||||
|
public ICommand Command
|
||||||
|
{
|
||||||
|
get { return (ICommand)GetValue(CommandProperty); }
|
||||||
|
set { SetValue(CommandProperty, value); }
|
||||||
|
}
|
||||||
|
|
||||||
|
public static readonly DependencyProperty CommandProperty =
|
||||||
|
DependencyProperty.Register("Command", typeof(ICommand), typeof(VideoView), new PropertyMetadata(null));
|
||||||
|
|
||||||
|
public object CommandParameter
|
||||||
|
{
|
||||||
|
get { return GetValue(CommandParameterProperty); }
|
||||||
|
set { SetValue(CommandParameterProperty, value); }
|
||||||
|
}
|
||||||
|
|
||||||
|
public static readonly DependencyProperty CommandParameterProperty =
|
||||||
|
DependencyProperty.Register("CommandParameter", typeof(object), typeof(VideoView), new PropertyMetadata(null));
|
||||||
|
|
||||||
|
private void pic_frame_MouseDoubleClick(object sender, System.Windows.Forms.MouseEventArgs e)
|
||||||
|
{
|
||||||
|
ExcuteCommand();
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +0,0 @@
|
||||||
namespace Meeting.V2.Demo.Services.Interfaces
|
|
||||||
{
|
|
||||||
public interface IMessageService
|
|
||||||
{
|
|
||||||
string GetMessage();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -4,4 +4,8 @@
|
||||||
<TargetFramework>netstandard2.1</TargetFramework>
|
<TargetFramework>netstandard2.1</TargetFramework>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="RestSharp" Version="112.1.0" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,12 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Meeting.V2.Demo.Services.Interfaces
|
||||||
|
{
|
||||||
|
public interface IAgoraConfigService : IBaseService
|
||||||
|
{
|
||||||
|
Task GetAgoraConfig();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace Meeting.V2.Demo.Services.Interfaces
|
||||||
|
{
|
||||||
|
public interface IBaseService
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -5,6 +5,7 @@
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\..\..\Demo.Common\Demo.Common.csproj" />
|
||||||
<ProjectReference Include="..\Meeting.V2.Demo.Services.Interfaces\Meeting.V2.Demo.Services.Interfaces.csproj" />
|
<ProjectReference Include="..\Meeting.V2.Demo.Services.Interfaces\Meeting.V2.Demo.Services.Interfaces.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,12 +0,0 @@
|
||||||
using Meeting.V2.Demo.Services.Interfaces;
|
|
||||||
|
|
||||||
namespace Meeting.V2.Demo.Services
|
|
||||||
{
|
|
||||||
public class MessageService : IMessageService
|
|
||||||
{
|
|
||||||
public string GetMessage()
|
|
||||||
{
|
|
||||||
return "Hello from the Message Service";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Loading…
Reference in New Issue