Use Function Compute for audio file recognition

更新时间:
复制 MD 格式

This topic describes how to use Function Compute for audio file recognition.

Overview

If you store audio files in OSS, you can automate the audio file recognition process using Function Compute. Instead of integrating an SDK, you can set up an OSS trigger to automatically invoke a function when a new audio file is uploaded. The function then processes the file and saves the recognition result to OSS or another storage service. This approach reduces SDK integration effort and lets non-developers quickly obtain and analyze recognition results. For more information about Function Compute, see What is Function Compute?.

Prerequisites

Ensure the following services are activated and that the account for Function Compute has read and write permissions on OSS:

  • You have activated OSS and obtained an AccessKey ID, an AccessKey Secret, and an OSS endpoint. For more information, see OSS.

  • You have activated Function Compute. For more information, see Function Compute.

  • You have activated Intelligent Speech Interaction and obtained an AccessKey ID, an AccessKey Secret, and an Appkey. For more information, see Intelligent Speech Interaction.

Demonstration

Note

This tutorial uses the OSS bucket nls-file-trans. Audio files are stored in the filetrans/raw path, and recognition results are saved to the filetrans/result path. Results are stored in JSON files. Successful recognition files are named [filename]_[taskId].json, and failed ones are named [filename]_[taskId]_failed.json. When you implement this solution, replace these values with your actual bucket name and paths.

  • Upload an audio file from the OSS console

    Click Upload File to upload an audio file to the specified bucket path filetrans/raw.

    Function Compute triggers:

    The Function Compute configuration includes two triggers: put-file-trigger (event type oss:ObjectCreated:PutObject) and post-file-trigger (event type oss:ObjectCreated:PostObject). Both triggers use the prefix filetrans/raw/ and the suffix .wav.

    Path for recognition results: filetrans/result

    This path contains three JSON files with the recognition results. The filenames follow the format [audio_filename]_[taskId].json. One of the result filenames includes the _failed suffix, indicating that the recognition task for that audio file failed.

    The following code block shows the recognition result for the uploaded nls-sample-16k.wav audio file:

    {
        "Result": {
            "Sentences": [{
                "EndTime": 2365,
                "SilenceDuration": 0,
                "BeginTime": 340,
                "Text": "北京的天气。",
                "ChannelId": 0,
                "SpeechRate": 177,
                "EmotionValue": 5.0
            }]
        },
        "TaskId": "fb0474184c6d11e9a213e11db149****",
        "StatusCode": 21050000,
        "StatusText": "SUCCESS",
        "RequestTime": 1553237085804,
        "SolveTime": 1553237086146,
        "BizDuration": 2956
    }
  • Upload an audio file using a common OSS tool

    This example uses ossutil. The recognition process is the same as uploading a file from the console.

    ossutil cp nls-sample-16k.wav oss://nls-file-trans/filetrans/raw/nls-sample-16k.wav

Implementation

Implement the following in Function Compute:

  1. Create a Function Compute service.

  2. Create a function to submit recognition tasks. This function is invoked by an OSS trigger and requires the callback URL from Step 3.

  3. Create a function to receive callbacks and save the results to OSS. This function is invoked by an HTTP trigger, which provides the necessary callback URL.

Step 1: Create a service

  1. Create a service in the Function Compute console.

    You can configure advanced settings during or after service creation.

    In the Create service dialog box, enter a Service name, which can contain only letters, digits, underscores (_), and hyphens (-). It cannot start with a digit or a hyphen and must be 1 to 128 characters in length. Select a region. You cannot change the region after service creation. Optionally, enter a Description and enable Advanced Settings as needed.

  2. Create a service role.

    Under Advanced Settings > Permissions, if you do not have an existing role, create a new one. For System Policies, select AliyunOSSFullAccess and click Authorize.

  3. Add permissions.

    Log on to the Resource Access Management (RAM) console. In the left-side navigation pane, choose Identities > Roles. Grant the AliyunOSSFullAccess, AliyunSTSAssumeRoleAccess, and AliyunNLSFullAccess policies to the role.

Step 2: Create the task submission function

When an audio file is uploaded to OSS, an OSS trigger invokes this function to submit an audio file recognition request.

  1. Create the function.

    Under the service you created, create a function to submit tasks with the following parameters:

    • Function name: call_filetrans

    • Handler: call_filetrans.handler

    • Runtime: Python 3

    • Memory: 128 MB (Select the minimum value, as this affects Function Compute billing.)

    • Timeout: 600s

    In the following function code, replace the placeholder parameters with your actual values:

    • The AccessKey ID, AccessKey Secret, and public endpoint for your OSS account.

    • The AccessKey ID, AccessKey Secret, Appkey, and callback URL for your audio file recognition service. You will obtain the callback URL when you create the HTTP trigger.

    # -*- 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
    import oss2
    import logging
    # The public endpoint for your OSS account.
    ossEndPoint = "YOUR_OSS_ENDPOINT"
    # The Appkey for audio file recognition. Obtain it from the console: https://nls-portal.console.aliyun.com/applist
    fileTransAppkey = "YOUR_APPKEY"
    # The callback URL. You will obtain this when you create the HTTP trigger.
    fileTransCallbackUrl = "YOUR_CALLBACK_URL"
    def handler(event, context):
        logger = logging.getLogger()
        logger.info(event)
        eventObj = json.loads(event)["events"]
        eventName=eventObj[0]["eventName"]
        bucketName=eventObj[0]["oss"]["bucket"]["name"]
        ossFileName=eventObj[0]["oss"]["object"]["key"]
        logger.info("eventName: %s" % eventName)
        logger.info("bucketName: %s" % bucketName)
        logger.info("ossFileName: %s" % ossFileName)
        appKey = fileTransAppkey
        # The following values are fixed.
        REGION_ID = "cn-shanghai"
        PRODUCT = "nls-filetrans"
        DOMAIN = "filetrans.cn-shanghai.aliyuncs.com"
        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"
        creds = context.credentials
        # Create an AcsClient instance.
        sts_token_credential = StsTokenCredential(creds.accessKeyId, creds.accessKeySecret, creds.securityToken)
        client = AcsClient(region_id=REGION_ID, credential=sts_token_credential)
        # Create a request to submit an audio file recognition task and set the parameters.
        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')
        filename = ossFileName.split('/')[-1]
        # Create file URL.
        auth = oss2.StsAuth(creds.accessKeyId, creds.accessKeySecret, creds.securityToken)
        bucket = oss2.Bucket(auth, ossEndPoint, bucketName)
        fileLink = bucket.sign_url('GET', ossFileName, 3600)
        logger.info("file link = " + fileLink)
        # The callback URL is generated in Step 3.
        callback_url = fileTransCallbackUrl + "/" + filename
        logger.info("callback url = " + callback_url)
        task = {"SecurityToken": creds.securityToken, KEY_APP_KEY : appKey, KEY_FILE_LINK : fileLink, KEY_VERSION : "4.0", "enable_words" : False, "enable_callback" : True, "callback_url" : callback_url}
        task = json.dumps(task)
        #logger.info (task)
        postRequest.add_body_params(KEY_TASK, task)
        taskId = ""
        try :
            # Submit the audio file recognition request and process the server response.
            postResponse = client.do_action_with_exception(postRequest)
            postResponse = json.loads(postResponse)
            logger.info(postResponse)
            # Obtain the task ID to query the recognition result.
            statusText = postResponse[KEY_STATUS_TEXT]
            if statusText == "SUCCESS" :
                logger.info("Audio file recognition request succeeded!")
                taskId = postResponse[KEY_TASK_ID]
                logger.info("taskId = " + taskId)
            else :
                logger.info ("Audio file recognition request failed!")
        except ServerException as e:
            logger.error(e)
        except ClientException as e:
            logger.error(e)
        logger.info('hello world')
        logger.info(taskId)
        return taskId
  2. Create and configure the OSS triggers.

    Important

    You can upload files to an OSS bucket using PutObject or PostObject operations. To handle all upload events, you must create two separate OSS triggers.

    Parameter

    Description

    Trigger type

    Object Storage trigger.

    Trigger name

    A custom name.

    Event type

    Create two triggers, one for oss:ObjectCreated:PutObject and another for oss:ObjectCreated:PostObject.

    Trigger rule: Prefix

    filetrans/raw/

    Trigger rule: Suffix

    .wav

    Role

    Select an existing role or create a new one.

    You can find the created triggers in the OSS console under the corresponding bucket's Function Compute settings.

    • oss:ObjectCreated:PutObject event:

      Set Trigger type to Object Storage trigger and Trigger name to put-file-trigger. For the trigger rules, set Prefix to filetrans/raw/ and Suffix to .wav. For Role creation method, select Select existing role and choose AliyunOSSEventNotificationRole for Existing role.

    • oss:ObjectCreated:PostObject event:

      Set Trigger name to post-file-trigger. For the trigger rules, set Prefix to filetrans/raw/ and Suffix to .wav. For Role creation method, select Select existing role and choose AliyunOSSEventNotificationRole for Existing role.

Step 3: Create a callback function

After Intelligent Speech Interaction completes the recognition, it sends the result to a callback URL. This URL is provided by an HTTP trigger, which invokes a function to save the result to an OSS bucket. You must add this URL to the task submission function from Step 2.

  1. Create the function.

    Under the service you created, create a function to write the results back to OSS with the following parameters:

    • Function name: put_http_post_to_oss

    • Handler: index.handler

    • Runtime: Python 3

    • Memory: 128 MB (Select the minimum value, as this affects Function Compute billing.)

    • Timeout: 600s

    In the following function code, replace the placeholder parameters with your actual values:

    • The public endpoint for OSS.

    • The name of your OSS bucket.

    • The path in your OSS bucket where recognition results will be stored.

    # -*- coding: utf-8 -*-
    import logging
    import oss2
    import json
    # OSS public endpoint
    endpoint = "YOUR_OSS_ENDPOINT" 
    # OSS bucket name
    bucketName = "YOUR_OSS_BUCKET_NAME" 
    # The OSS path to store recognition results.
    resultOssPath = "YOUR_RESULT_PATH"
    B_OK = b"ok"
    def handler(environ, start_response):
        logger = logging.getLogger()
        context = environ['fc.context']
        request_uri = environ['fc.request_uri']
        for k, v in environ.items():
          if k.startswith("HTTP_"):
            # process custom request headers
            pass
        logger.info("request_uri = " + request_uri)
        filename = request_uri.split('/')[-1]
        logger.info('filename = ' + filename)
        # Get request_body.
        try:
            request_body_size = int(environ.get('CONTENT_LENGTH', 0))
        except (ValueError):
            request_body_size = 0
        request_body = environ['wsgi.input'].read(request_body_size)
        # Parse result.
        postResponse = json.loads(request_body)
        taskId = postResponse['TaskId']
        statusText = postResponse['StatusText']
        # Put result to OSS.
        creds = context.credentials
        auth = oss2.StsAuth(creds.accessKeyId, creds.accessKeySecret, creds.securityToken)
        logger.info("creds.accessKeyId = " + creds.accessKeyId)
        logger.info("creds.accessKeySecret = " + creds.accessKeySecret)
        logger.info("creds.securityToken = " + creds.securityToken)
        bucket = oss2.Bucket(auth, endpoint, bucketName)
        if statusText == "SUCCESS" :
          filename = resultOssPath + "/" + filename + "_" + taskId + '.json'
        else :
          filename = resultOssPath + "/" + filename + "_" + taskId + '_failed.json'
        logger.info('filename = ' + filename)
        bucket.put_object(filename, request_body)
        # Do something here.
        status = '200 OK'
        response_headers = [('Content-type', 'text/plain')]
        start_response(status, response_headers)
        return [B_OK]
  2. Create and configure the HTTP trigger.

    After you create the trigger based on the following table, the system automatically generates a path that serves as the callback URL. Add this URL to the fileTransCallbackUrl parameter in the task submission function's code (from Step 2).

    Parameter

    Description

    Trigger type

    HTTP trigger

    Trigger name

    http_post_caller

    Authorization method

    anonymous

    Request method

    POST

    You can find the callback URL in the URL column on the Triggers page.