讯飞语音转写 API 文档
文档地址:https://www.xfyun.cn/doc/asr/ifasr_new/API.html
看到没有 js 版本的 demo(音频流模式),所以就搞了一个分享出来
在 React Native 运行环境下测试有效。
1、生成 signa
import axios from 'axios';
import { Buffer } from 'buffer'; // 导入 Buffer
import * as CryptoJS from 'crypto-js';
const APP_ID = ''; // 替换为您的 appId
const SECRET_KEY = ''; // 替换为您的 secretKey
// 生成 signa
const generateSigna = (ts: number) => {
const baseString = `${APP_ID}${ts}`;
const md5Hash = CryptoJS.MD5(baseString).toString();
const hmac = CryptoJS.HmacSHA1(md5Hash, SECRET_KEY);
return CryptoJS.enc.Base64.stringify(hmac);
};
2、上传音频文件
// 上传音频文件
export const uploadAudio = async (file: { path: string, base64: string, name: any; size: any; duration: number; }) => {
const ts = Math.floor(Date.now() / 1000); // 当前时间戳
const signa = generateSigna(ts);
// 读取音频文件为二进制数据
// const fileData = await RNFS.readFile(filePath, 'base64'); // 读取文件为 base64 编码
const fileData = file.base64; // 假设您有音频文件的 base64 编码数据
const buffer = Buffer.from(fileData, 'base64'); // 将 base64 转换为 Buffer
console.log("🚀 ~ uploadAudio ~ buffer:", buffer)
// 拼接请求参数到 URL
const url = `https://raasr.xfyun.cn/v2/api/upload
?fileName=${encodeURIComponent(file.name)}
&fileSize=${buffer.length}
&duration=${Math.floor(10)}
&standardWav=${1}
&appId=${APP_ID}
&ts=${ts}
&signa=${encodeURIComponent(signa)
}`;
try {
const response = await axios.post(
url,
buffer,
{
headers: {
'Content-Type': 'application/octet-stream',
'Content-Length': buffer.length,
},
});
return response.data; // 返回响应数据
} catch (error) {
console.error('上传音频文件失败:', error);
}
};
上传音频文件 使用示例
// 使用示例
try {
const result = await uploadAudio(file);
console.log('上传成功,订单 ID:', result.content.orderId);
} catch (error) {
console.error('上传失败:', error);
}
3、查询转写结果
// 查询转写结果
export const getResult = async (orderId: string, resultType = 'transfer') => {
const ts = `${Math.floor(Date.now() / 1000)}`; // 当前时间戳
const signa = generateSigna(Number(ts));
// 构建请求 URL
const url = `https://raasr.xfyun.cn/v2/api/getResult
?orderId=${encodeURIComponent(orderId)}
&resultType=${encodeURIComponent(resultType)}
&appId=${encodeURIComponent(APP_ID)}
&ts=${ts}
&signa=${encodeURIComponent(signa)
}`;
try {
const response: any = await axios.get(url); // 使用 GET 请求
// 检查响应状态码
if (response.data.code !== '000000') {
console.log(response.data.descInfo);
return;
}
// 处理响应数据
// lattice List 做顺滑功能的识别结果
const resultLattice = extractTranscriptionResults(JSON.parse(response.data.content.orderResult))
// lattice2 List 未做顺滑功能的识别结果,当开启顺滑和后语规整后 orderResult 才返回 lattice2 字段(需要开通权限)
const resultLattice2 = extractTranscriptionResults2(JSON.parse(response.data.content.orderResult))
return resultLattice2; // 返回响应数据
} catch (error) {
console.error('查询转写结果失败:', error);
}
};
// 使用示例
const orderId = ''; // 替换为实际的订单 ID
getResult(orderId)
.then(result => {
console.log('查询结果:', result);
})
.catch(error => {
console.error('查询失败:', error);
});
4、处理响应数据
// 做顺滑功能的识别结果
function extractTranscriptionResults(data: { lattice: any[]; }) {
// 检查输入数据的有效性
if (!data || !data.lattice || !data.lattice.length) {
return [];
}
const transcriptions: string[] = [];
// 遍历每个 json_1best
data.lattice.forEach((item: { json_1best: string; }) => {
const result = JSON.parse(item.json_1best).st;
// 检查结果对象的有效性
if (!result || !result.rt || !result.rt.length) {
return;
}
// 提取识别结果
let transcription = '';
result.rt.forEach((rtItem: { ws: any[]; }) => {
rtItem.ws.forEach((word: { cw: any; }) => {
// 获取词语候选识别结果
const candidates = word.cw;
if (candidates && candidates.length) {
// 取第一个候选词作为识别结果
transcription += candidates[0].w;
}
});
});
// 将提取的结果添加到数组中
transcriptions.push(transcription);
});
console.log("🚀 ~ extractTranscriptionResults ~ transcriptions:", transcriptions)
return transcriptions;
}
// 未做顺滑功能的识别结果
function extractTranscriptionResults2(data: { lattice2: { json_1best: { st: any; }; }[]; }) {
// 检查输入数据的有效性
if (!data || !data.lattice2 || !data.lattice2.length) {
return [];
}
const transcriptions: string[] = [];
// 遍历每个 json_1best
data.lattice2.forEach((item: { json_1best: { st: any; }; }) => {
const result = item.json_1best.st;
// 检查结果对象的有效性
if (!result || !result.rt || !result.rt.length) {
return;
}
// 提取识别结果
let transcription = '';
result.rt.forEach((rtItem: { ws: any[]; }) => {
rtItem.ws.forEach((word: { cw: any; }) => {
// 获取词语候选识别结果
const candidates = word.cw;
if (candidates && candidates.length) {
// 取第一个候选词作为识别结果
transcription += candidates[0].w;
}
});
});
// 将提取的结果添加到数组中
transcriptions.push(transcription);
});
return transcriptions;
}