繁体   English   中英

Alexa-SDK音频问题

[英]Alexa-SDK Audio Issue

我一直在尝试制作涉及音频的alexa技能。 我在这里找到了很棒的指南。

这是他们的示例代码:

var stateByUser = {};
var podcastURL = "https://feeds.soundcloud.com/stream/309340878-user-652822799-episode-010-building-an-alexa-skill-with-flask-ask-with-john-wheeler.mp3";

// Entry-point for the Lambda
exports.handler = function(event, context) {
    var player = new SimplePlayer(event, context);
    player.handle();
};

// The SimplePlayer has helpful routines for interacting with Alexa, within minimal overhead
var SimplePlayer = function (event, context) {
    this.event = event;
    this.context = context;
};

// Handles an incoming Alexa request
SimplePlayer.prototype.handle = function () {
    var requestType = this.event.request.type;
    var userId = this.event.context ? this.event.context.System.user.userId : this.event.session.user.userId;
    var response = null;

    // On launch, we tell the user what they can do (Play audio :-))
    if (requestType === "LaunchRequest") {
        this.say("Welcome to the Simple Audio Player. Say Play to play some audio!", "You can say Play");

    // Handle Intents here - Play, Pause and Resume is all for now
    } else if (requestType === "IntentRequest") {
        var intent = this.event.request.intent;
        if (intent.name === "Play") {
            this.play(podcastURL, 0);

        } else if (intent.name === "AMAZON.PauseIntent") {
            // When we receive a Pause Intent, we need to issue a stop directive
            //  Otherwise, it will resume playing - essentially, we are confirming the user's action
            this.stop();

        } else if (intent.name === "AMAZON.ResumeIntent") {
            var lastPlayed = this.load(userId);
            var offsetInMilliseconds = 0;
            if (lastPlayed !== null) {
                offsetInMilliseconds = lastPlayed.request.offsetInMilliseconds;
            }

            this.play(podcastURL, offsetInMilliseconds);
        }
    } else if (requestType === "AudioPlayer.PlaybackStopped") {
        // We save off the PlaybackStopped Intent, so we know what was last playing
        this.save(userId, this.event);

    }
};

/**
 * Creates a proper Alexa response using Text-To-Speech
 * @param message
 * @param repromptMessage
 */
SimplePlayer.prototype.say = function (message, repromptMessage) {
    var response = {
        version: "1.0",
        response: {
            shouldEndSession: false,
            outputSpeech: {
                type: "SSML",
                ssml: "<speak> " + message + " </speak>"
            },
            reprompt: {
                outputSpeech: {
                    type: "SSML",
                    ssml: "<speak> " + message + " </speak>"
                }
            }
        }
    }
    this.context.succeed(response);
};

/**
 * Plays a particular track, from specific offset
 * @param audioURL The URL to play
 * @param offsetInMilliseconds The point from which to play - we set this to something other than zero when resuming
 */
SimplePlayer.prototype.play = function (audioURL, offsetInMilliseconds) {
    var response = {
        version: "1.0",
        response: {
            shouldEndSession: true,
            directives: [
                {
                    type: "AudioPlayer.Play",
                    playBehavior: "REPLACE_ALL", // Setting to REPLACE_ALL means that this track will start playing immediately
                    audioItem: {
                        stream: {
                            url: audioURL,
                            token: "0", // Unique token for the track - needed when queueing multiple tracks
                            expectedPreviousToken: null, // The expected previous token - when using queues, ensures safety
                            offsetInMilliseconds: offsetInMilliseconds
                        }
                    }
                }
            ]
        }
    }

    this.context.succeed(response);
};

// Stops the playback of Audio
SimplePlayer.prototype.stop = function () {
    var response = {
        version: "1.0",
        response: {
            shouldEndSession: true,
            directives: [
                {
                    type: "AudioPlayer.Stop"
                }
            ]
        }
    }

    this.context.succeed(response);
};

// Saves information into our super simple, not-production-grade cache
SimplePlayer.prototype.save = function (userId, state) {
    console.log("Save: " + userId);
    stateByUser[userId] = state;
};

// Load information from our super simple, not-production-grade cache
SimplePlayer.prototype.load = function (userId) {
    console.log("Load: " + userId);
    var state = null;
    if (userId in stateByUser) {
        state = stateByUser[userId];
        console.log("Loaded " + userId + " State: " + state);
    }
    return state;
};

我正在尝试重构此代码,以便它遵循与亚马逊提供的琐事技巧示例类似的格式。 但是,当我运行我的重构代码时,我得到一个错误说

TypeError: Cannot set property 'say' of undefined
at Object.<anonymous> (/Users/Rob/Desktop/super-simple-audio-player/index.js:47:28)

这是我重构的尝试

"use strict";


var stateByUser = {};
var podcastURL = "https://p.scdn.co/mp3-preview/2385471a5d35709ad90e368dacabe4082af4541a?cid=null";
var Alexa = require("alexa-sdk");
// Entry-point for the Lambda
exports.handler = function(event, context) {
    var alexa = Alexa.handler(event, context);

    alexa.registerHandlers(SimplePlayer);

    alexa.execute();
};

// The SimplePlayer has helpful routines for interacting with Alexa, within minimal overhead
var SimplePlayer = {
  "LaunchRequest": function () {
        this.emit(":tell","Welcome to the Simple Audio Player. Say play to begin.");

    },
    "Play": function() {
        this.play(podcastURL, 0);
    },
    "AMAZON.PauseIntent": function() {
        this.stop();
    },
    "AMAZON.ResumeIntent": function () {
      var lastPlayed = this.load(userId);
      var offsetInMilliseconds = 0;
      if (lastPlayed !== null) {
          offsetInMilliseconds = lastPlayed.request.offsetInMilliseconds;
      }

      this.play(podcastURL, offsetInMilliseconds);
    },
    "AudioPlayer.PlaybackStopped": function () {
      this.save(userId, this.event);
    }
};

// Handles an incoming Alexa request


SimplePlayer.prototype.say = function (message, repromptMessage) {
    var response = {
        version: "1.0",
        response: {
            shouldEndSession: false,
            outputSpeech: {
                type: "SSML",
                ssml: "<speak> " + message + " </speak>"
            },
            reprompt: {
                outputSpeech: {
                    type: "SSML",
                    ssml: "<speak> " + message + " </speak>"
                }
            }
        }
    }
    this.context.succeed(response);
};

/**
 * Plays a particular track, from specific offset
 * @param audioURL The URL to play
 * @param offsetInMilliseconds The point from which to play - we set this to something other than zero when resuming
 */
SimplePlayer.prototype.play = function (audioURL, offsetInMilliseconds) {
    var response = {
        version: "1.0",
        response: {
            shouldEndSession: true,
            directives: [
                {
                    type: "AudioPlayer.Play",
                    playBehavior: "REPLACE_ALL", // Setting to REPLACE_ALL means that this track will start playing immediately
                    audioItem: {
                        stream: {
                            url: audioURL,
                            token: "0", // Unique token for the track - needed when queueing multiple tracks
                            expectedPreviousToken: null, // The expected previous token - when using queues, ensures safety
                            offsetInMilliseconds: offsetInMilliseconds
                        }
                    }
                }
            ]
        }
    }

    this.context.succeed(response);
};

// Stops the playback of Audio
SimplePlayer.prototype.stop = function () {
    var response = {
        version: "1.0",
        response: {
            shouldEndSession: true,
            directives: [
                {
                    type: "AudioPlayer.Stop"
                }
            ]
        }
    }

    this.context.succeed(response);
};

// Saves information into our super simple, not-production-grade cache
SimplePlayer.prototype.save = function (userId, state) {
    console.log("Save: " + userId);
    stateByUser[userId] = state;
};

// Load information from our super simple, not-production-grade cache
SimplePlayer.prototype.load = function (userId) {
    console.log("Load: " + userId);
    var state = null;
    if (userId in stateByUser) {
        state = stateByUser[userId];
        console.log("Loaded " + userId + " State: " + state);
    }
    return state;
};

我添加了alexa-sdk并更改了exports.handler和simplePlayer.prototype.handler()。 有什么想法,为什么它不工作?

提前致谢

我实际创建了你引用的项目。 很高兴你发现它很有用。

在重新分解项目时,您将其从原型样式的JS对象更改为对象文字。 两者都是可行的方法,但是当保持特定请求的状态(特别是事件和上下文字段)时,对象文字成为问题。

它还意味着项目中定义的原型方法不能从对象文字定义中获得。 您需要实例化SimplePlayer(通过调用new SimplePlayer(event, context) ),然后才能获得它们。

如果您想更好地理解这些方法之间的权衡,可以在这里阅读:
对象文字与构造函数+原型

以下是使用与我的项目一致的Alexa SDK的示例。 它将“LaunchRequest”函数定义为原型函数,而不仅仅是属性:

SimplePlayer.prototype.LaunchRequest = function () {
    this.emit(":tell", "Welcome to the Simple Audio Player. Say play to begin.");
};

您还需要确保实例化SimplePlayer(不仅仅是引用它)。 注册时,它应如下所示:

alexa.registerHandlers(new SimplePlayer(event, context));

希望有道理,祝你好运! 让我知道它是怎么回事(我总是可以通过https://gitter.im/bespoken/bst与我联系

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM