using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Newtonsoft.Json;
using WingInterfaceLibrary.DB.Request;
using WingInterfaceLibrary.DTO.Device;
using WingInterfaceLibrary.DTO.LiveRoom;
using WingInterfaceLibrary.DTO.Share;
using WingInterfaceLibrary.Enum;
using WingInterfaceLibrary.Interface;
using WingInterfaceLibrary.Internal.Request;
using WingInterfaceLibrary.Notifications;
using WingInterfaceLibrary.Notifications.Live;
using WingInterfaceLibrary.Notifications.Remote;
using WingInterfaceLibrary.Request;
using WingInterfaceLibrary.Request.Authentication;
using WingInterfaceLibrary.Request.Device;
using WingInterfaceLibrary.Request.Remote;
using WingServerCommon.Config;
using WingServerCommon.Interfaces.Cache;
using WingServerCommon.Service;
namespace WingDeviceService.Service
{
///
/// 设备直播
///
public partial class DeviceService : JsonRpcService, IDeviceService
{
///
/// 用户进入设备直播房间
///
/// 用户进入设备直播房间请求实体
///
public async Task JoinDeviceLiveRoomAsync(JoinDeviceLiveRoomRequest request)
{
var userInfo = await _authenticationService.GetTokenAsync(request);
var deviceCode = request.DeviceCode;
var deviceTokenInfo = CacheMaintenance.Instance.Get().Where(x => x.ClientId == deviceCode).FirstOrDefault();
if (deviceTokenInfo == null || !deviceTokenInfo.IsOnline)
{
ThrowCustomerException(CustomerRpcCode.DeviceNotOnline, "DeviceNotOnline");
}
if (deviceTokenInfo.IsOldPlatform)
{
await _deviceForwardService.GetDeviceVideoInfosAsync(new GetDeviceVideoInfosRequest { DeviceCode = deviceCode });
}
var deviceInfo = CacheMaintenance.Instance.Get().Get(deviceCode);
if (deviceInfo == null)
{
ThrowCustomerException(CustomerRpcCode.DeviceNotExist, "Not find device");
}
if (!deviceInfo.LiveOpened)
{
ThrowCustomerException(CustomerRpcCode.DeviceLiveClosed, "DeviceLiveClosed");
}
return await JoinDeviceLiveRoomAsync(deviceCode, userInfo);
}
///
/// 用户离开设备直播房间
///
/// 用户离开设备直播房间请求实体
///
public async Task LeaveDeviceLiveRoomAsync(LeaveDeviceLiveRoomRequest request)
{
var userInfo = await _authenticationService.GetTokenAsync(request);
var userCode = userInfo.ClientId;
var deviceCode = request.DeviceCode;
var liveRoom = await _rtcService.GetInitiatingRoomByDeviceCodeAsync(new GetInitiatingRoomByDeviceCodeRequest
{
DeviceCode = deviceCode
});
if (liveRoom != null)
{
//移除观众
var removeViewerResult = await _rtcService.RemoveViewerAsync(new RemoveViewerRequest
{
LiveRoomCode = liveRoom.LiveRoomCode,
UserCode = userInfo.ClientId,
});
var timeoutTime = DateTime.UtcNow.AddSeconds(-1 * _reportStateTimeout);
if (liveRoom.BusinessModule == BusinessModuleEnum.DeviceLiving && !liveRoom.ViewerInfos.Any(x => x.UserCode != userCode && x.LastReportTime >= timeoutTime))
{
await _rtcService.CloseAsync(new CloseRequest
{
LiveRoomCode = liveRoom.LiveRoomCode
});
}
}
return true;
}
///
/// 上报观看直播状态
///
/// 上报观看直播状态请求实体
///
public async Task ReportLiveViewStateAsync(ReportLiveViewStateRequest request)
{
var userInfo = await _authenticationService.GetTokenAsync(request);
var deviceCode = request.DeviceCode;
var liveRoom = await _rtcService.GetInitiatingRoomByDeviceCodeAsync(new GetInitiatingRoomByDeviceCodeRequest
{
DeviceCode = deviceCode
});
if (liveRoom != null)
{
//添加观众
var addOrUpdateViewerResult = await _rtcService.SaveViewerAsync(new SaveViewerRequest
{
LiveRoomCode = liveRoom.LiveRoomCode,
UserCode = userInfo.ClientId,
UserName = userInfo.AccountName,
});
}
return true;
}
///
/// 生成设备直播分享地址
///
/// 生成设备直播分享地址请求实体
///
///
public async Task CreateLiveShareInfoAsync(CreateLiveShareInfoRequest request)
{
var deviceCode = request.DeviceCode;
var deviceInfo = CacheMaintenance.Instance.Get().Get(deviceCode);
if (deviceInfo == null)
{
ThrowCustomerException(CustomerRpcCode.DeviceNotExist, "Not find device");
}
if (!deviceInfo.LiveOpened)
{
ThrowCustomerException(CustomerRpcCode.DeviceLiveClosed, "DeviceLiveClosed");
}
var userInfo = await _authenticationService.GetTokenAsync(request);
var shareInfo = new DeviceLiveShareInfoDTO
{
DeviceCode = request.DeviceCode,
ShareUserCode = userInfo.Code,
ShareUserName = userInfo.AccountName,
ShareTime = DateTime.UtcNow,
};
var shareContent = Newtonsoft.Json.JsonConvert.SerializeObject(shareInfo);
var shortCode = await _shareDBService.AddShareInfoAsync(new AddShareInfoDBRequest { Data = new ShareDTO { ShareContent = shareContent } });
return new CreateLiveShareInfoResult
{
ShareUrl = string.Format(_deviceShareUrl, shortCode),
};
}
///
/// 用户进入设备直播房间(无token)
///
/// 用户进入设备直播房间请求实体
///
///
public async Task JoinDeviceLiveRoomByShareAsync(JoinDeviceLiveRoomByShareRequest request)
{
if (string.IsNullOrWhiteSpace(request.ShareCode))
{
ThrowCustomerException(CustomerRpcCode.ShareCodeIsEmpty, "ShareCodeIsEmpty");
}
var shareResult = await _shareDBService.GetShareInfoAsync(new GetShareInfoDBRequest
{
ShortCode = request.ShareCode,
});
if (string.IsNullOrWhiteSpace(shareResult.ShareContent))
{
ThrowCustomerException(CustomerRpcCode.DeviceShareDataError, "DeviceShareDataError");
}
DeviceLiveShareInfoDTO shareInfo = null;
try
{
shareInfo = Newtonsoft.Json.JsonConvert.DeserializeObject(shareResult.ShareContent);
}
catch (Exception ex)
{
ThrowCustomerException(CustomerRpcCode.DeviceShareDataError, "DeviceShareDataError");
}
if (shareInfo == null || shareInfo.ShareTime.AddSeconds(_shareEffectiveSeconds) < DateTime.UtcNow)
{
ThrowCustomerException(CustomerRpcCode.DeviceShareExpired, "DeviceShareExpired");
}
var deviceCode = shareInfo.DeviceCode;
var deviceInfo = CacheMaintenance.Instance.Get().Get(deviceCode);
if (deviceInfo == null)
{
ThrowCustomerException(CustomerRpcCode.DeviceNotExist, "Not find device");
}
if (!deviceInfo.LiveOpened)
{
ThrowCustomerException(CustomerRpcCode.DeviceLiveClosed, "DeviceLiveClosed");
}
var deviceTokenInfo = CacheMaintenance.Instance.Get().Where(x => x.ClientId == deviceCode).FirstOrDefault();
if (deviceTokenInfo == null || !deviceTokenInfo.IsOnline)
{
ThrowCustomerException(CustomerRpcCode.DeviceNotOnline, "DeviceNotOnline");
}
if (deviceTokenInfo.IsOldPlatform)
{
await _deviceForwardService.GetDeviceVideoInfosAsync(new GetDeviceVideoInfosRequest { DeviceCode = deviceCode });
}
var joinResult = await JoinDeviceLiveRoomAsync(deviceCode);
return new JoinDeviceLiveRoomByShareResult
{
RoomNo = joinResult.RoomNo,
LiveProtocol = EnvironmentConfigs.General.LiveProtocolDetail(),
ReportStateIntervalSeconds = joinResult.ReportStateIntervalSeconds,
DeviceCode = joinResult.DeviceCode,
MergedChannel = joinResult.MergedChannel,
MergedVideoOutputWidth = joinResult.MergedVideoOutputWidth,
MergedVideoOutputHeight = joinResult.MergedVideoOutputHeight,
VideoDeviceInfos = joinResult.VideoDeviceInfos,
IsOldPlatform = joinResult.IsOldPlatform,
SupportRtc = joinResult.SupportRtc,
};
}
///
/// 用户离开设备直播房间(无token)
///
/// 用户离开设备直播房间请求实体
///
///
public async Task LeaveDeviceLiveRoomByShareAsync(LeaveDeviceLiveRoomByShareRequest request)
{
if (string.IsNullOrWhiteSpace(request.DeviceCode))
{
ThrowCustomerException(CustomerRpcCode.DeviceCodeIsEmpty, "DeviceCodeIsEmpty");
}
if (string.IsNullOrWhiteSpace(request.ViewerUniqueId))
{
ThrowCustomerException(CustomerRpcCode.UniqueIdIsEmpty, "UniqueIdIsEmpty");
}
var userCode = request.ViewerUniqueId;
var deviceCode = request.DeviceCode;
var liveRoom = await _rtcService.GetInitiatingRoomByDeviceCodeAsync(new GetInitiatingRoomByDeviceCodeRequest
{
DeviceCode = deviceCode
});
if (liveRoom != null)
{
//移除观众
var removeViewerResult = await _rtcService.RemoveViewerAsync(new RemoveViewerRequest
{
LiveRoomCode = liveRoom.LiveRoomCode,
UserCode = userCode,
});
var timeoutTime = DateTime.UtcNow.AddSeconds(-1 * _reportStateTimeout);
if (liveRoom.BusinessModule == BusinessModuleEnum.DeviceLiving && !liveRoom.ViewerInfos.Any(x => x.UserCode != userCode && x.LastReportTime >= timeoutTime))
{
await _rtcService.CloseAsync(new CloseRequest
{
LiveRoomCode = liveRoom.LiveRoomCode
});
}
}
return true;
}
///
/// 上报观看直播状态(无token)
///
/// 上报观看直播状态请求实体
///
///
public async Task ReportLiveViewStateByShareAsync(ReportLiveViewStateByShareRequest request)
{
if (string.IsNullOrWhiteSpace(request.DeviceCode))
{
ThrowCustomerException(CustomerRpcCode.DeviceCodeIsEmpty, "DeviceCodeIsEmpty");
}
if (string.IsNullOrWhiteSpace(request.ViewerUniqueId))
{
ThrowCustomerException(CustomerRpcCode.UniqueIdIsEmpty, "UniqueIdIsEmpty");
}
var deviceCode = request.DeviceCode;
var liveRoom = await _rtcService.GetInitiatingRoomByDeviceCodeAsync(new GetInitiatingRoomByDeviceCodeRequest
{
DeviceCode = deviceCode
});
if (liveRoom != null)
{
//添加观众
var uniqueId = request.ViewerUniqueId;
var addOrUpdateViewerResult = await _rtcService.SaveViewerAsync(new SaveViewerRequest
{
LiveRoomCode = liveRoom.LiveRoomCode,
UserCode = uniqueId,
UserName = uniqueId,
});
}
return true;
}
///
/// 开始直播
///
///
///
///
private async Task JoinDeviceLiveRoomAsync(string deviceCode, TokenDTO userInfo = null)
{
var deviceInfo = CacheMaintenance.Instance.Get().Get(deviceCode);
if (deviceInfo == null)
{
ThrowCustomerException(CustomerRpcCode.DeviceNotExist, "Not find device");
}
var liveRoom = await _rtcService.GetInitiatingRoomByDeviceCodeAsync(new GetInitiatingRoomByDeviceCodeRequest
{
DeviceCode = deviceCode
});
var deviceTokenInfo = CacheMaintenance.Instance.Get().Where(x => x.ClientId == deviceCode)?.FirstOrDefault();
LiveMemberDTO deviceMemberInfo;
if (liveRoom != null)
{
if (liveRoom.LiveRoomCode == deviceCode)
{
//设备正在推流
deviceMemberInfo = liveRoom.DeviceInfos.FirstOrDefault(x => x.Code == deviceCode);
if (deviceMemberInfo?.Status == LiveMemberStatus.Joined)
{
if (userInfo != null)
{
//添加观众
await _rtcService.SaveViewerAsync(new SaveViewerRequest
{
LiveRoomCode = liveRoom.LiveRoomCode,
UserCode = userInfo.ClientId,
UserName = userInfo.AccountName,
});
}
return new JoinDeviceLiveRoomResult
{
RoomNo = liveRoom.RtcRoomId,
LiveProtocol = EnvironmentConfigs.General.LiveProtocolDetail(),
ReportStateIntervalSeconds = _reportStateIntervalSeconds,
DeviceCode = deviceCode,
MergedChannel = deviceInfo.MergedChannel,
MergedVideoOutputWidth = deviceInfo.MergedVideoOutputWidth,
MergedVideoOutputHeight = deviceInfo.MergedVideoOutputHeight,
VideoDeviceInfos = deviceMemberInfo.VideoDeviceInfos?.Select(x => new VideoDeviceInfoDTO
{
VideoDeviceId = x.VideoDeviceId,
VideoDeviceSourceType = x.VideoDeviceSourceType,
LiveData = x.LiveData
})?.ToList() ?? new List(),
IsOldPlatform = deviceTokenInfo != null && deviceTokenInfo.IsOnline && deviceTokenInfo.IsOldPlatform,
SupportRtc = deviceInfo.SupportRtc,
};
}
}
}
//新增或更新设备直播间
var deviceName = deviceInfo.DisplayName;
var deviceLiveInfo = new LiveMemberDTO
{
Code = deviceCode,
Name = deviceName,
MemberType = LiveMemberEnum.Device,
HeadImageToken = deviceInfo.HeadPicUrl,
Status = LiveMemberStatus.Accepted,
};
var room = new LiveRoomDTO
{
LiveRoomCode = deviceCode,
Name = deviceName,
RelatedCode = deviceCode,
BusinessModule = BusinessModuleEnum.DeviceLiving,
Status = LiveRoomStatus.Default,
UserInfos = new List(),
DeviceInfos = new List { deviceLiveInfo }
};
await _rtcService.AddOrUpdateLiveRoomAsync(new AddOrUpdateLiveRoomRequest
{
LiveRoom = room,
});
var initiateResult = await _rtcService.InitiateAsync(new InitiateRequest
{
LiveRoomCode = deviceCode,
InitiatorCode = deviceCode,
});
deviceMemberInfo = initiateResult.DeviceInfos.FirstOrDefault(x => x.Code == deviceCode);
if (userInfo != null)
{
//添加观众
await _rtcService.SaveViewerAsync(new SaveViewerRequest
{
LiveRoomCode = initiateResult.LiveRoomCode,
UserCode = userInfo.ClientId,
UserName = userInfo.AccountName,
});
}
return new JoinDeviceLiveRoomResult
{
RoomNo = initiateResult.RtcRoomId,
LiveProtocol = EnvironmentConfigs.General.LiveProtocolDetail(),
ReportStateIntervalSeconds = _reportStateIntervalSeconds,
DeviceCode = deviceCode,
MergedChannel = deviceInfo.MergedChannel,
MergedVideoOutputWidth = deviceInfo.MergedVideoOutputWidth,
MergedVideoOutputHeight = deviceInfo.MergedVideoOutputHeight,
VideoDeviceInfos = deviceMemberInfo.VideoDeviceInfos?.Select(x => new VideoDeviceInfoDTO
{
VideoDeviceId = x.VideoDeviceId,
VideoDeviceSourceType = x.VideoDeviceSourceType,
LiveData = x.LiveData
})?.ToList() ?? new List(),
IsOldPlatform = deviceTokenInfo != null && deviceTokenInfo.IsOnline && deviceTokenInfo.IsOldPlatform,
SupportRtc = deviceInfo.SupportRtc,
};
}
}
}