public async Task <ActionResult <TTSTask> > SubmitText([FromBody] TTSRequest ttsRequest) { if (!ttsRequest.IsValid(ModelState)) { return(BadRequest(ttsRequest.GetErrors())); } var result = await _textToSpeechTaskService.SubmitTaskAsync(ttsRequest); return(Ok(result)); }
public async Task <TTSTask> SubmitTaskAsync(TTSRequest ttsRequest) { var ttsTask = new TTSTask { Submitted = DateTime.UtcNow, Status = Status.Submitted, Text = ttsRequest.Text, }; var savedTask = await _ttsTasksRepository.AddTTSTaskAsync(ttsTask); _backgroundJobClient.Enqueue <ITTSTaskProcessor>(t => t.Process(savedTask)); return(savedTask); }
public IActionResult Play( TTSRequest request) { if (string.IsNullOrEmpty(request.Voice) || string.IsNullOrEmpty(request.Pitch) || string.IsNullOrEmpty(request.Text)) { return(BadRequest()); } string user = request.User; if (string.IsNullOrEmpty(user)) { user = "******"; } Effect effect; if (string.IsNullOrEmpty(request.Effect) || request.Effect.ToLower() == "none") { effect = new NoEffect(); } else { effect = audioEffectSystem.SafeParse(request.Effect); } ttsHandler.HandleTTS( user: new Database.User() { AuthorizationLevel = Commands.AuthorizationLevel.Elevated, TwitchUserName = user, TTSVoicePreference = request.Voice.TranslateTTSVoice(), TTSPitchPreference = request.Pitch.TranslateTTSPitch(), TTSEffectsChain = effect.GetEffectsChain() }, message: request.Text, approved: true); return(Ok()); }
private byte[] Synthesis(XfyunTTSSettings settings, string text) { var apiSecret = settings.ApiSecret; var apiKey = settings.ApiKey; var appId = settings.AppId; if (string.IsNullOrEmpty(apiKey) || string.IsNullOrEmpty(apiSecret) || string.IsNullOrEmpty(appId)) { Logger.Error(strings.msgErrorEmptyApiSecretKey); _settingsControl.NotifyEmptyApiKey(); return(null); } var base64Text = Convert.ToBase64String(Encoding.UTF8.GetBytes(text)); if (base64Text.Length > 8000) { Logger.Error("Convert string too long. No more than 2000 chinese characters."); return(null); } using (var ws = SystemClientWebSocket.CreateClientWebSocket()) { // Connect var date = DateTime.UtcNow.ToString("R"); var sign = $"host: tts-api.xfyun.cn\ndate: {date}\nGET /v2/tts HTTP/1.1"; string sha; using (var hash = new HMACSHA256(Encoding.UTF8.GetBytes(apiSecret))) { sha = Convert.ToBase64String(hash.ComputeHash(Encoding.UTF8.GetBytes(sign))); hash.Clear(); } var authorization = $"api_key=\"{apiKey}\"," + $" algorithm=\"hmac-sha256\"," + $" headers=\"host date request-line\"," + $" signature=\"{sha}\""; var url = $"wss://tts-api.xfyun.cn/v2/tts?host=tts-api.xfyun.cn" + $"&date={WebUtility.UrlEncode(date).Replace("+", "%20")}" + $"&authorization={Convert.ToBase64String(Encoding.UTF8.GetBytes(authorization))}"; try { ws.ConnectAsync(new Uri(url), _wsCancellationSource.Token).Wait(); } catch (AggregateException e) { var inner = e.InnerExceptions.First().GetBaseException(); if (inner is WebException webException) { var resp = (HttpWebResponse)webException.Response; string body = null; using (var stream = resp.GetResponseStream()) { if (stream != null) { var reader = new StreamReader(stream, string.IsNullOrEmpty(resp.CharacterSet) ? Encoding.UTF8 : Encoding.GetEncoding(resp.CharacterSet)); body = reader.ReadToEnd(); } } Logger.Error($"Unable to connect to server: {body}"); switch (resp.StatusCode) { case HttpStatusCode.Unauthorized: case HttpStatusCode.Forbidden: Logger.Error(strings.msgErrorXfyunAuthFail); return(null); } } throw; } // Send request var request = new TTSRequest { Common = new TTSRequest.CommonParam { AppId = settings.AppId, }, Business = new TTSRequest.BusinessParam { Voice = settings.Voice, Pitch = settings.Pitch * 10, Speed = settings.Speed * 10, Volume = settings.Volume * 10, }, Data = new TTSRequest.DataParam { Status = 2, Text = base64Text, } }; ws.SendText(JsonConvert.SerializeObject(request), _wsCancellationSource); // Start receiving var buffer = new MemoryStream(); var session = new WebSocketHelper.Session(ws); while (true) { var message = WebSocketHelper.ReceiveNextMessage(session, _wsCancellationSource); Logger.Debug($"Received WS message\n{message}"); if (message.Type == WebSocketMessageType.Text) { var resp = JsonConvert.DeserializeObject <TTSResponse>(message.MessageStr); if (resp.Code == 0) { // Success! if (resp.Data != null) { var data = Convert.FromBase64String(resp.Data.Audio); buffer.Write(data, 0, data.Length); if (resp.Data.Status == 2) { // Complete! return(buffer.ToArray()); } } } else { Logger.Error($"Unexpected response code received: {resp.Code}: {resp.Message}"); switch (resp.Code) { case 10005: case 10313: Logger.Error(strings.msgErrorXfyunWrongAppId); break; case 11200: case 11201: Logger.Error(strings.msgErrorXfyunInsufficientApiQuota); break; } return(null); } } else if (message.Type == WebSocketMessageType.Binary) { throw new IOException("Unexpected binary message received"); } else if (message.Type == WebSocketMessageType.Close) { throw new IOException("Unexpected closing of connection"); } else { throw new ArgumentOutOfRangeException(); } } } }