為了避免在移動端App或者桌面端工具中保存固定AccessKey ID和AccessKey Secret可能引起的泄露風險,您可以通過在App服務端創建Token并下發到移動端使用,或使用STS臨時訪問憑證調用語音服務兩種方式,更加安全地訪問智能語音交互服務。
背景信息
方案 | 適用接口 |
| |
離線語音合成 |
方案一:通過App服務端創建Token并下發到移動端使用
前提條件
已開通智能語音交互服務,并根據產品文檔調試成功,具體操作,請參見開通服務。
適用場景
如果您作為移動App開發者或者桌面端開發者,希望您的用戶調用阿里云智能語音交互產品的語音合成、一句話識別、實時識別等服務時,為避免在移動端App或者桌面端工具中保存固定AccessKey ID和AccessKey Secret可能引起的泄露風險,您可以使用App服務端下發語音Token調用服務。
交互流程
App端向用戶應用服務器請求一個調用智能語音交互接口所依賴的語音Token,此處使用您自有的通信協議即可,比如用戶登錄時自動請求或服務端自動下發,或定時向應用服務器發起請求。
用戶應用服務器向阿里云智能語音服務發起創建語音Token的真正請求,此處請您使用阿里云SDK或智能語音交互SDK來創建Token,創建Token所需的AccessKey ID和AccessKey Secret保存在您的應用服務器上。由于語音Token具有時效性,您可以在有效期范圍內直接返回給App端,無需每次都向智能語音交互服務請求新的Token。
智能語音交互服務返回給應用服務器一個語音Token信息,包括Token字符串及有效期時間,在有效期內,您可以多次復用該Token而無需重新創建,Token的使用不受不同用戶、不同設備的限制。
用戶應用服務器將Token返回給App端,此時App端可以緩存并使用該Token,直到Token失效。當Token失效時,App端需要向應用服務器申請新的Token。假設Token憑證有效期為24小時,App端可以在Token過期前1到2小時主動向應用服務器請求更新Token。
App端使用獲取到的Token構建請求,向阿里云智能語音交互公共云發起調用,比如調用實時語音識別、一句話識別、語音合成等接口(不包括錄音文件識別、錄音文件識別閑時版等離線類接口),更多信息,請參見阿里云智能語音交互相關文檔。
此方案無需過多額外設置或開發,將AccessKey ID和AccessKey Secret保存到移動端改為保存到用戶自己的服務端,并通過服務端創建語音Token再下發給移動端使用,兼容了使用安全性及開發便捷性。
方案二:使用STS臨時訪問憑證調用語音服務
阿里云STS(Security Token Service)是阿里云提供的一種臨時訪問權限管理服務。您可以通過STS服務給其他用戶頒發臨時訪問憑證,該用戶可使用臨時訪問憑證,在規定時間內調用智能語音交互的錄音文件識別服務(含閑時版)。臨時訪問憑證無需透露您的長期密鑰,保障您的賬戶更加安全。
前提條件
已確保當前賬號為阿里云賬號或者被授予AliyunRAMFullAccess權限的RAM用戶。關于為RAM用戶授權的具體步驟,請參見為RAM用戶授權。
適用場景
如果您作為移動App開發者或者桌面端開發者,希望您的用戶調用阿里云智能語音交互產品的錄音文件識別等服務時,避免在移動端App或者桌面端工具中保存固定AccessKey ID和AccessKey Secret可能引起的泄露風險,您可以使用STS授權用戶調用服務。
交互流程
App端向用戶應用服務器請求STS臨時訪問憑證,此處使用用戶自有的通信協議即可,比如用戶登錄時自動請求或服務端自動下發,或定時向應用服務器發起請求。
用戶應用服務器向阿里云STS服務發起STS請求,此處請使用阿里云SDK,根據應用服務器自身保存的固定AK向STS請求生成一個臨時憑證。
STS返回給應用服務器一個臨時訪問憑證,包括臨時訪問密鑰(AccessKey ID和AccessKey Secret)、安全令牌(SecurityToken)、該憑證的過期時間等信息。
用戶應用服務器將臨時憑證返回給App端,此時App端可以緩存并使用該憑證,直到憑證失效。當憑證失效時,App端需要向應用服務器申請新的臨時訪問憑證。假設臨時訪問憑證有效期為1小時,App端可以每30分鐘或者每50分鐘的頻率向應用服務器請求更新臨時訪問憑證。
App端使用獲取到的臨時憑證構建請求,向阿里云智能語音交互公共云發起調用,更多信息,請參見阿里云智能語音交互相關開發文檔。
本文以錄音文件識別為例,為您介紹相關示例代碼。
操作步驟
步驟一:創建RAM用戶
登錄RAM控制臺。
在左側導航欄,選擇身份管理 > 用戶。
單擊創建用戶。
輸入登錄名稱和顯示名稱。
在訪問方式區域下,選擇使用永久AccessKey訪問,然后單擊確定。
單擊復制,保存訪問密鑰(AccessKey ID 和 AccessKey Secret)。
步驟二:為RAM用戶授予請求AssumeRole的權限
在已創建的RAM用戶右側,單擊對應的添加權限。
在添加權限頁面,選擇AliyunSTSAssumeRoleAccess系統策略。
單擊確定。
步驟三:創建用于獲取臨時訪問憑證的角色
在左側導航欄,選擇身份管理 > 角色。
單擊創建角色,可信實體類型選擇阿里云賬號,單擊下一步。
填寫角色名稱(此處以stsrole為例),選擇當前云賬號。
單擊完成。完成角色創建后,單擊關閉。
在RAM角色管理頁面,搜索框輸入角色名稱stsrole。
單擊復制,保存角色的ARN。
步驟四:為角色授予調用錄音文件識別接口的權限
創建上傳文件的自定義權限策略。
在左側導航欄,選擇權限管理 > 權限策略。
單擊創建權限策略。
在創建權限策略頁面,單擊腳本編輯。
如果您需要角色具備調用錄音文件識別、錄音文件識別閑時版服務,請參考以下配置示例。
重要以下示例僅供參考。您需要根據實際需求配置更細粒度的授權策略,防止出現權限過大的風險。關于更細粒度的授權策略配置詳情,請參見通過RAM或STS服務向其他用戶授權。
{ "Version": "1", "Statement": [ { "Action": "nls:SubmitTask", "Resource": "*", "Effect": "Allow" }, { "Action": "nls:GetTaskResult", "Resource": "*", "Effect": "Allow" } ] }
策略配置完成后,單擊繼續編輯基本信息。
在基本信息區域,填寫策略名稱(此處以nls-stsuser-policy為例),然后單擊確定。
為上面創建的RAM角色stsrole授予自定義權限策略。
在左側導航欄,選擇身份管理 > 角色。
在角色頁面,找到目標RAM角色stsrole。
單擊RAM角色stsrole右側的添加權限。
在添加權限頁面下的自定義策略頁簽,選擇已創建的自定義權限策略nls-stsuser-policy。
單擊確定。
步驟五:服務端獲取STS臨時訪問憑證
需要注意,此步驟并不是在客戶端側(移動端App或桌面端)調用的,您可以在自己的應用服務器側,通過您持有的固定AccessKey ID和AccessKey Secret(即步驟一創建RAM用戶時保存的賬戶信息)創建STS臨時訪問憑證,然后將該憑證通過您已有的交互鏈路返回給客戶端側。客戶端側獲取到臨時訪問憑證后,再調用步驟六中的錄音文件識別服務。
方式一:使用阿里云SDK(推薦)
您可以使用多語言STS SDK獲取臨時訪問憑證。
以下Java代碼用于獲取臨時訪問憑證。
引入POM依賴:
<dependency> <groupId>com.aliyun</groupId> <artifactId>aliyun-java-sdk-core</artifactId> <version>4.5.6</version> </dependency> <dependency> <groupId>com.aliyun</groupId> <artifactId>aliyun-java-sdk-sts</artifactId> <version>3.0.0</version> </dependency>
完整示例代碼如下:
import com.aliyuncs.CommonRequest; import com.aliyuncs.CommonResponse; import com.aliyuncs.DefaultAcsClient; import com.aliyuncs.IAcsClient; import com.aliyuncs.auth.sts.AssumeRoleRequest; import com.aliyuncs.auth.sts.AssumeRoleResponse; import com.aliyuncs.exceptions.ClientException; import com.aliyuncs.http.MethodType; import com.aliyuncs.http.ProtocolType; import com.aliyuncs.profile.DefaultProfile; import com.aliyuncs.profile.IClientProfile; public class CreateStsCredentialsDemo { public static void main(String args[]) throws ClientException { //同region STS的OpenAPI地址 String endpoint = "sts.aliyuncs.com"; // 填寫步驟一生成的訪問密鑰AccessKey ID和AccessKey Secret。 String accessKeyId = "******"; String accessKeySecret = "******"; // 填寫步驟三獲取的角色ARN, 一般是: acs:ram::********:role/*** String roleArn = "******"; // 自定義角色會話名稱,用來區分不同的令牌,例如可填寫為nls-role-session-99。 String roleSession = "nls-role-session-99"; // 添加endpoint(直接使用STS endpoint,前兩個參數留空,無需添加region ID) DefaultProfile.addEndpoint("", "Sts", endpoint); // 構造default profile(參數留空,無需添加region ID) IClientProfile profile = DefaultProfile.getProfile("", accessKeyId, accessKeySecret); // 用profile構造client DefaultAcsClient client = new DefaultAcsClient(profile); final AssumeRoleRequest request = new AssumeRoleRequest(); request.setRoleArn(roleArn); request.setRoleSessionName(roleSession); final AssumeRoleResponse response = client.getAcsResponse(request); String stsAccessKeyId = response.getCredentials().getAccessKeyId(); String stsAccessKeySecret = response.getCredentials().getAccessKeySecret(); String stsToken = response.getCredentials().getSecurityToken(); System.out.println("Expiration: " + response.getCredentials().getExpiration()); System.out.println("Access Key Id: " + stsAccessKeyId); System.out.println("Access Key Secret: " + stsAccessKeySecret); System.out.println("Security Token: " + stsToken); System.out.println("RequestId: " + response.getRequestId()); } }
方式二:使用REST API
您可以通過調用STS服務接口AssumeRole獲取臨時訪問憑證。
步驟六:客戶端使用臨時訪問憑證調用錄音文件識別服務(或錄音文件識別閑時版)
如果您使用的是錄音文件識別閑時版服務,本文流程及以下示例代碼都可復用。
為了調用錄音文件識別閑時版服務,下方的示例代碼的產品信息需要從:
PRODUCT = "nls-filetrans"
DOMAIN = "filetrans.cn-shanghai.aliyuncs.com"
API_VERSION = "2018-08-17"
改為:
PRODUCT = "SpeechFileTranscriberLite"
DOMAIN = "speechfiletranscriberlite.cn-shanghai.aliyuncs.com"
API_VERSION = "2021-12-21"
Java代碼演示通過STS臨時訪問憑證調用錄音文件識別服務
引入POM依賴:
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.83</version>
</dependency>
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>aliyun-java-sdk-core</artifactId>
<version>4.5.6</version>
</dependency>
以下是Java代碼演示通過STS臨時訪問憑證調用錄音文件轉寫服務的完整示例:
import com.alibaba.fastjson.JSONObject;
import com.aliyuncs.CommonRequest;
import com.aliyuncs.CommonResponse;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.http.MethodType;
import com.aliyuncs.profile.DefaultProfile;
public class FileTransByStsJavaDemo {
// 地域ID,常量,固定值。
public static final String REGIONID = "cn-shanghai";
public static final String ENDPOINTNAME = "cn-shanghai";
public static final String PRODUCT = "nls-filetrans";
public static final String DOMAIN = "filetrans.cn-shanghai.aliyuncs.com";
public static final String API_VERSION = "2018-08-17";
public static final String POST_REQUEST_ACTION = "SubmitTask";
public static final String GET_REQUEST_ACTION = "GetTaskResult";
// 請求參數
public static final String KEY_APP_KEY = "appkey";
public static final String KEY_FILE_LINK = "file_link";
public static final String KEY_VERSION = "version";
public static final String KEY_ENABLE_WORDS = "enable_words";
// 響應參數
public static final String KEY_TASK = "Task";
public static final String KEY_TASK_ID = "TaskId";
public static final String KEY_STATUS_TEXT = "StatusText";
public static final String KEY_RESULT = "Result";
// 狀態值
public static final String STATUS_SUCCESS = "SUCCESS";
private static final String STATUS_RUNNING = "RUNNING";
private static final String STATUS_QUEUEING = "QUEUEING";
// 阿里云鑒權client
IAcsClient client;
public FileTransByStsJavaDemo(String stsAccessKeyId, String stsAccessKeySecret, String stsToken) {
// 設置endpoint
try {
DefaultProfile.addEndpoint(ENDPOINTNAME, REGIONID, PRODUCT, DOMAIN);
} catch (ClientException e) {
e.printStackTrace();
}
// 創建DefaultAcsClient實例并初始化
DefaultProfile profile = DefaultProfile.getProfile(REGIONID, stsAccessKeyId, stsAccessKeySecret, stsToken);
this.client = new DefaultAcsClient(profile);
}
public String submitFileTransRequest(String appKey, String fileLink) {
/**
* 1. 創建CommonRequest,設置請求參數。
*/
CommonRequest postRequest = new CommonRequest();
// 設置域名
postRequest.setDomain(DOMAIN);
// 設置API的版本號,格式為YYYY-MM-DD。
postRequest.setVersion(API_VERSION);
// 設置action
postRequest.setAction(POST_REQUEST_ACTION);
// 設置產品名稱
postRequest.setProduct(PRODUCT);
/**
* 2. 設置錄音文件識別請求參數,以JSON字符串的格式設置到請求Body中。
*/
JSONObject taskObject = new JSONObject();
// 設置appkey
taskObject.put(KEY_APP_KEY, appKey);
// 設置音頻文件訪問鏈接
taskObject.put(KEY_FILE_LINK, fileLink);
// 新接入請使用4.0版本,已接入(默認2.0)如需維持現狀,請注釋掉該參數設置。
taskObject.put(KEY_VERSION, "4.0");
// 設置是否輸出詞信息,默認為false,開啟時需要設置version為4.0及以上。
taskObject.put(KEY_ENABLE_WORDS, true);
String task = taskObject.toJSONString();
System.out.println(task);
// 設置以上JSON字符串為Body參數。
postRequest.putBodyParameter(KEY_TASK, task);
// 設置為POST方式的請求。
postRequest.setMethod(MethodType.POST);
/**
* 3. 提交錄音文件識別請求,獲取錄音文件識別請求任務的ID,以供識別結果查詢使用。
*/
String taskId = null;
try {
CommonResponse postResponse = client.getCommonResponse(postRequest);
System.err.println("提交錄音文件識別請求的響應:" + postResponse.getData());
if (postResponse.getHttpStatus() == 200) {
JSONObject result = JSONObject.parseObject(postResponse.getData());
String statusText = result.getString(KEY_STATUS_TEXT);
if (STATUS_SUCCESS.equals(statusText)) {
taskId = result.getString(KEY_TASK_ID);
}
}
} catch (ClientException e) {
e.printStackTrace();
}
return taskId;
}
public String getFileTransResult(String taskId) {
/**
* 1. 創建CommonRequest,設置任務ID。
*/
CommonRequest getRequest = new CommonRequest();
// 設置域名
getRequest.setDomain(DOMAIN);
// 設置API版本
getRequest.setVersion(API_VERSION);
// 設置action
getRequest.setAction(GET_REQUEST_ACTION);
// 設置產品名稱
getRequest.setProduct(PRODUCT);
// 設置任務ID為查詢參數
getRequest.putQueryParameter(KEY_TASK_ID, taskId);
// 設置為GET方式的請求
getRequest.setMethod(MethodType.GET);
/**
* 2. 提交錄音文件識別結果查詢請求
* 以輪詢的方式進行識別結果的查詢,直到服務端返回的狀態描述為“SUCCESS”或錯誤描述,則結束輪詢。
*/
String result = null;
while (true) {
try {
CommonResponse getResponse = client.getCommonResponse(getRequest);
System.err.println("識別查詢結果:" + getResponse.getData());
if (getResponse.getHttpStatus() != 200) {
break;
}
JSONObject rootObj = JSONObject.parseObject(getResponse.getData());
String statusText = rootObj.getString(KEY_STATUS_TEXT);
if (STATUS_RUNNING.equals(statusText) || STATUS_QUEUEING.equals(statusText)) {
// 繼續輪詢,注意設置輪詢時間間隔。
Thread.sleep(10000);
}
else {
// 狀態信息為成功,返回識別結果;狀態信息為異常,返回空。
if (STATUS_SUCCESS.equals(statusText)) {
result = rootObj.getString(KEY_RESULT);
// 狀態信息為成功,但沒有識別結果,則可能是由于文件里全是靜音、噪音等導致識別為空。
if(result == null) {
result = "";
}
}
break;
}
} catch (Exception e) {
e.printStackTrace();
}
}
return result;
}
public static void main(String args[]) throws Exception {
// 相比非STS模式,此時此處填寫之前生成的STS臨時訪問憑證。
// 特別需要注意的是:臨時訪問憑證存在有效期,在有效期內您可以一直使用,但是請在過期前及時再次獲取
final String stsAccessKeyId = "STS.******";
final String stsAccessKeySecret = "******";
final String stsToken = "******";
final String appKey = "******";
String fileLink = "https://gw.alipayobjects.com/os/bmw-prod/0574ee2e-f494-45a5-820f-63aee583045a.wav";
FileTransByStsJavaDemo demo = new FileTransByStsJavaDemo(stsAccessKeyId, stsAccessKeySecret, stsToken);
// 第一步:提交錄音文件識別請求,獲取任務ID用于后續的識別結果輪詢。
String taskId = demo.submitFileTransRequest(appKey, fileLink);
if (taskId != null) {
System.out.println("錄音文件識別請求成功,task_id: " + taskId);
}
else {
System.out.println("錄音文件識別請求失敗!");
return;
}
// 第二步:根據任務ID輪詢識別結果。
String result = demo.getFileTransResult(taskId);
if (result != null) {
System.out.println("錄音文件識別結果查詢成功:" + result);
}
else {
System.out.println("錄音文件識別結果查詢失敗!");
}
}
}
Python代碼演示通過STS臨時訪問憑證調用錄音文件識別服務
# -*- coding: utf-8 -*-
import json
import time
from aliyunsdkcore.acs_exception.exceptions import ClientException
from aliyunsdkcore.acs_exception.exceptions import ServerException
from aliyunsdkcore.client import AcsClient
from aliyunsdkcore.auth.credentials import StsTokenCredential
from aliyunsdkcore.request import CommonRequest
REGION_ID = "cn-shanghai"
DOMAIN = "filetrans.cn-shanghai.aliyuncs.com"
PRODUCT = "nls-filetrans"
API_VERSION = "2018-08-17"
POST_REQUEST_ACTION = "SubmitTask"
GET_REQUEST_ACTION = "GetTaskResult"
KEY_APP_KEY = "appkey"
KEY_FILE_LINK = "file_link"
KEY_VERSION = "version"
KEY_TASK = "Task"
KEY_TASK_ID = "TaskId"
KEY_STATUS_TEXT = "StatusText"
def submitTask(stsAkId, stsAkSecret, stsToken, appKey, fileLink):
# 創建AcsClient實例
stsTokenCredential = StsTokenCredential(stsAkId, stsAkSecret, stsToken)
client = AcsClient(region_id=REGION_ID, credential=stsTokenCredential)
# 創建提交錄音文件識別請求,并設置請求參數。
postRequest = CommonRequest()
postRequest.set_domain(DOMAIN)
postRequest.set_version(API_VERSION)
postRequest.set_product(PRODUCT)
postRequest.set_action_name(POST_REQUEST_ACTION)
postRequest.set_method('POST')
task = {KEY_APP_KEY : appKey, KEY_FILE_LINK : fileLink, KEY_VERSION : "4.0", "enable_words" : False}
task = json.dumps(task)
print(task)
postRequest.add_body_params(KEY_TASK, task)
taskId = ""
try :
# 提交錄音文件識別請求,處理服務端返回的響應。
postResponse = client.do_action_with_exception(postRequest)
postResponse = json.loads(postResponse)
print(postResponse)
# 獲取錄音文件識別請求任務的ID,以供識別結果查詢使用。
statusText = postResponse[KEY_STATUS_TEXT]
if statusText == "SUCCESS" :
print("錄音文件識別請求成功響應!")
taskId = postResponse[KEY_TASK_ID]
print("taskId = " + taskId)
else :
print("錄音文件識別請求失敗!")
except ServerException as e:
print(e)
except ClientException as e:
print(e)
print(taskId)
return taskId
def queryResult(stsAkId, stsAkSecret, stsToken, taskId):
# 創建CommonRequest,設置任務ID。
stsTokenCredential = StsTokenCredential(stsAkId, stsAkSecret, stsToken)
client = AcsClient(region_id=REGION_ID, credential=stsTokenCredential)
getRequest = CommonRequest()
getRequest.set_domain(DOMAIN)
getRequest.set_version(API_VERSION)
getRequest.set_product(PRODUCT)
getRequest.set_action_name(GET_REQUEST_ACTION)
getRequest.set_method('GET')
getRequest.add_query_param(KEY_TASK_ID, taskId)
# 提交錄音文件識別結果查詢請求
# 以輪詢的方式進行識別結果的查詢,直到服務端返回的狀態描述符為"SUCCESS"、"SUCCESS_WITH_NO_VALID_FRAGMENT",或者為錯誤描述,則結束輪詢。
statusText = ""
while True :
try :
getResponse = client.do_action_with_exception(getRequest)
getResponse = json.loads(getResponse)
print (json.dumps(getResponse).decode('unicode-escape'))
statusText = getResponse[KEY_STATUS_TEXT]
if statusText == "RUNNING" or statusText == "QUEUEING" :
# 繼續輪詢
time.sleep(5)
else :
# 退出輪詢
break
except ServerException as e:
print (e)
except ClientException as e:
print (e)
if statusText == "SUCCESS" :
print ("錄音文件識別成功!")
else :
print ("錄音文件識別失敗!")
# 智能語音交互Appkey,獲取Appkey請前往控制臺:https://nls-portal.console.aliyun.com/applist
appKey = '******'
# 測試錄音的url
fileLink = "https://gw.alipayobjects.com/os/bmw-prod/0574ee2e-f494-45a5-820f-63aee583045a.wav"
# 相比非STS模式,此時此處填寫之前生成的STS臨時訪問憑證(含STS賬號信息及SecurityToken)
# 特別需要注意的是:臨時訪問憑證存在有效期,在有效期內您可以一直使用,但是請在過期前及時再次獲取
stsAkId = 'STS.******'
stsAkSecret = '******'
stsToken = '************'
print("--- submit one file ---")
taskId = submitTask(stsAkId, stsAkSecret, stsToken, appKey, fileLink)
print("--- query result ---")
queryResult(stsAkId, stsAkSecret, stsToken, taskId)
Go代碼演示通過STS臨時訪問憑證調用錄音文件轉寫服務
關于阿里云SDK Go語言版本的安裝操作,請參見Go SDK 依賴及STS SDK。
以下是Go代碼演示通過STS臨時訪問憑證調用錄音文件轉寫服務的完整示例:
package main
import (
"encoding/json"
"fmt"
"time"
"github.com/aliyun/alibaba-cloud-sdk-go/sdk"
"github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests"
)
func main() {
// 地域ID,固定值。
const REGION_ID string = "cn-shanghai"
const ENDPOINT_NAME string = "cn-shanghai"
const PRODUCT string = "nls-filetrans"
const DOMAIN string = "filetrans.cn-shanghai.aliyuncs.com"
const API_VERSION string = "2018-08-17"
const POST_REQUEST_ACTION string = "SubmitTask"
const GET_REQUEST_ACTION string = "GetTaskResult"
// 請求參數
const KEY_APP_KEY string = "appkey"
const KEY_FILE_LINK string = "file_link"
const KEY_VERSION string = "version"
const KEY_ENABLE_WORDS string = "enable_words"
// 響應參數
const KEY_TASK string = "Task"
const KEY_TASK_ID string = "TaskId"
const KEY_STATUS_TEXT string = "StatusText"
const KEY_RESULT string = "Result"
// 狀態值
const STATUS_SUCCESS string = "SUCCESS"
const STATUS_RUNNING string = "RUNNING"
const STATUS_QUEUEING string = "QUEUEING"
// 相比非STS模式,此時此處填寫之前生成的STS臨時訪問憑證(含STS賬號信息及SecurityToken)
// 特別需要注意的是:臨時訪問憑證存在有效期,在有效期內您可以一直使用,但是請在過期前及時再次獲取
var accessKeyId string = "STS.******"
var accessKeySecret string = "******"
var stsToken string = ""******""
var appKey string = "請填寫您的appkey"
var fileLink string = "https://gw.alipayobjects.com/os/bmw-prod/0574ee2e-f494-45a5-820f-63aee583045a.wav"
client, err := sdk.NewClientWithStsToken(REGION_ID, accessKeyId, accessKeySecret, stsToken)
if err != nil {
panic(err)
}
postRequest := requests.NewCommonRequest()
postRequest.Domain = DOMAIN
postRequest.Version = API_VERSION
postRequest.Product = PRODUCT
postRequest.ApiName = POST_REQUEST_ACTION
postRequest.Method = "POST"
mapTask := make(map[string]string)
mapTask[KEY_APP_KEY] = appKey
mapTask[KEY_FILE_LINK] = fileLink
// 新接入請使用4.0版本,已接入(默認2.0)如需維持現狀,請注釋掉該參數設置。
mapTask[KEY_VERSION] = "4.0"
// 設置是否輸出詞信息,默認為false。開啟時需要設置version為4.0。
mapTask[KEY_ENABLE_WORDS] = "false"
task, err := json.Marshal(mapTask)
if err != nil {
panic(err)
}
postRequest.FormParams[KEY_TASK] = string(task)
postResponse, err := client.ProcessCommonRequest(postRequest)
if err != nil {
panic(err)
}
postResponseContent := postResponse.GetHttpContentString()
fmt.Println(postResponseContent)
if postResponse.GetHttpStatus() != 200 {
fmt.Println("錄音文件識別請求失敗,Http錯誤碼: ", postResponse.GetHttpStatus())
return
}
var postMapResult map[string]interface{}
err = json.Unmarshal([]byte(postResponseContent), &postMapResult)
if err != nil {
panic(err)
}
var taskId string = ""
var statusText string = ""
statusText = postMapResult[KEY_STATUS_TEXT].(string)
if statusText == STATUS_SUCCESS {
fmt.Println("錄音文件識別請求成功響應!")
taskId = postMapResult[KEY_TASK_ID].(string)
} else {
fmt.Println("錄音文件識別請求失敗!")
return
}
getRequest := requests.NewCommonRequest()
getRequest.Domain = DOMAIN
getRequest.Version = API_VERSION
getRequest.Product = PRODUCT
getRequest.ApiName = GET_REQUEST_ACTION
getRequest.Method = "GET"
getRequest.QueryParams[KEY_TASK_ID] = taskId
statusText = ""
for true {
getResponse, err := client.ProcessCommonRequest(getRequest)
if err != nil {
panic(err)
}
getResponseContent := getResponse.GetHttpContentString()
fmt.Println("識別查詢結果:", getResponseContent)
if getResponse.GetHttpStatus() != 200 {
fmt.Println("識別結果查詢請求失敗,Http錯誤碼:", getResponse.GetHttpStatus())
break
}
var getMapResult map[string]interface{}
err = json.Unmarshal([]byte(getResponseContent), &getMapResult)
if err != nil {
panic(err)
}
statusText = getMapResult[KEY_STATUS_TEXT].(string)
if statusText == STATUS_RUNNING || statusText == STATUS_QUEUEING {
time.Sleep(10 * time.Second)
} else {
break
}
}
if statusText == STATUS_SUCCESS {
fmt.Println("錄音文件識別成功!")
} else {
fmt.Println("錄音文件識別失敗!")
}
}
Node.js代碼演示通過STS臨時訪問憑證調用錄音文件識別服務
請您提前安裝阿里云Core SDK、STS SDK及錄音文件轉寫識別SDK,前兩個SDK的安裝,請參見Node.js SDK安裝及示例。簡單步驟如下:
npm install @alicloud/pop-core --save
npm install @alicloud/sts-sdk --save
npm install @alicloud/nls-filetrans-2018-08-17 --save
以下是Node.js代碼演示通過STS臨時訪問憑證調用錄音文件轉寫服務的完整示例:
'use strict';
const Client = require('@alicloud/nls-filetrans-2018-08-17');
function fileTrans(akID, akSecret, stsToken, appKey, fileLink) {
//地域ID,固定值。
var ENDPOINT = 'http://filetrans.cn-hangzhou.aliyuncs.com';
var API_VERSION = '2018-08-17';
/**
* 創建阿里云鑒權client
*/
var client = new Client({
accessKeyId: akID,
secretAccessKey: akSecret,
securityToken: stsToken,
endpoint: ENDPOINT,
apiVersion: API_VERSION
});
/**
* 提交錄音文件識別請求,請求參數組合成JSON格式的字符串作為task的值。
* 請求參數appkey:項目appkey,獲取Appkey請前往控制臺:https://nls-portal.console.aliyun.com/applist
* 請求參數file_link:需要識別的錄音文件。
*/
var task = {
appkey : appKey,
file_link : fileLink,
version : "4.0", // 新接入請使用4.0版本,已接入(默認2.0)如需維持現狀,請注釋掉該參數設置。
enable_words : false // 設置是否輸出詞信息,默認值為false,開啟時需要設置version為4.0。
};
task = JSON.stringify(task);
var taskParams = {
Task : task
};
var options = {
method: 'POST'
};
// 提交錄音文件識別請求,處理服務端返回的響應。
client.submitTask(taskParams, options).then((response) => {
console.log(response);
// 服務端響應信息的狀態描述StatusText。
var statusText = response.StatusText;
if (statusText != 'SUCCESS') {
console.log('錄音文件識別請求響應失敗!')
return;
}
console.log('錄音文件識別請求響應成功!');
// 獲取錄音文件識別請求任務的TaskId,以供識別結果查詢使用。
var taskId = response.TaskId;
/**
* 以TaskId為查詢參數,提交識別結果查詢請求。
* 以輪詢的方式進行識別結果的查詢,直到服務端返回的狀態描述為"SUCCESS"、SUCCESS_WITH_NO_VALID_FRAGMENT,
* 或者為錯誤描述,則結束輪詢。
*/
var taskIdParams = {
TaskId : taskId
};
var timer = setInterval(() => {
client.getTaskResult(taskIdParams).then((response) => {
console.log('識別結果查詢響應:');
console.log(response);
var statusText = response.StatusText;
if (statusText == 'RUNNING' || statusText == 'QUEUEING') {
// 繼續輪詢,注意間隔周期。
}
else {
if (statusText == 'SUCCESS' || statusText == 'SUCCESS_WITH_NO_VALID_FRAGMENT') {
console.log('錄音文件識別成功:');
var sentences = response.Result;
console.log(sentences);
}
else {
console.log('錄音文件識別失敗!');
}
// 退出輪詢
clearInterval(timer);
}
}).catch((error) => {
console.error(error);
// 異常情況,退出輪詢。
clearInterval(timer);
});
}, 10000);
}).catch((error) => {
console.error(error);
});
}
// 相比非STS模式,此時此處填寫之前生成的STS臨時訪問憑證(含STS賬號信息及SecurityToken)
// 特別需要注意的是:臨時訪問憑證存在有效期,在有效期內您可以一直使用,但是請在過期前及時再次獲取
var akId = 'STS.******';
var akSecret = '******';
var stsToken = '******';
var appKey = '請填寫您的appkey';
var fileLink = 'https://gw.alipayobjects.com/os/bmw-prod/0574ee2e-f494-45a5-820f-63aee583045a.wav';
fileTrans(akId, akSecret, stsToken, appKey, fileLink);
PHP代碼演示通過STS臨時訪問憑證調用錄音文件識別服務
請您提前安裝阿里云Core SDK、STS SDK的PHP語言版本,詳細安裝請參見Node.js SDK安裝及示例。簡單步驟如下:
composer require alibabacloud/sdk
composer require alibabacloud/sts
以下是PHP代碼演示通過STS臨時訪問憑證調用錄音文件識別服務的完整示例:
<?php
require __DIR__ . '/vendor/autoload.php';
use AlibabaCloud\Client\AlibabaCloud;
use AlibabaCloud\Client\Exception\ClientException;
use AlibabaCloud\Client\Exception\ServerException;
class NLSFileTrans {
// 請求參數
private const KEY_APP_KEY = "appkey";
private const KEY_FILE_LINK = "file_link";
private const KEY_VERSION = "version";
private const KEY_ENABLE_WORDS = "enable_words";
// 響應參數
private const KEY_TASK_ID = "TaskId";
private const KEY_STATUS_TEXT = "StatusText";
private const KEY_RESULT = "Result";
// 狀態值
private const STATUS_SUCCESS = "SUCCESS";
private const STATUS_RUNNING = "RUNNING";
private const STATUS_QUEUEING = "QUEUEING";
function submitFileTransRequest($appKey, $fileLink) {
// 獲取task JSON字符串,包含appkey和file_link參數等。
$taskArr = array(self::KEY_APP_KEY => $appKey, self::KEY_FILE_LINK => $fileLink, self::KEY_VERSION => "4.0", self::KEY_ENABLE_WORDS => FALSE);
$task = json_encode($taskArr);
print $task . "\n";
try {
// 提交請求,返回服務端的響應。
$submitTaskResponse = AlibabaCloud::nlsFiletrans()
->v20180817()
->submitTask()
->host("filetrans.cn-shanghai.aliyuncs.com")
->withTask($task)
->request();
print $submitTaskResponse . "\n";
// 獲取錄音文件識別請求任務的ID,以供識別結果查詢使用。
$taskId = NULL;
$statusText = $submitTaskResponse[self::KEY_STATUS_TEXT];
if (strcmp(self::STATUS_SUCCESS, $statusText) == 0) {
$taskId = $submitTaskResponse[self::KEY_TASK_ID];
}
return $taskId;
} catch (ClientException $exception) {
// 獲取錯誤消息
print_r($exception->getErrorMessage());
} catch (ServerException $exception) {
// 獲取錯誤消息
print_r($exception->getErrorMessage());
}
}
function getFileTransResult($taskId) {
$result = NULL;
while (TRUE) {
try {
$getResultResponse = AlibabaCloud::nlsFiletrans()
->v20180817()
->getTaskResult()
->host("filetrans.cn-shanghai.aliyuncs.com")
->withTaskId($taskId)
->request();
print "識別查詢結果: " . $getResultResponse . "\n";
$statusText = $getResultResponse[self::KEY_STATUS_TEXT];
if (strcmp(self::STATUS_RUNNING, $statusText) == 0 || strcmp(self::STATUS_QUEUEING, $statusText) == 0) {
// 繼續輪詢
sleep(10);
}
else {
if (strcmp(self::STATUS_SUCCESS, $statusText) == 0) {
$result = $getResultResponse;
}
// 退出輪詢
break;
}
} catch (ClientException $exception) {
// 獲取錯誤消息
print_r($exception->getErrorMessage());
} catch (ServerException $exception) {
// 獲取錯誤消息
print_r($exception->getErrorMessage());
}
}
return $result;
}
}
$accessKeyId = "STS.******";
$accessKeySecret = "******";
$stsToken = "******";
$appKey = "請填寫您的appkey";
$fileLink = "https://gw.alipayobjects.com/os/bmw-prod/0574ee2e-f494-45a5-820f-63aee583045a.wav";
/**
* 第一步:設置一個全局客戶端。
* 使用阿里云RAM賬號的AccessKey ID和AccessKey Secret進行鑒權。
*/
Alibabacloud::stsClient($accessKeyId, $accessKeySecret, $stsToken)
->regionId("cn-shanghai")
->asGlobalClient();
$fileTrans = new NLSFileTrans();
/**
* 第二步:提交錄音文件識別請求,獲取任務ID,用于后續的識別結果輪詢。
*/
$taskId = $fileTrans->submitFileTransRequest($appKey, $fileLink);
if ($taskId != NULL) {
print "錄音文件識別請求成功,task_id: " . $taskId . "\n";
}
else {
print "錄音文件識別請求失敗!";
return ;
}
/**
* 第三步:根據任務ID輪詢識別結果。
*/
$result = $fileTrans->getFileTransResult($taskId);
if ($result != NULL) {
print "錄音文件識別結果查詢成功: " . $result . "\n";
}
else {
print "錄音文件識別結果查詢失敗!";
}