public async Task ProcessAsync(TTSTask ttsTask)
        {
            await _textToSpeechTaskService.StartTaskAsync(ttsTask.TaskId);

            var speech = await _textToSpeechService.TextToSpeechAsync(ttsTask.Text);

            await _textToSpeechTaskService.CompleteTaskAsync(ttsTask.TaskId, speech);
        }
        // 更新文本转语音任务队列
        void updateTaskQueue()
        {
            for (int i = 0; i < taskQueue.Count;)
            {
                TTSTask task    = taskQueue[i];
                bool    removed = false;

                switch (task.state)
                {
                case TTSTask.State.Queuing:
                {
                    if (File.Exists(task.filePath))
                    {
                        task.state = TTSTask.State.Translated;

                        if (i == 0)
                        {
                            playTTSTask(task);
                        }
                    }
                    else
                    {
                        if (!translatingTasks.Contains(task.filePath))
                        {
                            translatingTasks.Add(task.filePath);
                            translateTTSTask(task);
                        }
                    }
                }

                break;

                case TTSTask.State.Translating:
                    break;

                case TTSTask.State.Translated:
                    if (i == 0)
                    {
                        playTTSTask(task);
                    }
                    break;

                case TTSTask.State.Playing:
                    break;

                case TTSTask.State.Fin:
                    taskQueue.RemoveAt(i);
                    removed = true;
                    break;
                }

                if (!removed)
                {
                    ++i;
                }
            }
        }
        // 文本转语音完毕
        void onTranslateFinished(string err, TTSTask task, byte[] audioData)
        {
            if (string.IsNullOrEmpty(err))
            {
                // 没有错误,转换成功

                try
                {
                    if (File.Exists(task.filePath))
                    {
                        File.Delete(task.filePath);
                    }

                    if (!Directory.Exists(pluginDir))
                    {
                        Directory.CreateDirectory(pluginDir);
                    }
                    if (!Directory.Exists(voicesDir))
                    {
                        Directory.CreateDirectory(voicesDir);
                    }

                    // 声音数据写入文件
                    File.WriteAllBytes(task.filePath, audioData);

                    foreach (TTSTask itTask in taskQueue)
                    {
                        if (itTask.filePath == task.filePath)
                        {
                            itTask.state = TTSTask.State.Translated;
                        }
                    }
                }
                catch (Exception e)
                {
                    Log(e.Message);

                    task.state = TTSTask.State.Fin;
                }
            }
            else
            {
                // 有错误,转换失败

                Log(err);

                // 出错的任务直接设为 fin
                task.state = TTSTask.State.Fin;
            }

            translatingTasks.Remove(task.filePath);

            updateTaskQueue();
        }
        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);
        }
        // 播放文本语音
        void playTTSTask(TTSTask task)
        {
            task.state = TTSTask.State.Playing;

            if (needInitAudio)
            {
                needInitAudio = false;

                AudioService.playStoppedEvent -= onPlayFinished;
                AudioService.uninit();
                AudioService.init(config);
                AudioService.playStoppedEvent += onPlayFinished;
            }

            AudioService.playAudio(task.filePath);
        }
        public async Task UpdateTTSTaskAsync(TTSTask ttsTask)
        {
            var entity = await _context.TTSTasks.FindAsync(ttsTask.TaskId);

            if (entity != null)
            {
                entity.Started               = ttsTask.Started;
                entity.Submitted             = ttsTask.Submitted;
                entity.Completed             = ttsTask.Completed;
                entity.Status                = (byte)ttsTask.Status;
                entity.Text                  = ttsTask.Text;
                entity.Audio                 = ttsTask.Audio;
                _context.Entry(entity).State = EntityState.Modified;
                await _context.SaveChangesAsync();
            }
        }
        // 开始文本转语音
        void translateTTSTask(TTSTask task)
        {
            task.state = TTSTask.State.Translating;

            if (needInitTTS)
            {
                needInitTTS = false;

                TTSService.uninit();
                string secretId  = config.useCustomSecret ? config.secretId : TencentSecret.secretId;
                string secretKey = config.useCustomSecret ? config.secretKey : TencentSecret.secretKey;
                TTSService.init(secretId, secretKey);
            }

            TTSService.translate(task.text, config.volume, (int)config.speed, (int)config.voiceType, (text, audioData, err) =>
            {
                onTranslateFinished(err, task, audioData);
            });
        }
        public async Task <TTSTask> AddTTSTaskAsync(TTSTask ttsTask)
        {
            var entity = new TTSTaskEntity
            {
                Id        = Guid.NewGuid(),
                Status    = (byte)ttsTask.Status,
                Submitted = ttsTask.Submitted,
                Started   = ttsTask.Started,
                Completed = ttsTask.Completed,
                Text      = ttsTask.Text,
                Audio     = ttsTask.Audio,
            };
            await _context.TTSTasks.AddAsync(entity);

            await _context.SaveChangesAsync();

            ttsTask.TaskId = entity.Id;
            return(ttsTask);
        }
        // 添加一个文本转语音任务
        void addTTSTask(string text)
        {
            if (string.IsNullOrEmpty(text) || string.IsNullOrWhiteSpace(text))
            {
                return;
            }

            TTSTask task = new TTSTask()
            {
                state = TTSTask.State.Queuing, text = text
            };

            byte[] bytes = Encoding.UTF8.GetBytes(text);
            uint   crc32 = Crc32Algorithm.Compute(bytes);

            task.filePath = string.Format("{0}{1}_{2}_{3}_{4}.mp3", voicesDir, crc32, config.volume, config.speed, config.voiceType);

            taskQueue.Add(task);

            updateTaskQueue();
        }
        public async Task <TTSTask> GetTTSTaskAsync(Guid id)
        {
            var entity = await _context.TTSTasks.FindAsync(id);

            if (entity == null)
            {
                return(null);
            }

            var ttsTask = new TTSTask
            {
                TaskId    = entity.Id,
                Submitted = entity.Submitted,
                Started   = entity.Started,
                Completed = entity.Completed,
                Status    = (Status)entity.Status,
                Text      = entity.Text,
                Audio     = entity.Audio,
            };

            return(ttsTask);
        }
 public void Process(TTSTask ttsTask)
 {
     ProcessAsync(ttsTask).Wait();
 }