519 lines
14 KiB
PHP
519 lines
14 KiB
PHP
<?php
|
|
|
|
namespace app\api\logic;
|
|
|
|
use app\api\logic\service\TokenLogService;
|
|
use app\common\enum\user\AccountLogEnum;
|
|
use app\common\logic\AccountLogLogic;
|
|
use app\common\model\audio\Audio;
|
|
use app\common\model\audio\AudioInfo;
|
|
use think\Exception;
|
|
use app\common\model\user\UserTokensLog;
|
|
use app\common\service\FileService;
|
|
use app\common\model\user\User;
|
|
|
|
class AudioLogic extends ApiLogic
|
|
{
|
|
|
|
/**
|
|
* 详情
|
|
* @param int $audioId
|
|
* @return bool
|
|
* @author L
|
|
* @data 2024/6/29 10:30
|
|
*/
|
|
public static function detail(int $audioId): bool
|
|
{
|
|
try {
|
|
$audioInfo = AudioInfo::where('user_id', self::$uid)
|
|
->where('id', $audioId)
|
|
->findOrEmpty();
|
|
|
|
if ($audioInfo->isEmpty()) {
|
|
throw new \Exception('任务不存在');
|
|
}
|
|
|
|
$audioInfo->url = FileService::getFileUrl($audioInfo->url);
|
|
$audioInfo->ws_url = $audioInfo->ws_url ?: '';
|
|
$audioInfo->text = $audioInfo->text ?: '';
|
|
self::$returnData = $audioInfo->toArray();
|
|
return true;
|
|
} catch (\Exception $exception) {
|
|
self::setError($exception->getMessage());
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 删除音频转写记录 以及音频文件
|
|
* @param array $data
|
|
* @return bool
|
|
* @author L
|
|
* @data 2024/6/29 16:02
|
|
*/
|
|
public static function delete(array $data): bool
|
|
{
|
|
try {
|
|
|
|
if (is_string($data['id'])) {
|
|
AudioInfo::destroy(['id' => $data['id'], 'user_id' => self::$uid]);
|
|
} else {
|
|
AudioInfo::whereIn('id', $data['id'])->where('user_id', self::$uid)->select()->delete();
|
|
}
|
|
|
|
return true;
|
|
} catch (\Exception $exception) {
|
|
self::setError($exception->getMessage());
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 创建任务
|
|
* @param array $params
|
|
* @return bool
|
|
* @throws \Exception
|
|
* @author L
|
|
* @data 2024/6/29 10:46
|
|
*/
|
|
public static function task(array $params): bool
|
|
{
|
|
$unit = TokenLogService::checkToken(self::$uid, 'meeting');
|
|
|
|
try {
|
|
|
|
$request = [
|
|
'language' => $params['language'],
|
|
'task_type' => $params['task_type'],
|
|
'url' => $params['url'],
|
|
'speaker' => $params['speaker'],
|
|
'translation' => $params['translation'],
|
|
];
|
|
|
|
if ($params['task_type'] == 2) {
|
|
|
|
$request['tips'] = 'start';
|
|
}
|
|
|
|
$response = \app\common\service\ToolsService::Asr()->text($request);
|
|
|
|
if (!isset($response['data']['task_id']) || !isset($response['data']['duration'])) {
|
|
|
|
self::setError('转写失败');
|
|
return false;
|
|
}
|
|
|
|
$audioInfo = AudioInfo::create([
|
|
'task_id' => $response['data']['task_id'],
|
|
'url' => FileService::setFileUrl($params['url']),
|
|
'status' => 0,
|
|
'user_id' => self::$uid,
|
|
'task_type' => $params['task_type'],
|
|
'language' => $params['language'],
|
|
'speaker' => $params['speaker'],
|
|
'translation' => $params['translation'],
|
|
'name' => $params['name']
|
|
]);
|
|
|
|
if ($audioInfo->task_type == 1) { //离线
|
|
|
|
$audioInfo->status = 3;
|
|
|
|
$audioInfo->task_id = $response['data']['task_id'];
|
|
|
|
$audioInfo->save();
|
|
|
|
$unit = TokenLogService::checkToken(self::$uid, 'meeting');
|
|
|
|
//时长
|
|
$duration = $response['data']['duration'] ?? 60;
|
|
|
|
//折算分钟
|
|
$minutes = ((int)($duration / 60)) + ($duration % 60 > 0 ? 1 : 0);
|
|
|
|
$points = ceil($minutes * $unit);
|
|
|
|
//token扣除
|
|
User::userTokensChange(self::$uid, $points);
|
|
|
|
$extra = ['音视频时长' => $minutes, '算力单价' => $unit, '实际消耗算力' => $points];
|
|
|
|
//记录日志
|
|
AccountLogLogic::recordUserTokensLog(true, self::$uid, AccountLogEnum::TOKENS_DEC_MEETING, $points, $audioInfo->task_id, $extra);
|
|
} else { //实时
|
|
|
|
$audioInfo->status = 1; //录音中
|
|
$audioInfo->ws_url = $response['data']['ws_url'];
|
|
$audioInfo->save();
|
|
}
|
|
|
|
self::$returnData = $audioInfo->toArray();
|
|
return true;
|
|
} catch (\think\exception\HttpResponseException $exception) {
|
|
|
|
throw $exception;
|
|
} catch (\Throwable $exception) {
|
|
|
|
self::setError($exception->getMessage());
|
|
return false;
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
* 创建任务
|
|
* @param array $params
|
|
* @return bool
|
|
* @throws \Exception
|
|
* @author L
|
|
* @data 2024/6/29 10:46
|
|
*/
|
|
public static function batch(array $data): bool
|
|
{
|
|
$unit = TokenLogService::checkToken(self::$uid, 'meeting');
|
|
|
|
try {
|
|
|
|
if (count($data) > 10) {
|
|
|
|
self::setError("批量最多支持10个文件");
|
|
return false;
|
|
}
|
|
|
|
foreach ($data as $params) {
|
|
|
|
$request = [
|
|
'language' => $params['language'],
|
|
'task_type' => 1,
|
|
'url' => $params['url'],
|
|
'speaker' => $params['speaker'],
|
|
'translation' => $params['translation'],
|
|
];
|
|
|
|
$audioInfo = AudioInfo::create([
|
|
'url' => FileService::setFileUrl($params['url']),
|
|
'status' => 0,
|
|
'user_id' => self::$uid,
|
|
'task_type' => 1,
|
|
'language' => $params['language'],
|
|
'speaker' => $params['speaker'],
|
|
'translation' => $params['translation'],
|
|
'name' => $params['name']
|
|
]);
|
|
|
|
$response = \app\common\service\ToolsService::Asr()->text($request);
|
|
|
|
if (!isset($response['data']['task_id']) || !isset($response['data']['duration'])) {
|
|
|
|
$audioInfo->status = 5;
|
|
$audioInfo->remark = '转写失败';
|
|
$audioInfo->save();
|
|
continue;
|
|
}
|
|
|
|
$audioInfo->status = 3;
|
|
|
|
$audioInfo->task_id = $response['data']['task_id'];
|
|
|
|
$audioInfo->save();
|
|
|
|
//时长
|
|
$duration = $response['data']['duration'] ?? 60;
|
|
|
|
//折算分钟
|
|
$minutes = ((int)($duration / 60)) + ($duration % 60 > 0 ? 1 : 0);
|
|
|
|
$points = ceil($minutes * $unit);
|
|
|
|
//token扣除
|
|
User::userTokensChange(self::$uid, $points);
|
|
|
|
$extra = ['音视频时长' => $minutes, '算力单价' => $unit, '实际消耗算力' => $points];
|
|
|
|
//记录日志
|
|
AccountLogLogic::recordUserTokensLog(true, self::$uid, AccountLogEnum::TOKENS_DEC_MEETING, $points, $audioInfo->task_id, $extra);
|
|
}
|
|
|
|
self::$returnData = [];
|
|
return true;
|
|
} catch (\think\exception\HttpResponseException $exception) {
|
|
|
|
throw $exception;
|
|
} catch (\Throwable $exception) {
|
|
|
|
self::setError($exception->getMessage());
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 获取任务状态
|
|
* @param array $data
|
|
* @return bool
|
|
* @author L
|
|
* @data 2024/6/29 16:18
|
|
*/
|
|
public static function status(string $taskId): bool
|
|
{
|
|
|
|
$audioInfo = AudioInfo::where('task_id', $taskId)->findOrEmpty();
|
|
|
|
if ($audioInfo->isEmpty()) {
|
|
|
|
self::setError("任务不存在");
|
|
return false;
|
|
}
|
|
|
|
$request = [
|
|
'task_id' => $taskId
|
|
];
|
|
|
|
$response = \app\common\service\ToolsService::Asr()->status($request);
|
|
|
|
if ($response['code'] != 10000) {
|
|
|
|
self::setError("获取任务状态失败");
|
|
return false;
|
|
}
|
|
|
|
self::updateAudioInfo($response['data']);
|
|
self::$returnData = $response['data'];
|
|
return true;
|
|
}
|
|
|
|
|
|
/**
|
|
* 重试
|
|
* @param array $data
|
|
* @return bool
|
|
* @author L
|
|
* @data 2024/6/29 16:18
|
|
*/
|
|
public static function retry(int $audioId): bool
|
|
{
|
|
|
|
$audioInfo = AudioInfo::where('id', $audioId)->findOrEmpty();
|
|
|
|
if ($audioInfo->isEmpty()) {
|
|
|
|
self::setError("任务不存在");
|
|
return false;
|
|
}
|
|
|
|
if (!in_array($audioInfo->status, [0, 5])) { //待处理 转写失败
|
|
|
|
self::setError("当前状态无法重试");
|
|
return false;
|
|
}
|
|
|
|
if ($audioInfo->task_type != 1) {
|
|
|
|
self::setError("当前任务类型无法重试");
|
|
return false;
|
|
}
|
|
|
|
$request = [
|
|
'language' => $audioInfo->language,
|
|
'task_type' => 1,
|
|
'url' => $audioInfo->url,
|
|
'speaker' => $audioInfo->speaker,
|
|
'translation' => $audioInfo->translation,
|
|
];
|
|
|
|
$response = \app\common\service\ToolsService::Asr()->text($request);
|
|
|
|
if (!isset($response['data']['task_id']) || !isset($response['data']['duration'])) {
|
|
|
|
self::setError('转写失败');
|
|
return false;
|
|
}
|
|
|
|
$audioInfo->status = 3;
|
|
$audioInfo->task_id = $response['data']['task_id'];
|
|
$audioInfo->save();
|
|
|
|
self::$returnData = $response['data'];
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* 富文本
|
|
* @param array $data
|
|
* @return bool
|
|
* @author L
|
|
* @data 2024/6/29 16:18
|
|
*/
|
|
public static function text(array $data): bool
|
|
{
|
|
$audioInfo = AudioInfo::where('id', $data['id'])->findOrEmpty();
|
|
|
|
if ($audioInfo->isEmpty()) {
|
|
|
|
self::setError("任务不存在");
|
|
return false;
|
|
}
|
|
|
|
$audioInfo->text = $data['text'];
|
|
$audioInfo->save();
|
|
|
|
self::$returnData = $audioInfo->toArray();
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* 暂停
|
|
* @param array $data
|
|
* @return bool
|
|
* @author L
|
|
* @data 2024/6/29 16:18
|
|
*/
|
|
public static function pause(int $audioId): bool
|
|
{
|
|
$audioInfo = AudioInfo::where('id', $audioId)->findOrEmpty();
|
|
|
|
if ($audioInfo->isEmpty()) {
|
|
|
|
self::setError("任务不存在");
|
|
return false;
|
|
}
|
|
|
|
$audioInfo->status = 2;
|
|
$audioInfo->save();
|
|
|
|
self::$returnData = $audioInfo->toArray();
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* 继续录音
|
|
* @param array $data
|
|
* @return bool
|
|
* @author L
|
|
* @data 2024/6/29 16:18
|
|
*/
|
|
public static function continue(int $audioId): bool
|
|
{
|
|
$audioInfo = AudioInfo::where('id', $audioId)->findOrEmpty();
|
|
|
|
if ($audioInfo->isEmpty()) {
|
|
|
|
self::setError("任务不存在");
|
|
return false;
|
|
}
|
|
|
|
$audioInfo->status = 1;
|
|
$audioInfo->save();
|
|
|
|
self::$returnData = $audioInfo->toArray();
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* 停止录音
|
|
* @param array $data
|
|
* @return bool
|
|
* @author L
|
|
* @data 2024/6/29 16:18
|
|
*/
|
|
public static function stop(int $audioId, string $url): bool
|
|
{
|
|
$audioInfo = AudioInfo::where('id', $audioId)->findOrEmpty();
|
|
|
|
if ($audioInfo->isEmpty()) {
|
|
|
|
self::setError("任务不存在");
|
|
return false;
|
|
}
|
|
|
|
$audioInfo->url = $url;
|
|
|
|
$request = [
|
|
'language' => $audioInfo->language,
|
|
'task_type' => $audioInfo->task_type,
|
|
'url' => $audioInfo->url,
|
|
'speaker' => $audioInfo->speaker,
|
|
'translation' => $audioInfo->translation,
|
|
'tips' => 'stop'
|
|
];
|
|
|
|
$response = \app\common\service\ToolsService::Asr()->text($request);
|
|
|
|
if (!isset($response['data']['task_id']) || !isset($response['data']['duration'])) {
|
|
|
|
$audioInfo->status = 5;
|
|
$audioInfo->remark = '转写失败';
|
|
$audioInfo->save();
|
|
self::setError('转写失败');
|
|
return false;
|
|
}
|
|
|
|
$audioInfo->status = 3; //转写中
|
|
$audioInfo->task_id = $response['data']['task_id'];
|
|
$audioInfo->save();
|
|
|
|
$unit = TokenLogService::checkToken(self::$uid, 'meeting');
|
|
|
|
//时长
|
|
$duration = $response['data']['duration'] ?? 60;
|
|
|
|
//折算分钟
|
|
$minutes = ((int)($duration / 60)) + ($duration % 60 > 0 ? 1 : 0);
|
|
|
|
$points = ceil($minutes * $unit);
|
|
|
|
$extra = ['音视频时长' => $minutes, '算力单价' => $unit, '实际消耗算力' => $points];
|
|
|
|
//记录日志
|
|
AccountLogLogic::recordUserTokensLog(true, self::$uid, AccountLogEnum::TOKENS_DEC_MEETING, $points, $audioInfo->task_id, $extra);
|
|
|
|
self::$returnData = $audioInfo->toArray();
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* 更新音频信息
|
|
* @param array $data
|
|
* @return bool
|
|
* @author L
|
|
* @data 2024/6/29 16:18
|
|
*/
|
|
public static function updateAudioInfo(array $data): bool
|
|
{
|
|
|
|
$audioInfo = AudioInfo::where('task_id', $data['TaskId'])->findOrEmpty();
|
|
|
|
if ($audioInfo->isEmpty()) {
|
|
|
|
return false;
|
|
}
|
|
|
|
$audioInfo->response = $data;
|
|
$audioInfo->remark = $data['TaskStatus'];
|
|
|
|
if ($data['TaskStatus'] == "COMPLETED") {
|
|
|
|
$audioInfo->status = 4;
|
|
}
|
|
|
|
if ($data['TaskStatus'] == "FAILED") {
|
|
|
|
$audioInfo->status = 5;
|
|
}
|
|
|
|
$audioInfo->save();
|
|
|
|
if ($audioInfo->status === 5) {
|
|
|
|
//查询是否已返还
|
|
if (UserTokensLog::where('user_id', $audioInfo->user_id)->where('change_type', AccountLogEnum::TOKENS_DEC_MEETING)->where('action', 1)->where('task_id', $audioInfo->task_id)->count() == 0) {
|
|
|
|
$points = UserTokensLog::where('user_id', $audioInfo->user_id)->where('change_type', AccountLogEnum::TOKENS_DEC_MEETING)->where('task_id', $audioInfo->task_id)->value('change_amount') ?? 0;
|
|
|
|
AccountLogLogic::recordUserTokensLog(false, $audioInfo->user_id, AccountLogEnum::TOKENS_DEC_MEETING, $points, $audioInfo->task_id);
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
}
|