使用Nodejs BOT SDK开发视频播放技能示例代码
DuerOS-王超 发布于2018-11-17 16:47 浏览:1268 回复:42
5
收藏

视频播放技能依次播放列表中的视频,并支持“暂停”,“继续”,“上一个”,“下一个”等常用视频指令。

意图配置:

示例代码:

const Bot = require('bot-sdk');
const privateKey = require('./rsaKeys.js').privateKey;
const player = Bot.Directive.VideoPlayer.Play;
let curIndex = 0;
const videoList = [
    'url_1',
    'url_2'
];

class InquiryBot extends Bot {
    constructor(postData) {
        super(postData);

        this.addLaunchHandler(() => {
            this.waitAnswer();
            this.setExpectSpeech(false);
            let directive = this.getVideoPlayer(videoList[curIndex], curIndex);
            let playerInfo = this.getPlayerInfo(curIndex);
            return {
                directives: [directive, playerInfo],
                outputSpeech: '欢迎进入视频播放。'
            };
        });

        this.addSessionEndedHandler(() => {
            this.endSession();
            return {
                outputSpeech: '再见!'
            };
        });

        this.addIntentHandler('ai.dueros.common.continue_intent', () => {
            this.waitAnswer();
            this.setExpectSpeech(false);
            let offset = this.getSessionAttribute('offsetInMilliSeconds');
            let directive = this.getVideoPlayer(videoList[curIndex], curIndex);
            let playerInfo = this.getPlayerInfo(curIndex);
            directive.setOffsetInMilliseconds(offset);
            return {
                directives: [directive, playerInfo],
            };
        });

        this.addIntentHandler('ai.dueros.common.next_intent', () => {
            this.waitAnswer();
            this.setExpectSpeech(false);
            curIndex++;
            if (curIndex >= videoList.length) {
                curIndex = 0;
            }
            let directive = this.getVideoPlayer(videoList[curIndex], curIndex);
            let playerInfo = this.getPlayerInfo(curIndex);
            return {
                directives: [directive, playerInfo],
            };
        });

        this.addIntentHandler('ai.dueros.common.previous_intent', () => {
            this.waitAnswer();
            this.setExpectSpeech(false);
            if (curIndex > 0) {
                curIndex--;
            }
            let directive = this.getVideoPlayer(videoList[curIndex], curIndex);
            let playerInfo = this.getPlayerInfo(curIndex);
            return {
                directives: [directive, playerInfo],
            };
        });

        this.addIntentHandler('start', () => {
            this.waitAnswer();
            this.setExpectSpeech(false);
            curIndex = 0;
            let directive = this.getVideoPlayer(videoList[curIndex], curIndex);
            let playerInfo = this.getPlayerInfo(curIndex);
            return {
                directives: [directive, playerInfo],
            };
        });

        this.addIntentHandler('ai.dueros.common.pause_intent', () => {
            this.waitAnswer();
            this.setExpectSpeech(false);
            let directive = new Bot.Directive.VideoPlayer.Stop();
            return {
                directives: [directive],
            };
        });

        this.addIntentHandler('ai.dueros.common.stop_intent', () => {
            this.waitAnswer();
            this.setExpectSpeech(false);
            let directive = new Bot.Directive.VideoPlayer.Stop();
            return {
                directives: [directive],
            };
        });

        this.addIntentHandler('ai.dueros.common.default_intent', () => {
            this.waitAnswer();
            return {
                outputSpeech: '请对我说开始或者继续来播放视频。您也可以跟我说退出来退出技能。'
            };
        });

        this.addEventListener('VideoPlayer.PlaybackStopped', function (event) {
            this.waitAnswer();
            this.setExpectSpeech(false);
            this.setSessionAttribute('offsetInMilliSeconds', event.offsetInMilliseconds);
            return {
                outputSpeech: '好的'
            };
        });

        this.addEventListener('VideoPlayer.PlaybackFinished', function (event) {
            this.waitAnswer();
            this.setExpectSpeech(false);
            curIndex++;
            if (curIndex >= videoList.length) {
                curIndex = 0;
            }
            let directive = this.getVideoPlayer(videoList[curIndex], curIndex);
            let playerInfo = this.getPlayerInfo(curIndex);
            return {
                directives: [directive, playerInfo]
            };
        });

        this.addEventListener('Form.ButtonClicked', function (event) {
            this.waitAnswer();
            this.setExpectSpeech(false);
            let buttonName = event.name;
            if (buttonName == 'NEXT') {
                curIndex++;
                if (curIndex >= videoList.length) {
                    curIndex = 0;
                }
                let directive = this.getVideoPlayer(videoList[curIndex], curIndex);
                let playerInfo = this.getPlayerInfo(curIndex);
                return {
                    directives: [directive, playerInfo],
                };
            } else if (buttonName == 'PREVIOUS') {
                if (curIndex > 0) {
                    curIndex--;
                }
                let directive = this.getVideoPlayer(videoList[curIndex], curIndex);
                let playerInfo = this.getPlayerInfo(curIndex);
                return {
                    directives: [directive, playerInfo],
                };
            }
        });

        this.addDefaultEventListener(function () {
            this.waitAnswer();
            this.setExpectSpeech(false);
        });
    }

    /**
     *  获取视频播放指令
     *
     *  @param {number} offset 歌曲播放的进度
     *  @return {Bot.Directive.VideoPlayer.Play} Play指令
     */
    getVideoPlayer(videoUrl, token) {
        let directive = new Bot.Directive.VideoPlayer.Play(videoUrl, player.REPLACE_ALL);
        directive.setToken(token.toString());
        return directive;
    }

    /**
     *  获取播放控制控件
     *
     *  @return {RenderVideoPlayerInfo} RenderVideoPlayerInfo
     */
    getPlayerInfo(token) {
        let playerInfo = new Bot.Directive.Display.RenderVideoPlayerInfo();
        playerInfo.addControl(new Bot.Directive.AudioPlayer.Control.PreviousButton());
        playerInfo.addControl(new Bot.Directive.AudioPlayer.Control.PlayPauseButton());
        playerInfo.addControl(new Bot.Directive.AudioPlayer.Control.NextButton());
        playerInfo.setToken(token.toString());
        return playerInfo;
    }
}

exports.handler = function (event, context, callback) {
    try {
        let b = new InquiryBot(event);
        // 0: debug  1: online
        b.botMonitor.setEnvironmentInfo(privateKey, 1);
        b.run().then(function (result) {
            callback(null, result);
        }).catch(callback);
    } catch (e) {
        callback(e);
    }
}
收藏
点赞
5
个赞
共42条回复 最后由wangwei8638回复于2018-12-11 16:44
#2hehung回复于2018-11-17

点赞

0
#3qipaiai回复于2018-11-18

赞,如果能使用音频、视频流形式就更完美了

0
#4njljx200778回复于2018-11-18

如何监听一个视频即将播放完毕?我想自动播放下一个

0
#5易伟回复于2018-11-18
#4 njljx200778回复
如何监听一个视频即将播放完毕?我想自动播放下一个
VideoPlayer.PlaybackFinished
0
#6njljx200778回复于2018-11-18
#5 易伟回复
[代码]

谢谢!

0
#7守望者lv回复于2018-11-20

这些接口有文档吗?我在视频里看到了接口的说明,但是没有找到对应的页面,有人可以提供一下吗?多谢!

0
#8DuerOS-王超回复于2018-11-20
#7 守望者lv回复
这些接口有文档吗?我在视频里看到了接口的说明,但是没有找到对应的页面,有人可以提供一下吗?多谢!
展开
0
#9_迁畅回复于2018-11-21

我的团长我的团是1个资源,需要把语音上一集/第N集/下一集转换为指令

比如:第5集转为指令ChoseEpisode,参数episodeNumber5,然后把指令ChoseEpisode和参数episodeNumber给视频播放客户端去执行

请问,怎么实现?

0
#10DuerOS-王超回复于2018-11-22
#9 _迁畅回复
我的团长我的团是1个资源,需要把语音上一集/第N集/下一集转换为指令 比如:第5集转为指令ChoseEpisode,参数episodeNumber5,然后把指令ChoseEpisode和参数episodeNumber给视频播放客户端去执行 请问,怎么实现?
展开

您这个可以设置一个意图,该意图的常用表达可以是“第5集”,“播放第5集”等等。然后对5这个槽位引入系统词典sys.number。意图被唤醒以后获取槽位值,返回相应播放指令。

您可以参照 https://dueros.baidu.com/forum/topic/show/293365 中对槽位的处理。

0
#11njljx200778回复于2018-11-26

那个触摸屏上面视频播放器的下一个、上一个和播放列表分别对应什么事件呢?

0
#12Dueross回复于2018-11-26
#11 njljx200778回复
那个触摸屏上面视频播放器的下一个、上一个和播放列表分别对应什么事件呢?
展开

建议多看文档 Form事件

0
#13易伟回复于2018-11-28

技能在小度在家上体验,技能不支持“上/下一个”“播放列表”等点击操作,需要支持,示例代码应该完善啊,要不然不给通过。

0
#14Dueross回复于2018-11-28
#13 易伟回复
技能在小度在家上体验,技能不支持“上/下一个”“播放列表”等点击操作,需要支持,示例代码应该完善啊,要不然不给通过。
展开

1、建议多看文档 Form事件

2、addEventListener注册Form对应事件回调方法,方法内通过event中name字段获取控件名, 之后处理自己的业务逻辑

3、伪代码:

this.addEventListener('Form.ButtonClicked', function(event){
    this.waitAnswer();
    this.setExpectSpeech(false);
    name = event.name;
    //判断控件名称 PLAY_PAUSE 暂停、PREVIOUS 上一首  更多事件类型详看文档FORM事件....
    //处理自己的业务
});

 

0
#15蓝兰兰111回复于2018-11-29
#5 易伟回复
[代码]

我添加了事件,但是播放完成没触发

0
#16DuerOS-王超回复于2018-11-30

更新了代码。在下发Play指令的同时,也同时下发Bot.Directive.Display.RenderVideoPlayerInfo指令。还增加了Form.ButtonClicked事件的处理。

另外需要注意,Play指令和RenderVideoPlayerInfo指令需要设置相同的Token才能正常工作。

0
#17njljx200778回复于2018-11-30

播放列表应该怎么获取和展现?

0
#18易伟回复于2018-11-30

点击菜单按钮并没有打开菜单

0
#19153******86回复于2018-12-01

审核不通过,过来看,才发现,刚刚示例代码有不少更新

0
#20forky回复于2018-12-01
原样使用,报错: 
"errorMessage": "Bot.Directive.Display.RenderVideoPlayerInfo is not a constructor", "errorType": "TypeError", "stackTrace": [ "at InquiryBot.getPlayerInfo (/var/task/index.js:181:26)", "at InquiryBot.addLaunchHandler (/var/task/index.js:19:35)", "at _intentHandler.set (/var/task/node_modules/bot-sdk/lib/Bot.js:128:28)", "at InquiryBot._intentDispatch (/var/task/node_modules/bot-sdk/lib/Bot.js:454:56)", "at InquiryBot._run (/var/task/node_modules/bot-sdk/lib/Bot.js:424:24)", "at InquiryBot.run (/var/task/node_modules/bot-sdk/lib/Bot.js:392:21)", "at exports.handler (/var/task/index.js:195:11)", "at invokeHandler (/var/runtime/lib/node_modules/@baidu/nodejs6-runtime/runtime.js:295:5)", "at CfcRuntime._handleMessage (/var/runtime/lib/node_modules/@baidu/nodejs6-runtime/runtime.js:143:13)", "at emitOne (events.js:96:13)"
1
#21forky回复于2018-12-01

另外也提供 用户点击视频列表按钮后展现列表的全部代码

0
TOP