private async Task PlayFromOffset( string userId, Station station, NowPlaying ownerNP, StationServiceResult result, TimeSpan error = default) { if (error.Equals(default))
public async Task <StationServiceResult> Start(string userId, string stationId) { if (string.IsNullOrEmpty(userId)) { throw new ArgumentNullException(nameof(userId)); } if (string.IsNullOrEmpty(stationId)) { throw new ArgumentNullException(nameof(stationId)); } var result = new StationServiceResult { Logs = new List <MetricLogEntry>() }; string sId = Station.CanonicalId(stationId); var station = await _data.GetOrDefault(sId, sId); if (station == null) { return new StationServiceResult { Status = 404, Message = $"Station ({stationId}) not found" } } ; // Does station have an owner, and is it this user? if (station.OwnerUserId != null && station.OwnerUserId != userId) { result.Message = $"Station ({stationId}) already has another owner. Change owner before starting."; result.Status = 500; result.Code = StationServiceResult.StationHasOwner; return(result); } var np = await GetNowPlaying(userId, result); if (!np.IsPlaying) { result.Message = "User's device is not active"; result.Status = 202; result.Code = StationServiceResult.UserDeviceNotActive; return(result); } if (!ContextSupported(np)) { result.Message = $"Spotify playback context ({np.Context?.Type}) is not supported."; result.Status = 500; result.Code = StationServiceResult.ContextNotSupported; return(result); } // set player await _playerService.SetPlayer(stationId, userId, np); // set owner station.OwnerUserId = userId; // set startdate station.StartDateTime = DateTimeOffset.UtcNow; await _data.Replace(station, station.ETag); result.Status = 200; result.Message = "Playing"; result.Success = true; return(result); }
public async Task <StationServiceResult> Join(string userId, string stationId) { if (string.IsNullOrEmpty(userId)) { throw new ArgumentNullException(nameof(userId)); } if (string.IsNullOrEmpty(stationId)) { throw new ArgumentNullException(nameof(stationId)); } var result = new StationServiceResult { Logs = new List <MetricLogEntry>() }; string sId = Station.CanonicalId(stationId); var station = await _data.GetOrDefault(sId, sId); if (station == null) { return new StationServiceResult { Status = 404, Message = $"Station ({stationId}) not found" } } ; if (station.OwnerUserId == null) { return new StationServiceResult { Status = 500, Message = $"Station ({stationId}) has no owner. Start the station to continue.", Code = StationServiceResult.StationHasNoOwner } } ; var ownerNP = await GetNowPlaying(station.OwnerUserId, result); if (!ownerNP.IsPlaying) { // set player await _playerService.SetPlayer(stationId, station.OwnerUserId, ownerNP); return(new StationServiceResult { Status = 202, Message = $"Station ({stationId}) Owner's device is not active", Code = StationServiceResult.StationOwnersDeviceNotActive }); } if (!ContextSupported(ownerNP)) { // set player await _playerService.SetPlayer(stationId, station.OwnerUserId, ownerNP); result.Message = $"Spotify playback context ({ownerNP.Context?.Type}) is not supported."; result.Status = 500; result.Code = StationServiceResult.ContextNotSupported; return(result); } // ONE var np1 = await GetNowPlaying(userId, result); if (!np1.IsPlaying) { // set player await _playerService.SetPlayer(stationId, userId, np1); return(new StationServiceResult { Status = 202, Message = "User's device is not active", Code = StationServiceResult.UserDeviceNotActive }); } // SYNC user to owner await TurnOffShuffleRepeat(userId, np1); try { // mute joining player await MuteUnmute(userId, np1, true); // TWO await PlayFromOffset(userId, station, ownerNP, result); // THREE //CALCULATE ERROR, if greater than 250ms, DO FOUR var ownerNP2 = await GetNowPlaying(station.OwnerUserId, result); var error = CalculateError(ownerNP2, await GetNowPlaying(userId, result), result); if (Math.Abs(error.TotalMilliseconds) > 500) { // FOUR // PLAY OFFSET AGAIN await PlayFromOffset(userId, station, ownerNP2, result, error : error); var ownerNP3 = await GetNowPlaying(station.OwnerUserId, result); var error2 = CalculateError(ownerNP3, await GetNowPlaying(userId, result), result); if (Math.Abs(error2.TotalMilliseconds) > 500) { // FIVE // PLAY OFFSET AGAIN await PlayFromOffset(userId, station, ownerNP3, result, error : error2); CalculateError(await GetNowPlaying(station.OwnerUserId, result), await GetNowPlaying(userId, result), result); } } } finally { // unmute joining player await MuteUnmute(userId, np1, false, volume : np1.Device.VolumePercent ?? 100); } // set Owner.Player await _playerService.SetPlayer(stationId, station.OwnerUserId, ownerNP); // set User.Player await _playerService.SetPlayer(stationId, userId, np1); result.Status = 200; result.Message = "Playing"; return(result); }