TimbreService.php 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396
  1. <?php
  2. namespace App\Services\Timbre;
  3. use App\Consts\ErrorConst;
  4. use App\Facade\Site;
  5. use App\Libs\Utils;
  6. use GuzzleHttp\Client;
  7. use Illuminate\Support\Facades\DB;
  8. use Illuminate\Support\Facades\Log;
  9. use Illuminate\Support\Facades\Redis;
  10. use OSS\Core\OssException;
  11. use OSS\OssClient;
  12. class TimbreService
  13. {
  14. public function __construct() {
  15. }
  16. public function addCategory($data) {
  17. $category_name = getProp($data, 'category_name');
  18. $pid = getProp($data, 'pid');
  19. if ($pid === '') Utils::throwError('20003:参数异常');
  20. $category = DB::table('mp_timbre_categories')->where('category_name', $category_name)->first();
  21. if ($category) {
  22. return Utils::throwError('20003:该分类已存在');
  23. }
  24. if ($pid) {
  25. $category = DB::table('mp_timbre_categories')->where('id', $pid)->first();
  26. if (!$category) {
  27. return Utils::throwError('20003:该分类不存在');
  28. }
  29. }
  30. $category_id = DB::table('mp_timbre_categories')->insertGetId([
  31. 'category_name' => $category_name,
  32. 'pid' => $pid,
  33. 'created_at' => date('Y-m-d H:i:s'),
  34. 'updated_at' => date('Y-m-d H:i:s'),
  35. ]);
  36. if (!$category_id) Utils::throwError('20003:添加失败');
  37. return [
  38. 'category_id' => $category_id,
  39. 'category_name' => $category_name,
  40. 'pid' => $pid,
  41. ];
  42. }
  43. public function editCategory($data) {
  44. $category_id = getProp($data, 'category_id');
  45. $category_name = getProp($data, 'category_name');
  46. $category = DB::table('mp_timbre_categories')->where('id', $category_id)->first();
  47. if (!$category) {
  48. return Utils::throwError('20003:该分类不存在');
  49. }
  50. $category = DB::table('mp_timbre_categories')->where('category_name', $category_name)->first();
  51. if ($category && $category->id != $category_id) {
  52. return Utils::throwError('20003:该分类已存在');
  53. }
  54. return DB::table('mp_timbre_categories')->where('id', $category_id)->update([
  55. 'category_name' => $category_name,
  56. 'updated_at' => date('Y-m-d H:i:s'),
  57. ]);
  58. }
  59. public function getCategoryList($data) {
  60. $category_type = getProp($data, 'category_type', 1);
  61. $category_id = getProp($data, 'category_id');
  62. $category_name = getProp($data, 'category_name');
  63. $pid = getProp($data, 'pid');
  64. $query = DB::table('mp_timbre_categories')->where('is_enable', 1)->select('*');
  65. switch ($category_type) {
  66. case 1:
  67. $query->where('pid', 0);
  68. break;
  69. case 2:
  70. $query->where('pid', $pid);
  71. break;
  72. case 3:
  73. $query->where('pid', $pid);
  74. break;
  75. default:
  76. break;
  77. }
  78. if ($category_id) {
  79. $query->where('id', $category_id);
  80. }
  81. if ($category_name) {
  82. $query->where('category_name', 'like', "%{$category_name}%");
  83. }
  84. return $query->orderBy('id')->paginate();
  85. }
  86. public function getTimbreList($data) {
  87. $timbre_name = getProp($data, 'voice_name');
  88. $language = getProp($data, 'language');
  89. $status = getProp($data, 'status');
  90. $dialect = getProp($data, 'dialect');
  91. $query = DB::table('mp_timbres')->where('is_enabled', 1)->select('*');
  92. if ($timbre_name) {
  93. $query->where('timbre_name', 'like', "%{$timbre_name}%");
  94. }
  95. if ($language) {
  96. $query->where('language', 'like', "%{$language}%");
  97. }
  98. if ($dialect) {
  99. $query->where('dialect', $dialect);
  100. }
  101. $result = $query->orderBy('id')->paginate();
  102. return $result;
  103. }
  104. public function timbreCategories($data) {
  105. $categories = DB::table('mp_timbre_categories')->where('is_enable', 1)->select('id as category_id', 'category_name', 'pid')->get()->map(function ($value) {
  106. return (array)$value;
  107. })->toArray();
  108. $result = buildCategoryTree($categories, 0);
  109. return $result;
  110. }
  111. public function editTimbre($data) {
  112. $timbre_id = getProp($data, 'voice_id');
  113. $timbre = DB::table('mp_timbres')->where('id', $timbre_id)->first();
  114. if (!$timbre) {
  115. return Utils::throwError('20003:该音色不存在');
  116. }
  117. $update_data = [
  118. 'updated_at' => date('Y-m-d H:i:s'),
  119. ];
  120. if (getProp($data, 'first_category_id')) {
  121. $update_data['first_category_id'] = getProp($data, 'first_category_id');
  122. $update_data['first_category_name'] = DB::table('mp_timbre_categories')->where('id', getProp($data, 'first_category_id'))->value('category_name');
  123. }
  124. if (getProp($data, 'second_category_id')) {
  125. $update_data['second_category_id'] = getProp($data, 'second_category_id');
  126. $update_data['second_category_name'] = DB::table('mp_timbre_categories')->where('id', getProp($data, 'second_category_id'))->value('category_name');
  127. }
  128. if (getProp($data, 'third_category_id')) {
  129. $update_data['third_category_id'] = getProp($data, 'third_category_id');
  130. $update_data['third_category_name'] = DB::table('mp_timbre_categories')->where('id', getProp($data, 'third_category_id'))->value('category_name');
  131. }
  132. if (getProp($data, 'label')) $update_data['label'] = getProp($data, 'label');
  133. return DB::table('mp_timbres')->where('id', $timbre_id)->update($update_data);
  134. }
  135. public function getAllBooks($data) {
  136. $bid = getProp($data, 'bid');
  137. $book_name = getProp($data, 'book_name');
  138. $query = DB::table('book_configs')->whereIn('is_on_shelf', [1,2])->select('bid', 'book_name');
  139. if ($bid) {
  140. $query->where('bid', $bid);
  141. }
  142. if ($book_name) {
  143. $query->where('book_name', 'like', "%{$book_name}%");
  144. }
  145. return $query->orderBy('bid', 'desc')->get()->map(function($value) {
  146. return (array)$value;
  147. })->toArray();
  148. }
  149. public function timbreGroupList($data) {
  150. $group_name = getProp($data, 'group_name');
  151. $label = getProp($data, 'label');
  152. $query = DB::table('mp_timbre_groups')->select('*');
  153. if ($group_name) {
  154. $query->where('group_name', 'like', "%{$group_name}%");
  155. }
  156. if ($label) {
  157. $query->where('label', 'like', $label);
  158. }
  159. return $query->orderBy('id')->paginate();
  160. }
  161. public function addTimbreGroup($data) {
  162. $group_name = getProp($data, 'group_name');
  163. $male_lead_voice_name = getProp($data, 'male_lead_voice_name');
  164. $male_lead_voice_type = getProp($data, 'male_lead_voice_type');
  165. $female_lead_voice_name = getProp($data, 'female_lead_voice_name');
  166. $female_lead_voice_type = getProp($data, 'female_lead_voice_type');
  167. $narration_voice_name = getProp($data, 'narration_voice_name');
  168. $narration_voice_type = getProp($data, 'narration_voice_type');
  169. if (!$group_name || !$male_lead_voice_type || !$female_lead_voice_type || !$narration_voice_type) Utils::throwError('20003:参数错误');
  170. $label = getProp($data, 'label');
  171. $other_roles = getProp($data, 'other_roles');
  172. if (DB::table('mp_timbre_groups')->where('group_name', $group_name)->value('id')) Utils::throwError('20003:该音色组已存在');
  173. return DB::table('mp_timbre_groups')->insert([
  174. 'group_name' => $group_name,
  175. 'male_lead_voice_name' => $male_lead_voice_name,
  176. 'male_lead_voice_type' => $male_lead_voice_type,
  177. 'female_lead_voice_name' => $female_lead_voice_name,
  178. 'female_lead_voice_type' => $female_lead_voice_type,
  179. 'narration_voice_name' => $narration_voice_name,
  180. 'narration_voice_type' => $narration_voice_type,
  181. 'label' => $label,
  182. 'other_roles' => $other_roles,
  183. 'created_at' => date('Y-m-d H:i:s'),
  184. 'updated_at' => date('Y-m-d H:i:s'),
  185. ]);
  186. }
  187. public function editTimbreGroup($data) {
  188. $group_id = getProp($data, 'group_id');
  189. $group_name = getProp($data, 'group_name');
  190. $male_lead_voice_name = getProp($data, 'male_lead_voice_name');
  191. $male_lead_voice_type = getProp($data, 'male_lead_voice_type');
  192. $female_lead_voice_name = getProp($data, 'female_lead_voice_name');
  193. $female_lead_voice_type = getProp($data, 'female_lead_voice_type');
  194. $narration_voice_name = getProp($data, 'narration_voice_name');
  195. $narration_voice_type = getProp($data, 'narration_voice_type');
  196. if (!$group_id || !$group_name || !$male_lead_voice_type || !$female_lead_voice_type || !$narration_voice_type) Utils::throwError('20003:参数错误');
  197. $label = getProp($data, 'label');
  198. $other_roles = getProp($data, 'other_roles');
  199. $tmp_group_id = DB::table('mp_timbre_groups')->where('group_name', $group_name)->value('id');
  200. if ($tmp_group_id && $tmp_group_id != $group_id) Utils::throwError('20003:该音色组已存在');
  201. return DB::table('mp_timbre_groups')->where('id', $group_id)->update([
  202. 'group_name' => $group_name,
  203. 'male_lead_voice_name' => $male_lead_voice_name,
  204. 'male_lead_voice_type' => $male_lead_voice_type,
  205. 'female_lead_voice_name' => $female_lead_voice_name,
  206. 'female_lead_voice_type' => $female_lead_voice_type,
  207. 'narration_voice_name' => $narration_voice_name,
  208. 'narration_voice_type' => $narration_voice_type,
  209. 'label' => $label,
  210. 'other_roles' => $other_roles,
  211. 'updated_at' => date('Y-m-d H:i:s'),
  212. ]);
  213. }
  214. public function emotionGroupList($data) {
  215. $id = getProp($data, 'group_id');
  216. $group_name = getProp($data, 'group_name');
  217. $voice_type = getProp($data, 'voice_type');
  218. $query = DB::table('mp_emotion_groups')->where('is_enabled', 1)->select('*');
  219. if ($group_name) {
  220. $query->where('group_name', 'like', "%{$group_name}%");
  221. }
  222. if ($id) {
  223. $query->where('id', $id);
  224. }
  225. if ($voice_type) {
  226. $query->where('voice_type', $voice_type);
  227. }
  228. return $query->orderBy('id')->paginate();
  229. }
  230. public function addEmotionGroup($data) {
  231. $group_name = getProp($data, 'group_name');
  232. if (DB::table('mp_emotion_groups')->where('group_name', $group_name)->value('id')) Utils::throwError('20003:该组名已存在');
  233. // 获取所有情感
  234. $emotion_list = DB::table('mp_emotion_list')->where('is_enabled', 1)->pluck('emotion_name', 'emotion_code')->toArray();
  235. $emotion_list = array_flip($emotion_list);
  236. // 获取音色支持情感
  237. $timbre_emotion = DB::table('mp_timbres')->where('timbre_type', getProp($data, 'voice_type'))->value('emotion');
  238. $timbre_emotion = explode(',', $timbre_emotion);
  239. $emotion = getProp($data, 'emotion');
  240. if (!in_array($emotion, $timbre_emotion)) $emotion = '中性';
  241. $emotion_type = isset($emotion_list[$emotion]) ? $emotion_list[$emotion] : 'neutral';
  242. // 给一个默认文案
  243. $text = '试听这段由专业团队打造的声音杰作。从角色塑造到环境音效,每个元素都经过反复推敲,只为给你带来最完美的听觉体验。';
  244. $list = [
  245. 'group_name' => $group_name,
  246. // 'text' => trim(getProp($data, 'text')),
  247. 'text' => $text,
  248. 'emotion' => $emotion,
  249. 'emotion_type' => $emotion_type,
  250. 'voice_type' => getProp($data, 'voice_type'),
  251. 'voice_name' => getProp($data, 'voice_name'),
  252. 'speed_ratio' => getProp($data, 'speed_ratio', 0),
  253. 'loudness_ratio'=> getProp($data, 'loudness_ratio', 0),
  254. 'emotion_scale' => getProp($data, 'emotion_scale', 4),
  255. 'pitch' => getProp($data, 'pitch', 0),
  256. 'generate_status' => '制作中',
  257. 'error_msg' => '',
  258. 'created_at' => date('Y-m-d H:i:s'),
  259. 'updated_at' => date('Y-m-d H:i:s')
  260. ];
  261. $id = DB::table('mp_emotion_groups')->insertGetId($list);
  262. $boolen = $id ? true : false;
  263. if ($boolen) {
  264. $boolen = false;
  265. $client = new Client(['timeout' => 300, 'verify' => false]);
  266. // 根据ID通过API通知合成音频
  267. // $result = $client->get("http://47.240.171.155:5000/api/emotionGroupTask?taskId={$id}");
  268. $result = $client->get("http://122.9.129.83:5000/api/emotionGroupTask?taskId={$id}");
  269. $response = $result->getBody()->getContents();
  270. $response_arr = json_decode($response, true);
  271. if (!isset($response_arr['code']) || (int)$response_arr['code'] !== 0) {
  272. $error_msg = isset($response_arr['msg']) ? $response_arr['msg'] : '未知错误';
  273. Log::info('通知火山生成段落音频失败: '.$error_msg);
  274. Utils::throwError('20003:通知火山生成段落音频失败');
  275. }
  276. $boolen = true;
  277. }
  278. return $boolen;
  279. }
  280. public function editEmotionGroup($data) {
  281. $group_id = getProp($data, 'group_id');
  282. $group_name = getProp($data, 'group_name');
  283. $tmp_group_id = DB::table('mp_emotion_groups')->where('group_name', $group_name)->value('id');
  284. if ($tmp_group_id && $tmp_group_id != $group_id) Utils::throwError('20003:该音色组已存在');
  285. // 获取所有情感
  286. $emotion_list = DB::table('mp_emotion_list')->where('is_enabled', 1)->pluck('emotion_name', 'emotion_code')->toArray();
  287. $emotion_list = array_flip($emotion_list);
  288. // 获取音色支持情感
  289. $timbre_emotion = DB::table('mp_timbres')->where('timbre_type', getProp($data, 'voice_type'))->value('emotion');
  290. $timbre_emotion = explode(',', $timbre_emotion);
  291. $emotion = getProp($data, 'emotion');
  292. if (!in_array($emotion, $timbre_emotion)) $emotion = '中性';
  293. $emotion_type = isset($emotion_list[$emotion]) ? $emotion_list[$emotion] : 'neutral';
  294. $list = [
  295. 'group_name' => $group_name,
  296. // 'text' => trim(getProp($data, 'text')),
  297. 'emotion' => $emotion,
  298. 'emotion_type' => $emotion_type,
  299. 'voice_type' => getProp($data, 'voice_type'),
  300. 'voice_name' => getProp($data, 'voice_name'),
  301. 'speed_ratio' => getProp($data, 'speed_ratio', 0),
  302. 'loudness_ratio'=> getProp($data, 'loudness_ratio', 0),
  303. 'emotion_scale' => getProp($data, 'emotion_scale', 4),
  304. 'pitch' => getProp($data, 'pitch', 0),
  305. 'generate_status' => '制作中',
  306. 'error_msg' => '',
  307. 'updated_at' => date('Y-m-d H:i:s')
  308. ];
  309. $boolen = DB::table('mp_emotion_groups')->where('id', $group_id)->update($list);
  310. if ($boolen) {
  311. $boolen = false;
  312. $client = new Client(['timeout' => 300, 'verify' => false]);
  313. // 根据ID通过API通知合成音频
  314. // $result = $client->get("http://47.240.171.155:5000/api/emotionGroupTask?taskId={$group_id}");
  315. $result = $client->get("http://122.9.129.83:5000/api/emotionGroupTask?taskId={$group_id}");
  316. $response = $result->getBody()->getContents();
  317. $response_arr = json_decode($response, true);
  318. if (!isset($response_arr['code']) || (int)$response_arr['code'] !== 0) {
  319. $error_msg = isset($response_arr['msg']) ? $response_arr['msg'] : '未知错误';
  320. Log::info('通知火山生成段落音频失败: '.$error_msg);
  321. Utils::throwError('20003:通知火山生成段落音频失败');
  322. }
  323. $boolen = true;
  324. }
  325. return $boolen;
  326. }
  327. public function delEmotionGroup($data) {
  328. $group_id = getProp($data, 'group_id');
  329. return DB::table('mp_emotion_groups')->where('id', $group_id)->update([
  330. 'is_enabled' => 0,
  331. 'updated_at' => date('Y-m-d H:i:s')
  332. ]);
  333. }
  334. }