TimbreService.php 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426
  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. $page = getProp($data, 'page', 1);
  64. $per_page = getProp($data, 'pageSize', 15);
  65. $pid = getProp($data, 'pid');
  66. $query = DB::table('mp_timbre_categories')->where('is_enable', 1)->select('*');
  67. switch ($category_type) {
  68. case 1:
  69. $query->where('pid', 0);
  70. break;
  71. case 2:
  72. $query->where('pid', $pid);
  73. break;
  74. case 3:
  75. $query->where('pid', $pid);
  76. break;
  77. default:
  78. break;
  79. }
  80. if ($category_id) {
  81. $query->where('id', $category_id);
  82. }
  83. if ($category_name) {
  84. $query->where('category_name', 'like', "%{$category_name}%");
  85. }
  86. return $query->orderBy('id')->paginate($per_page);
  87. }
  88. public function getTimbreList($data) {
  89. $timbre_name = getProp($data, 'voice_name');
  90. $language = getProp($data, 'language');
  91. $status = getProp($data, 'status');
  92. $dialect = getProp($data, 'dialect');
  93. $page = getProp($data, 'page', 1);
  94. $per_page = getProp($data, 'pageSize', 15);
  95. $query = DB::table('mp_timbres')->where('is_enabled', 1)->select('*');
  96. if ($timbre_name) {
  97. $query->where('timbre_name', 'like', "%{$timbre_name}%");
  98. }
  99. if ($language) {
  100. $query->where('language', 'like', "%{$language}%");
  101. }
  102. if ($dialect) {
  103. $query->where('dialect', $dialect);
  104. }
  105. $result = $query->orderBy('id')->paginate($per_page);
  106. return $result;
  107. }
  108. public function timbreCategories($data) {
  109. $categories = DB::table('mp_timbre_categories')->where('is_enable', 1)->select('id as category_id', 'category_name', 'pid')->get()->map(function ($value) {
  110. return (array)$value;
  111. })->toArray();
  112. $result = buildCategoryTree($categories, 0);
  113. return $result;
  114. }
  115. public function editTimbre($data) {
  116. $timbre_id = getProp($data, 'voice_id');
  117. $timbre = DB::table('mp_timbres')->where('id', $timbre_id)->first();
  118. if (!$timbre) {
  119. return Utils::throwError('20003:该音色不存在');
  120. }
  121. $update_data = [
  122. 'updated_at' => date('Y-m-d H:i:s'),
  123. ];
  124. if (getProp($data, 'first_category_id')) {
  125. $update_data['first_category_id'] = getProp($data, 'first_category_id');
  126. $update_data['first_category_name'] = DB::table('mp_timbre_categories')->where('id', getProp($data, 'first_category_id'))->value('category_name');
  127. }
  128. if (getProp($data, 'second_category_id')) {
  129. $update_data['second_category_id'] = getProp($data, 'second_category_id');
  130. $update_data['second_category_name'] = DB::table('mp_timbre_categories')->where('id', getProp($data, 'second_category_id'))->value('category_name');
  131. }
  132. if (getProp($data, 'third_category_id')) {
  133. $update_data['third_category_id'] = getProp($data, 'third_category_id');
  134. $update_data['third_category_name'] = DB::table('mp_timbre_categories')->where('id', getProp($data, 'third_category_id'))->value('category_name');
  135. }
  136. if (getProp($data, 'label')) $update_data['label'] = getProp($data, 'label');
  137. return DB::table('mp_timbres')->where('id', $timbre_id)->update($update_data);
  138. }
  139. public function getAllBooks($data) {
  140. $bid = getProp($data, 'bid');
  141. $book_name = getProp($data, 'book_name');
  142. $query = DB::table('book_configs')->whereIn('is_on_shelf', [1,2])->select('bid', 'book_name');
  143. if ($bid) {
  144. $query->where('bid', $bid);
  145. }
  146. if ($book_name) {
  147. $query->where('book_name', 'like', "%{$book_name}%");
  148. }
  149. return $query->orderBy('bid', 'desc')->get()->map(function($value) {
  150. return (array)$value;
  151. })->toArray();
  152. }
  153. public function timbreGroupList($data) {
  154. $group_name = getProp($data, 'group_name');
  155. $label = getProp($data, 'label');
  156. $page = getProp($data, 'page', 1);
  157. $per_page = getProp($data, 'pageSize', 15);
  158. $query = DB::table('mp_timbre_groups')->select('*');
  159. if ($group_name) {
  160. $query->where('group_name', 'like', "%{$group_name}%");
  161. }
  162. if ($label) {
  163. $query->where('label', 'like', $label);
  164. }
  165. return $query->orderBy('id')->paginate($per_page);
  166. }
  167. public function addTimbreGroup($data) {
  168. $group_name = getProp($data, 'group_name');
  169. $male_lead_voice_name = getProp($data, 'male_lead_voice_name');
  170. $male_lead_voice_type = getProp($data, 'male_lead_voice_type');
  171. $female_lead_voice_name = getProp($data, 'female_lead_voice_name');
  172. $female_lead_voice_type = getProp($data, 'female_lead_voice_type');
  173. $narration_voice_name = getProp($data, 'narration_voice_name');
  174. $narration_voice_type = getProp($data, 'narration_voice_type');
  175. if (!$group_name || !$male_lead_voice_type || !$female_lead_voice_type || !$narration_voice_type) Utils::throwError('20003:参数错误');
  176. $label = getProp($data, 'label');
  177. $other_roles = getProp($data, 'other_roles');
  178. if (DB::table('mp_timbre_groups')->where('group_name', $group_name)->value('id')) Utils::throwError('20003:该音色组已存在');
  179. return DB::table('mp_timbre_groups')->insert([
  180. 'group_name' => $group_name,
  181. 'male_lead_voice_name' => $male_lead_voice_name,
  182. 'male_lead_voice_type' => $male_lead_voice_type,
  183. 'female_lead_voice_name' => $female_lead_voice_name,
  184. 'female_lead_voice_type' => $female_lead_voice_type,
  185. 'narration_voice_name' => $narration_voice_name,
  186. 'narration_voice_type' => $narration_voice_type,
  187. 'label' => $label,
  188. 'other_roles' => $other_roles,
  189. 'created_at' => date('Y-m-d H:i:s'),
  190. 'updated_at' => date('Y-m-d H:i:s'),
  191. ]);
  192. }
  193. public function editTimbreGroup($data) {
  194. $group_id = getProp($data, 'group_id');
  195. $group_name = getProp($data, 'group_name');
  196. $male_lead_voice_name = getProp($data, 'male_lead_voice_name');
  197. $male_lead_voice_type = getProp($data, 'male_lead_voice_type');
  198. $female_lead_voice_name = getProp($data, 'female_lead_voice_name');
  199. $female_lead_voice_type = getProp($data, 'female_lead_voice_type');
  200. $narration_voice_name = getProp($data, 'narration_voice_name');
  201. $narration_voice_type = getProp($data, 'narration_voice_type');
  202. if (!$group_id || !$group_name || !$male_lead_voice_type || !$female_lead_voice_type || !$narration_voice_type) Utils::throwError('20003:参数错误');
  203. $label = getProp($data, 'label');
  204. $other_roles = getProp($data, 'other_roles');
  205. $tmp_group_id = DB::table('mp_timbre_groups')->where('group_name', $group_name)->value('id');
  206. if ($tmp_group_id && $tmp_group_id != $group_id) Utils::throwError('20003:该音色组已存在');
  207. return DB::table('mp_timbre_groups')->where('id', $group_id)->update([
  208. 'group_name' => $group_name,
  209. 'male_lead_voice_name' => $male_lead_voice_name,
  210. 'male_lead_voice_type' => $male_lead_voice_type,
  211. 'female_lead_voice_name' => $female_lead_voice_name,
  212. 'female_lead_voice_type' => $female_lead_voice_type,
  213. 'narration_voice_name' => $narration_voice_name,
  214. 'narration_voice_type' => $narration_voice_type,
  215. 'label' => $label,
  216. 'other_roles' => $other_roles,
  217. 'updated_at' => date('Y-m-d H:i:s'),
  218. ]);
  219. }
  220. public function emotionGroupList($data) {
  221. $id = getProp($data, 'group_id');
  222. $group_name = getProp($data, 'group_name');
  223. $voice_type = getProp($data, 'voice_type');
  224. $page = getProp($data, 'page', 1);
  225. $per_page = getProp($data, 'pageSize', 15);
  226. $query = DB::table('mp_emotion_groups')->where('is_enabled', 1)->select('*');
  227. if ($group_name) {
  228. $query->where('group_name', 'like', "%{$group_name}%");
  229. }
  230. if ($id) {
  231. $query->where('id', $id);
  232. }
  233. if ($voice_type) {
  234. $query->where('voice_type', $voice_type);
  235. }
  236. return $query->orderBy('id')->paginate($per_page);
  237. }
  238. public function addEmotionGroup($data) {
  239. $group_name = getProp($data, 'group_name');
  240. if (DB::table('mp_emotion_groups')->where('group_name', $group_name)->value('id')) Utils::throwError('20003:该组名已存在');
  241. // 获取所有情感
  242. $emotion_list = DB::table('mp_emotion_list')->where('is_enabled', 1)->pluck('emotion_name', 'emotion_code')->toArray();
  243. $emotion_list = array_flip($emotion_list);
  244. // 获取音色支持情感
  245. $timbre_emotion = DB::table('mp_timbres')->where('timbre_type', getProp($data, 'voice_type'))->value('emotion');
  246. $timbre_emotion = explode(',', $timbre_emotion);
  247. $emotion = getProp($data, 'emotion');
  248. if (!in_array($emotion, $timbre_emotion)) $emotion = '中性';
  249. $emotion_type = isset($emotion_list[$emotion]) ? $emotion_list[$emotion] : 'neutral';
  250. // 给一个默认文案
  251. $text = '试听这段由专业团队打造的声音杰作。从角色塑造到环境音效,每个元素都经过反复推敲,只为给你带来最完美的听觉体验。';
  252. $list = [
  253. 'group_name' => $group_name,
  254. // 'text' => trim(getProp($data, 'text')),
  255. 'text' => $text,
  256. 'emotion' => $emotion,
  257. 'emotion_type' => $emotion_type,
  258. 'voice_type' => getProp($data, 'voice_type'),
  259. 'voice_name' => getProp($data, 'voice_name'),
  260. 'speed_ratio' => getProp($data, 'speed_ratio', 0),
  261. 'loudness_ratio'=> getProp($data, 'loudness_ratio', 0),
  262. 'emotion_scale' => getProp($data, 'emotion_scale', 4),
  263. 'pitch' => getProp($data, 'pitch', 0),
  264. 'generate_status' => '制作中',
  265. 'error_msg' => '',
  266. 'created_at' => date('Y-m-d H:i:s'),
  267. 'updated_at' => date('Y-m-d H:i:s')
  268. ];
  269. $id = DB::table('mp_emotion_groups')->insertGetId($list);
  270. $boolen = $id ? true : false;
  271. if ($boolen) {
  272. $boolen = false;
  273. $client = new Client(['timeout' => 300, 'verify' => false]);
  274. // 根据ID通过API通知合成音频
  275. // $result = $client->get("http://47.240.171.155:5000/api/emotionGroupTask?taskId={$id}");
  276. $result = $client->get("http://122.9.129.83:5000/api/emotionGroupTask?taskId={$id}");
  277. $response = $result->getBody()->getContents();
  278. $response_arr = json_decode($response, true);
  279. if (!isset($response_arr['code']) || (int)$response_arr['code'] !== 0) {
  280. $error_msg = isset($response_arr['msg']) ? $response_arr['msg'] : '未知错误';
  281. Log::info('火山生成音频失败: '.$error_msg);
  282. Utils::throwError('20003:火山生成音频失败');
  283. }
  284. $boolen = true;
  285. }
  286. return $boolen;
  287. }
  288. public function editEmotionGroup($data) {
  289. $group_id = getProp($data, 'group_id');
  290. $group_name = getProp($data, 'group_name');
  291. $tmp_group_id = DB::table('mp_emotion_groups')->where('group_name', $group_name)->value('id');
  292. if ($tmp_group_id && $tmp_group_id != $group_id) Utils::throwError('20003:该音色组已存在');
  293. // 获取所有情感
  294. $emotion_list = DB::table('mp_emotion_list')->where('is_enabled', 1)->pluck('emotion_name', 'emotion_code')->toArray();
  295. $emotion_list = array_flip($emotion_list);
  296. // 获取音色支持情感
  297. $timbre_emotion = DB::table('mp_timbres')->where('timbre_type', getProp($data, 'voice_type'))->value('emotion');
  298. $timbre_emotion = explode(',', $timbre_emotion);
  299. $emotion = getProp($data, 'emotion');
  300. if (!in_array($emotion, $timbre_emotion)) $emotion = '中性';
  301. $emotion_type = isset($emotion_list[$emotion]) ? $emotion_list[$emotion] : 'neutral';
  302. $list = [
  303. 'group_name' => $group_name,
  304. // 'text' => trim(getProp($data, 'text')),
  305. 'emotion' => $emotion,
  306. 'emotion_type' => $emotion_type,
  307. 'voice_type' => getProp($data, 'voice_type'),
  308. 'voice_name' => getProp($data, 'voice_name'),
  309. 'speed_ratio' => getProp($data, 'speed_ratio', 0),
  310. 'loudness_ratio'=> getProp($data, 'loudness_ratio', 0),
  311. 'emotion_scale' => getProp($data, 'emotion_scale', 4),
  312. 'pitch' => getProp($data, 'pitch', 0),
  313. 'generate_status' => '制作中',
  314. 'error_msg' => '',
  315. 'updated_at' => date('Y-m-d H:i:s')
  316. ];
  317. $boolen = DB::table('mp_emotion_groups')->where('id', $group_id)->update($list);
  318. if ($boolen) {
  319. $boolen = false;
  320. $client = new Client(['timeout' => 300, 'verify' => false]);
  321. // 根据ID通过API通知合成音频
  322. // $result = $client->get("http://47.240.171.155:5000/api/emotionGroupTask?taskId={$group_id}");
  323. $result = $client->get("http://122.9.129.83:5000/api/emotionGroupTask?taskId={$group_id}");
  324. $response = $result->getBody()->getContents();
  325. $response_arr = json_decode($response, true);
  326. if (!isset($response_arr['code']) || (int)$response_arr['code'] !== 0) {
  327. $error_msg = isset($response_arr['msg']) ? $response_arr['msg'] : '未知错误';
  328. Log::info('火山生成音频失败: '.$error_msg);
  329. Utils::throwError('20003:火山生成音频失败');
  330. }
  331. $boolen = true;
  332. }
  333. return $boolen;
  334. }
  335. public function delEmotionGroup($data) {
  336. $group_id = getProp($data, 'group_id');
  337. $url = DB::table('mp_emotion_groups')->where('id', $group_id)->value('audio_url');
  338. $boolen = DB::table('mp_emotion_groups')->where('id', $group_id)->update([
  339. 'is_enabled' => 0,
  340. 'updated_at' => date('Y-m-d H:i:s')
  341. ]);
  342. if ($boolen && $url) {
  343. $boolen = false;
  344. $encode_url = urlencode($url);
  345. $client = new Client(['timeout' => 300, 'verify' => false]);
  346. // 根据ID通过API通知合成音频
  347. // $result = $client->get("http://47.240.171.155:5000/api/fileDelete?url={$encode_url}");
  348. $result = $client->get("http://122.9.129.83:5000/api/fileDelete?url={$encode_url}");
  349. $response = $result->getBody()->getContents();
  350. $response_arr = json_decode($response, true);
  351. Log::info('火山删除音频返回: '.$response);
  352. if (!isset($response_arr['status']) || (int)$response_arr['status'] !== 0) {
  353. $error_msg = isset($response_arr['msg']) ? $response_arr['msg'] : '未知错误';
  354. Log::info('火山删除音频失败: '.$error_msg);
  355. Utils::throwError('20003:火山删除音频失败');
  356. }
  357. $boolen = true;
  358. }
  359. return $boolen;
  360. }
  361. }