Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/powerbi/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Amazon使用Http/2在Node.js中转录流媒体服务请求时未给出响应_Node.js_Amazon Web Services_Aws Transcribe - Fatal编程技术网

Amazon使用Http/2在Node.js中转录流媒体服务请求时未给出响应

Amazon使用Http/2在Node.js中转录流媒体服务请求时未给出响应,node.js,amazon-web-services,aws-transcribe,Node.js,Amazon Web Services,Aws Transcribe,我正在尝试将Amazon转录流媒体服务与Node.js的http2请求一起使用,下面是我所关注的文档链接 . 根据本文档,终点是..amazonaws.com,但请求此url会导致url未找到错误。 但是在找到的端点为''''.amazonaws.com中,因此向该url发出请求不会返回任何错误或响应。我正在美国东部1区尝试 这是我正在尝试的代码 const http2 = require('http2'); var aws4 = require('aws4'); var opts = {

我正在尝试将Amazon转录流媒体服务与Node.js的http2请求一起使用,下面是我所关注的文档链接 . 根据本文档,终点是..amazonaws.com,但请求此url会导致url未找到错误。 但是在找到的端点为''''.amazonaws.com中,因此向该url发出请求不会返回任何错误或响应。我正在美国东部1区尝试

这是我正在尝试的代码

const http2 = require('http2');
var aws4  = require('aws4');

var opts = {
  service: 'transcribe', 
  region: 'us-east-1', 
  path: '/stream-transcription', 
  headers:{
   'content-type': 'application/json',
   'x-amz-target': 'com.amazonaws.transcribe.Transcribe.StartStreamTranscription'
  }
}

var urlObj = aws4.sign(opts, {accessKeyId: '<access key>', secretAccessKey: '<aws secret>'});
const client = http2.connect('https://transcribestreaming.<region>.amazonaws.com');
client.on('error', function(err){
  console.error("error in request ",err);
});

const req = client.request({
  ':method': 'POST',
  ':path': '/stream-transcription',
  'authorization': urlObj.headers.Authorization,  
  'content-type': 'application/json',
  'x-amz-content-sha256': 'STREAMING-AWS4-HMAC-SHA256-EVENTS',
  'x-amz-target': 'com.amazonaws.transcribe.Transcribe.StartStreamTranscription',
  'x-amz-date': urlObj['headers']['X-Amz-Date'],
  'x-amz-transcribe-language-code': 'en-US',
  'x-amz-transcribe-media-encoding': 'pcm',
  'x-amz-transcribe-sample-rate': 44100
});

req.on('response', (headers, flags) => {
  for (const name in headers) {
    console.log(`${name}: ${headers[name]}`);
  }
});
let data = '';
req.on('data', (chunk) => { data += chunk; });
req.on('end', () => {
  console.log(`\n${data}`);
  client.close();
});
req.end();
更新(2019年4月22日):

在结束请求之前,我通过序列化添加一个“audioblod”作为有效负载。我的“audioBufferData”是来自浏览器的原始PCM音频格式。 我从有效负载中看到必须编码为“事件流编码”,但我不知道如何实现它

因此,目前没有这个事件流编码,我得到以下异常,响应状态为200

{"Output":{"__type":"com.amazon.coral.service#UnknownOperationException"},"Version":"1.0"}

我联系了AWS支持人员,他们似乎也无法使用NodeJS实现HTTP/2

然而,他们现在提供了一种直接通过WebSocket(博客文章)与转录流式API交互的方法

如果这符合您的用例,我强烈建议您在以下位置查看新的回购示例:


如果您在面向公众的页面中使用它,我建议您使用未经验证的Cognoto会话来处理凭证检索。我已经在一个生产应用程序中实现了这一点,所以请随时在任何其他问题中标记我

这并不能直接回答这个问题,但我认为它足够有用,可以作为答案而不是评论发布

AWS WebSocket对Amazon转录的支持,这是一个例子。最大的区别,也是我认为使与WebSockets集成更简单的区别,是您不需要像http/2那样对每个音频块进行签名

中提供了使用预签名URL授权和启动连接的相关代码

我们在以下方面引用它:

要以我们需要的事件流消息格式进行打包,我们需要


在节点js中使用AWS转录服务和WebSocket API时,我也有类似的要求。鉴于官方软件包中还没有对这一点的支持,我已经在这个实现之后编写了一个软件包。它叫AWS转录,可以找到。我希望这有帮助

它在WebSocket周围提供了一个流接口,可以像下面的示例一样使用

import { AwsTranscribe, StreamingClient } from "aws-transcribe"

const client = new AwsTranscribe({
    // if these aren't provided, they will be taken from the environment
    accessKeyId: "ACCESS KEY HERE",
    secretAccessKey: "SECRET KEY HERE",
})

const transcribeStream = client
    .createStreamingClient({
        region: "eu-west-1",
        sampleRate,
        languageCode: "en-US",
    })
    // enums for returning the event names which the stream will emit
    .on(StreamingClient.EVENTS.OPEN, () => console.log(`transcribe connection opened`))
    .on(StreamingClient.EVENTS.ERROR, console.error)
    .on(StreamingClient.EVENTS.CLOSE, () => console.log(`transcribe connection closed`))
    .on(StreamingClient.EVENTS.DATA, (data) => {
        const results = data.Transcript.Results

        if (!results || results.length === 0) {
            return
        }

        const result = results[0]
        const final = !result.IsPartial
        const prefix = final ? "recognized" : "recognizing"
        const text = result.Alternatives[0].Transcript
        console.log(`${prefix} text: ${text}`)
    })

someStream.pipe(transcribeStream)

AWS SDK V3现在支持转录流:

您是否能够实现这一功能?我也有类似的情况。谢谢没有,仍然停留在同一个问题上。还有关于流式转录的旧文档,它有正确的主机,但内容类型不正确:D我在Go中与相同的API进行斗争,我能够通过初始连接和IAM身份验证,但尚未完全工作。删除/不设置内容类型应该会有所帮助。在我的例子中,设置正确的
内容类型
返回HTTP 404。但是在那之后,我被卡住了。是的,设置内容类型:application/json返回了状态为200的响应,但异常为{“Output”:{“{uuuu type”:“com.amazon.coral.service#SerializationException”},“Version”:“1.0”};但是如果没有提供内容类型,它会给出403。谢谢@calvin的努力。我尝试运行此代码,但它出现以下异常“message typeappexception{“message”:“无法处理您提供的音频流。请重试您的请求。”}o?=o?=(“。我使用的是同一个文件,当我使用我在问题中提到的Java示例时,该文件运行良好。嘿@Manoj-我在这里的回答还不成熟。但是,在与AWS来回了一段时间之后,我们终于有了一些进展。请参阅editThreak@calvin-我的用例有点不同,我们有一个自行开发的日志服务来检测speaker change等…目前AWS不提供。因此,如果我使用websockets浏览器,将需要双倍的带宽才能将数据发送到两个不同的服务。因此,现在作为一种解决方法,我编辑了他们提供的java示例,并在后端使用它发送请求。尽管在流式处理20或30分钟后,它仍然面临一些问题当会话仍然从AWS服务处于活动状态时,异常已过期。
{"Output":{"__type":"com.amazon.coral.service#UnknownOperationException"},"Version":"1.0"}
exports.createPresignedURL = function(method, host, path, service, payload, options) {
  options = options || {};
  options.key = options.key || process.env.AWS_ACCESS_KEY_ID;
  options.secret = options.secret || process.env.AWS_SECRET_ACCESS_KEY;
  options.protocol = options.protocol || 'https';
  options.headers = options.headers || {};
  options.timestamp = options.timestamp || Date.now();
  options.region = options.region || process.env.AWS_REGION || 'us-east-1';
  options.expires = options.expires || 86400; // 24 hours
  options.headers = options.headers || {};

  // host is required
  options.headers.Host = host;

  var query = options.query ? querystring.parse(options.query) : {};
  query['X-Amz-Algorithm'] = 'AWS4-HMAC-SHA256';
  query['X-Amz-Credential'] = options.key + '/' + exports.createCredentialScope(options.timestamp, options.region, service);
  query['X-Amz-Date'] = toTime(options.timestamp);
  query['X-Amz-Expires'] = options.expires;
  query['X-Amz-SignedHeaders'] = exports.createSignedHeaders(options.headers);

  var canonicalRequest = exports.createCanonicalRequest(method, path, query, options.headers, payload);
  var stringToSign = exports.createStringToSign(options.timestamp, options.region, service, canonicalRequest);
  var signature = exports.createSignature(options.secret, options.timestamp, options.region, service, stringToSign);
  query['X-Amz-Signature'] = signature;
  return options.protocol + '://' + host + path + '?' + querystring.stringify(query);
};
function createPresignedUrl() {
    let endpoint = "transcribestreaming." + region + ".amazonaws.com:8443";

    // get a preauthenticated URL that we can use to establish our WebSocket
    return v4.createPresignedURL(
        'GET',
        endpoint,
        '/stream-transcription-websocket',
        'transcribe',
        crypto.createHash('sha256').update('', 'utf8').digest('hex'), {
            'key': $('#access_id').val(),
            'secret': $('#secret_key').val(),
            'protocol': 'wss',
            'expires': 15,
            'region': region,
            'query': "language-code=" + languageCode + "&media-encoding=pcm&sample-rate=" + sampleRate
        }
    );
}
function convertAudioToBinaryMessage(audioChunk) {
    let raw = mic.toRaw(audioChunk);

    if (raw == null)
        return;

    // downsample and convert the raw audio bytes to PCM
    let downsampledBuffer = audioUtils.downsampleBuffer(raw, sampleRate);
    let pcmEncodedBuffer = audioUtils.pcmEncode(downsampledBuffer);

    // add the right JSON headers and structure to the message
    let audioEventMessage = getAudioEventMessage(Buffer.from(pcmEncodedBuffer));

    //convert the JSON object + headers into a binary event stream message
    let binary = eventStreamMarshaller.marshall(audioEventMessage);

    return binary;
}

function getAudioEventMessage(buffer) {
    // wrap the audio data in a JSON envelope
    return {
        headers: {
            ':message-type': {
                type: 'string',
                value: 'event'
            },
            ':event-type': {
                type: 'string',
                value: 'AudioEvent'
            }
        },
        body: buffer
    };
}
import { AwsTranscribe, StreamingClient } from "aws-transcribe"

const client = new AwsTranscribe({
    // if these aren't provided, they will be taken from the environment
    accessKeyId: "ACCESS KEY HERE",
    secretAccessKey: "SECRET KEY HERE",
})

const transcribeStream = client
    .createStreamingClient({
        region: "eu-west-1",
        sampleRate,
        languageCode: "en-US",
    })
    // enums for returning the event names which the stream will emit
    .on(StreamingClient.EVENTS.OPEN, () => console.log(`transcribe connection opened`))
    .on(StreamingClient.EVENTS.ERROR, console.error)
    .on(StreamingClient.EVENTS.CLOSE, () => console.log(`transcribe connection closed`))
    .on(StreamingClient.EVENTS.DATA, (data) => {
        const results = data.Transcript.Results

        if (!results || results.length === 0) {
            return
        }

        const result = results[0]
        const final = !result.IsPartial
        const prefix = final ? "recognized" : "recognizing"
        const text = result.Alternatives[0].Transcript
        console.log(`${prefix} text: ${text}`)
    })

someStream.pipe(transcribeStream)