1
0
Fork 0
mirror of https://github.com/jellyfin/jellyfin-web synced 2025-03-30 19:56:21 +00:00

Update voice components

This commit is contained in:
Tavares André 2016-02-17 07:58:07 +01:00
parent c6b15e3001
commit 984b49650e
14 changed files with 1613 additions and 449 deletions

View file

@ -0,0 +1,177 @@
#Emby Voice commands
Emby voice commands use json and regular expression to find corresponding commands.
With this solution the translation to other languages will be simplified and is fully compatible with regular expression for many programming languages.
###Json template :
```json
[
{
"group": "general",
"name": "General commands",
"defaultValues": {
"sourceid": "",
"deviceid": "",
"itemName": "",
"itemType": "",
"shuffle": false,
"filters": [],
"sortBy": "",
"sortOrder": "",
"limit": 100,
"category": ""
},
"items": [
{
"actionid": "show",
"sourceid": "movies",
"menuid" : "home",
"groupid" : "movie",
"deviceid": "displaymirroring",
"command": "(?<action>play|Listen to)\\s?(?<determiner1>my|me)?\\s?(?<source> music)\\s?(?<ArtistName>.*)?\\s?(?<deviceaction>on device|to device)\\s?(?<Devicename>.*)",
"altcommand": "(?<action>play|Listen to)\\s?(?<determiner1>my|me)?\\s?(?<source> music)\\s?(?<ArtistName>.*)?",
"itemName": "",
"itemType": "movie",
"shuffle": false,
"filters": [ ],
"sortBy": "",
"sortOrder": "Ascending",
"limit": 100,
"category": "",
"commandtemplates": [
"Show Movie based commands",
"Show Music based commands",
"Show Picture based commands",
"Show TV series based commands",
"Show general commands"
]
}
]
}
]
```
###Json hierarchy
>+ Group
- defaultValues
- Items
+ commandtemplates
###Json Description :
**Group**
>**groupid** : (mandatory) id of the group commands
>**name** : (mandatory) name of the group
**Items and defaultValues (mandatory)**
**actionid** : (mandatory) Liste of actions available
>- show
- play
- shuffle
- search
- control
- enable
- disable
- toggle
**sourceid** : (optional) source commands available
>- music
- movies
- tvseries
- livetv
- recordings
- latestepisodes
- home
- group
**menuid** : (optional) menu commands available
>- Commands for live TV
- livetv
- guide
- channels
- recordings
- scheduled
- series
- group
>- Commands for home menus
- home
- nextup
- favorites
- upcoming
- nowplaying
**groupid** : (optional) name of the group
You can define a group name specified in the json file
**deviceid** : (optional) devices commands available
>- displaymirroring
**Emby filters** : (optional)
>- itemName
- itemType
- shuffle : default value = false
- filters
- sortBy
- sortOrder
- limit : default value = 100
- category
**commandtemplates** (mandatory)
array : list of text commands
**command** : (mandatory)
regular expression used to filter commands
**Exemple :**
command: "(?<action>play|Listen to)\\s?(?<determiner1>my|me)?\\s?(?<source> music)\\s?(?<ArtistName>.*)?\\s?(?<deviceaction>on device|to device)\\s?(?<Devicename>.*)",
altcommand: "(?<action>play|Listen to)\\s?(?<determiner1>my|me)?\\s?(?<source> music)\\s?(?<ArtistName>.*)?",
####Regular expression description
```json
(?<action> or ?<MovieName>, etc) - are for defining watts is captured
my|me - indicate each of those words/phrases can be used
\\s? - is for spaces
(?<MovieName>.*)? - the ? at the end of the closing brackets represent an optional value
```
In the example below theses phrases can the match for an action
- Show my movies
- Show movies
- Display movies
- Go to movies
- etc.
**altcommand** : (optional)
alternate regular expression used to filter commands if the property **command** does not match
####Regular expression description
```json
?<action> or ?<MovieName>, etc - are for defining watts is captured
my|me - indicate each of those words/phrases can be used
\s? - is for spaces
(?<MovieName>.*)? - the ? at the end of the closing brackets represent an optional value
```
####Additional properties used by regular expression
>**action** : Linked to actionid
>**source** : Linked to sourceid
>**menu** : Linked to menuid
>**group** : Linked to groupid
>**device** : Linked to deviceid
>**determiner1 or determiner2 etc** : used just to capture words
>**moviename**
>**devicename**
>**songname**
>**artistname**
>**albumname**
>**seriename**
>**seasonname**
>**picturename**
>**authorname**

View file

@ -0,0 +1,11 @@

define([], function () {
return function (result) {
result.success = true;
if (result.properties.devicename)
MediaController.trySetActiveDeviceName(result.properties.devicename);
return;
}
});

View file

@ -0,0 +1,16 @@

define([], function () {
return function (result) {
result.success = true;
switch (result.item.deviceid) {
case 'displaymirroring':
MediaController.enableDisplayMirroring(false);
break;
default:
result.success = false;
return;
}
}
});

View file

@ -0,0 +1,16 @@

define([], function () {
return function (result) {
result.success = true;
switch (result.item.deviceid) {
case 'displaymirroring':
MediaController.enableDisplayMirroring(true);
break;
default:
result.success = false;
return;
}
}
});

View file

@ -0,0 +1,106 @@

define([], function () {
/// <summary> Play items. </summary>
/// <param name="items"> The items. </param>
/// <param name="shuffle"> The shuffle. </param>
/// <returns> . </returns>
function playItems(items, shuffle) {
if (shuffle) {
items = shuffleArray(items);
}
items = items.map(function (i) {
return i.Id;
});
if (items.length) {
MediaController.play({
ids: items
});
}
else {
Dashboard.alert({
message: Globalize.translate('MessageNoItemsFound')
});
}
}
/// <summary> Shuffle array. </summary>
/// <param name="array"> The array. </param>
/// <returns> . </returns>
function shuffleArray(array) {
var currentIndex = array.length, temporaryValue, randomIndex;
// While there remain elements to shuffle...
while (0 !== currentIndex) {
// Pick a remaining element...
randomIndex = Math.floor(Math.random() * currentIndex);
currentIndex -= 1;
// And swap it with the current element.
temporaryValue = array[currentIndex];
array[currentIndex] = array[randomIndex];
array[randomIndex] = temporaryValue;
}
return array;
}
return function (result) {
result.success = false;
var query = {
Limit: result.item.limit || 100,
UserId: result.userId,
ExcludeLocationTypes: "Virtual"
};
if (result.item.itemType) {
query.IncludeItemTypes = result.item.itemType;
}
if (result.item.sourceid === 'nextup') {
ApiClient.getNextUpEpisodes(query).then(function (queryResult) {
playItems(queryResult.Items, result.item.shuffle);
});
result.success = true;
return;
}
if (result.item.shuffle) {
result.item.sortBy = result.sortBy ? 'Random,' + result.item.sortBy : 'Random';
}
query.SortBy = result.item.sortBy;
query.SortOrder = result.item.sortOrder;
query.Recursive = true;
if (result.item.filters.indexOf('unplayed') !== -1) {
query.IsPlayed = false;
}
if (result.item.filters.indexOf('played') !== -1) {
query.IsPlayed = true;
}
if (result.item.filters.indexOf('favorite') !== -1) {
query.Filters = 'IsFavorite';
}
ApiClient.getItems(Dashboard.getCurrentUserId(), query).then(function (queryResult) {
playItems(queryResult.Items, result.item.shuffle);
});
result.success = true;
return;
}
});

View file

@ -0,0 +1,16 @@

define([], function () {
return function (result) {
result.success = true;
switch (result.item.deviceid) {
case 'displaymirroring':
MediaController.enableDisplayMirroring(false);
break;
default:
result.success = false;
return;
}
}
});

View file

@ -0,0 +1,93 @@

define([], function () {
return function (result) {
result.success = true;
switch (result.item.sourceid) {
case 'music':
Dashboard.navigate('music.html');
break;
case 'movies':
if (result.properties.movieName) {
//TODO: Find a way to display movie
var query = {
Limit: 1,
UserId: result.userId,
ExcludeLocationTypes: "Virtual"
};
if (result.item.itemType) {
query.IncludeItemTypes = result.item.itemType;
}
query.SearchTerm = result.properties.movieName;
ApiClient.getItems(Dashboard.getCurrentUserId(), query).then(function (queryResult) {
var s = queryResult[0];
});
}
else
Dashboard.navigate('movies.html');
break;
case 'tvseries':
Dashboard.navigate('tv.html');
break;
case 'livetv':
var act = result.item.menuid;
if (act) {
if (act.indexOf('livetv') != -1)
Dashboard.navigate('livetv.html?tab=0');
else if (act.indexOf('guide') != -1)
Dashboard.navigate('livetv.html?tab=1');
else if (act.indexOf('channels') != -1)
Dashboard.navigate('livetv.html?tab=2');
else if (act.indexOf('recordings') != -1)
Dashboard.navigate('livetv.html?tab=3');
else if (act.indexOf('scheduled') != -1)
Dashboard.navigate('livetv.html?tab=4');
else if (act.indexOf('series') != -1)
Dashboard.navigate('livetv.html?tab=5');
else
Dashboard.navigate('livetv.html?tab=0');
}
else
Dashboard.navigate('livetv.html?tab=0');
break;
case 'recordings':
Dashboard.navigate('livetv.html?tab=3');
break;
case 'latestepisodes':
Dashboard.navigate('tv.html?tab=1');
case 'home':
var act = result.item.menuid;
if (act) {
if (act.indexOf('home') != -1)
Dashboard.navigate('index.html');
else if (act.indexOf('nextup') != -1)
Dashboard.navigate('index.html?tab=2');
else if (act.indexOf('favorites') != -1)
Dashboard.navigate('index.html?tab=2');
else if (act.indexOf('upcoming') != -1)
Dashboard.navigate('index.html?tab=3');
else if (act.indexOf('nowplaying') != -1)
Dashboard.navigate('nowplaying.html');
else
Dashboard.navigate('index.html');
}
else
Dashboard.navigate('index.html');
case 'group':
break;
default:
result.success = false;
return;
}
}
});

View file

@ -0,0 +1,16 @@

define([], function () {
return function (result) {
result.success = true;
switch (result.item.deviceid) {
case 'displaymirroring':
MediaController.toggleDisplayMirroring();
break;
default:
result.success = false;
return;
}
}
});

View file

@ -0,0 +1,330 @@
[
{
"groupid": "general",
"name": "General commands",
"items": [
{
"actionid": "show",
"sourceid": "group",
"groupid": "movie",
"command": "(?<action>show|display|view)\\s?(?<source>Movie)?\\s?(?<text>based commands)",
"commandtemplates": [ "Show Movie based commands" ]
},
{
"actionid": "show",
"sourceid": "group",
"groupid": "music",
"command": "(?<action>show|display|view)\\s?(?<source>Music)?\\s?(?<text>based commands)",
"commandtemplates": [ "Show Music based commands" ]
},
{
"actionid": "show",
"sourceid": "group",
"groupid": "picture",
"command": "(?<action>show|display|view)\\s?(?<source>Picture)?\\s?(?<text>based commands)",
"commandtemplates": [ "Show Picture based commands" ]
},
{
"actionid": "show",
"sourceid": "group",
"groupid": "tvseries",
"command": "(?<action>show|display|view)\\s?(?<source>TV series)?\\s?(?<text>based commands)",
"commandtemplates": [ "Show TV series based commands" ]
},
{
"actionid": "show",
"sourceid": "group",
"groupid": "home",
"command": "(?<action>show|display|view)\\s?(?<source>home page)?\\s?(?<text>based commands)",
"commandtemplates": [ "Show home page based commands" ]
},
{
"actionid": "show",
"sourceid": "group",
"groupid": "general",
"command": "(?<action>show|display|view)\\s?(?<source>general)?\\s?(?<text>group commands)",
"commandtemplates": [ "Show general group commands" ]
},
{
"actionid": "show",
"sourceid": "group",
"groupid": "devices",
"command": "(?<action>show|display|view)\\s?(?<source>devices)?\\s?(?<text>based commands)",
"commandtemplates": [ "Show devices based commands" ]
},
{
"actionid": "show",
"sourceid": "group",
"groupid": "livetv",
"command": "(?<action>show|display|view)\\s?(?<source>live tv)?\\s?(?<text>based commands)",
"commandtemplates": [ "Show Live TV based commands" ]
}
]
},
{
"groupid": "home",
"name": "Home commands",
"items": [
{
"actionid": "show",
"sourceid": "home",
"menuid": "home",
"command": "(?<action> show|display|view)\\s?(?<menu>home)",
"commandtemplates": [ "Show home" ]
},
{
"actionid": "show",
"sourceid": "home",
"menuid": "nextup",
"command": "(?<action> show|display|view)\\s?(?<menu>next up)",
"commandtemplates": [ "Show next up" ]
},
{
"actionid": "show",
"sourceid": "home",
"menuid": "favorites",
"command": "(?<action> show|display|view)\\s?(?<menu>favorites)",
"commandtemplates": [ "Show favorites" ]
},
{
"actionid": "show",
"sourceid": "home",
"menuid": "upcoming",
"command": "(?<action> show|display|view)\\s?(?<menu>upcoming)",
"commandtemplates": [ "Show upcoming" ]
},
{
"actionid": "show",
"sourceid": "home",
"menuid": "nowplaying",
"command": "(?<action> show|display|view)\\s?(?<menu>now playing)",
"commandtemplates": [ "Show now playing" ]
}
]
},
{
"groupid": "movie",
"name": "Movie based commands",
"defaultValues": {
"sourceid": "movies",
"itemType": "Movie",
"filters": [ ],
"sortBy": "",
"sortOrder": "Ascending"
},
"items": [
{
"actionid": "show",
"sourceid": "movies",
"command": "(?<action>show|display|go to|view)\\s?(?<determiner1>my|me)?\\s?(?<source>movies)\\s?(?<MovieName>.*)?",
"altcommand": "(?<action>show|display|go to|view)\\s?(?<determiner1>the)?\\s?(?<source>movie)\\s?(?<MovieName>.*)?",
"itemName": "",
"commandtemplates": [
"Show movies",
"Show my movies",
"Show the movie [movie name]"
]
},
{
"actionid": "play",
"sourceid": "movies",
"command": "(?<action>play|Listen to)\\s?(?<determiner1>my|me)?\\s?(?<source> music)\\s?(?<ArtistName>.*)?\\s?(?<deviceaction>on device|to device)\\s?(?<Devicename>.*)",
"altcommand": "(?<action>play|Listen to)\\s?(?<determiner1>my|me)?\\s?(?<source> music)\\s?(?<ArtistName>.*)?",
"itemName": "",
"itemType": "Audio",
"shuffle": false,
"filters": [ ],
"sortBy": "",
"sortOrder": "Ascending",
"commandtemplates": [
"Play music",
"Play my music",
"Listen to my music "
]
}
]
},
{
"groupid": "music",
"name": "Music based commands",
"defaultValues": {
"itemName": "",
"itemType": "Audio",
"shuffle": false,
"filters": [ ],
"sortBy": "",
"sortOrder": "Ascending"
},
"items": [
{
"actionid": "show",
"sourceid": "music",
"command": "(?<action>show|display|go to|view)\\s?(?<determiner1>my|me)?\\s?(?<source>(music|songs))\\s?(?<SongName>.*)?",
"commandtemplates": [
"Show music",
"Show my music",
"Show my songs"
]
},
{
"actionid": "play",
"sourceid": "music",
"command": "(?<action>play|Listen to)\\s?(?<determiner1>my|me)?\\s?(?<source> music)\\s?(?<ArtistName>.*)?\\s?(?<deviceaction>on device|to device)\\s?(?<Devicename>.*)",
"altcommand": "(?<action>play|Listen to)\\s?(?<determiner1>my|me)?\\s?(?<source> music)\\s?(?<ArtistName>.*)?",
"itemName": "",
"commandtemplates": [
"Play music",
"Play my music",
"Listen to my music "
]
},
{
"actionid": "shuffle",
"sourceid": "music",
"command": "(?<action>shuffle)\\s?(?<determiner1>my|me)?\\s?(?<source> music)\\s?(?<ArtistName>.*)?\\s?(?<deviceaction>on device|to device)\\s?(?<Devicename>.*)",
"altcommand": "(?<action>shuffle)\\s?(?<determiner1>my|me)?\\s?(?<source> music)\\s?(?<ArtistName>.*)?",
"shuffle": true,
"commandtemplates": [
"Play music",
"Play my music",
"Listen to my music "
]
}
]
},
{
"groupid": "tvseries",
"name": "TV series based commands",
"defaultValues": {
"itemType": "Series",
"filters": [ ],
"sortBy": "",
"sortOrder": "Ascending"
},
"items": [
{
"actionid": "show",
"sourceid": "tvseries",
"command": "(?<action>show|display|go to|view)\\s?(?<determiner1>my|me)?\\s?(?<source>(tv series))\\s?(?<SerieName>.*)?",
"commandtemplates": [
"Show tv series",
"Show my tv series"
]
},
{
"actionid": "play",
"sourceid": "nextup",
"command": "(?<action>play|Listen to)\\s?(?<source> next up)\\s?(?<deviceaction>on device|to device)\\s?(?<Devicename>.*)",
"altcommand": "(?<action>play|Listen to)\\s?(?<source> next up)",
"commandtemplates": [ "Play next up" ]
},
{
"actionid": "play",
"sourceid": "latestepisodes",
"command": "(?<action>play)\\s?(?<determiner1>my|me)?\\s?(?<text>latest episodes)\\s?(?<deviceaction>on device|to device)\\s?(?<Devicename>.*)",
"altcommand": "(?<action>play)\\s?(?<determiner1>my|me)?\\s?(?<text>latest episodes)",
"commandtemplates": [ "Play my latest episodes" ]
}
]
},
{
"groupid": "livetv",
"name": "Live TV based commands",
"items": [
{
"actionid": "show",
"sourceid": "livetv",
"menuid": "suggestions",
"command": "(?<action>show|display|go to|view)\\s?(?<determiner1>my|me)?\\s?(?<source>Live tv|live tv suggestions)",
"commandtemplates": [ "Show live tv" ]
},
{
"actionid": "show",
"sourceid": "livetv",
"menuid": "guide",
"command": "(?<action>show|display|go to|view)\\s?(?<determiner1>my|me)?\\s?(?<source>Live tv guide)",
"commandtemplates": [ "Show live tv guide" ]
},
{
"actionid": "show",
"sourceid": "livetv",
"menuid": "channels",
"command": "(?<action>show|display|go to|view)\\s?(?<determiner1>my|me)?\\s?(?<source>Live tv channels)",
"commandtemplates": [ "Show live tv channels" ]
},
{
"actionid": "show",
"sourceid": "livetv",
"menuid": "recordings",
"command": "(?<action>show|display|go to|view)\\s?(?<determiner1>my|me)?\\s?(?<source>Live tv recordings)",
"commandtemplates": [ "Show live tv recordings" ]
},
{
"actionid": "show",
"sourceid": "livetv",
"menuid": "scheduled",
"command": "(?<action>show|display|go to|view)\\s?(?<determiner1>my|me)?\\s?(?<source>Live tv scheduled)",
"commandtemplates": [ "Show live tv scheduled" ]
},
{
"actionid": "show",
"sourceid": "livetv",
"menuid": "series",
"command": "(?<action>show|display|go to|view)\\s?(?<determiner1>my|me)?\\s?(?<source>Live tv series)",
"commandtemplates": ["Show live tv series"]
}
]
},
{
"groupid": "picture",
"name": "Picture based commands",
"defaultValues": {
"itemType": "Picture",
"shuffle": false,
"filters": [ ],
"sortBy": "",
"sortOrder": "Ascending"
},
"items": [
{
"actionid": "show",
"sourceid": "tvseries",
"command": "(?<action>show|display|go to|view)\\s?(?<determiner1>my|me)?\\s?(?<source>pictures)",
"commandtemplates": [
"Show pictures",
"Show my pictures"
]
}
]
},
{
"groupid": "devices",
"name": "Devices based commands",
"items": [
{
"actionid": "enable",
"deviceid": "displaymirroring",
"command": "(?<action> enable|turn on)\\s?(?<device>display mirroring)",
"commandtemplates": [ "Turn on display mirroring", "Enable display mirroring" ]
},
{
"actionid": "disable",
"deviceid": "displaymirroring",
"command": "(?<action> disable|turn off)\\s?(?<device>display mirroring)",
"commandtemplates": [ "Turn off display mirroring", "Disable display mirroring" ]
},
{
"actionid": "toggle",
"deviceid": "displaymirroring",
"command": "(?<action>toggle)\\s?(?<device>display mirroring)",
"commandtemplates": [ "Toggle display mirroring" ]
},
{
"actionid": "control",
"command": "(?<action>control)\\s?(?<Devicename>.*)",
"commandtemplates": [ "Control [Device Name]" ]
}
]
}
]

View file

@ -0,0 +1,330 @@
[
{
"groupid": "general",
"name": "General commands",
"items": [
{
"actionid": "show",
"sourceid": "group",
"groupid": "movie",
"command": "(?<action>show|display|view)\\s?(?<source>Movie)?\\s?(?<text>based commands)",
"commandtemplates": [ "Show Movie based commands" ]
},
{
"actionid": "show",
"sourceid": "group",
"groupid": "music",
"command": "(?<action>show|display|view)\\s?(?<source>Music)?\\s?(?<text>based commands)",
"commandtemplates": [ "Show Music based commands" ]
},
{
"actionid": "show",
"sourceid": "group",
"groupid": "picture",
"command": "(?<action>show|display|view)\\s?(?<source>Picture)?\\s?(?<text>based commands)",
"commandtemplates": [ "Show Picture based commands" ]
},
{
"actionid": "show",
"sourceid": "group",
"groupid": "tvseries",
"command": "(?<action>show|display|view)\\s?(?<source>TV series)?\\s?(?<text>based commands)",
"commandtemplates": [ "Show TV series based commands" ]
},
{
"actionid": "show",
"sourceid": "group",
"groupid": "home",
"command": "(?<action>show|display|view)\\s?(?<source>home page)?\\s?(?<text>based commands)",
"commandtemplates": [ "Show home page based commands" ]
},
{
"actionid": "show",
"sourceid": "group",
"groupid": "general",
"command": "(?<action>show|display|view)\\s?(?<source>general)?\\s?(?<text>group commands)",
"commandtemplates": [ "Show general group commands" ]
},
{
"actionid": "show",
"sourceid": "group",
"groupid": "devices",
"command": "(?<action>show|display|view)\\s?(?<source>devices)?\\s?(?<text>based commands)",
"commandtemplates": [ "Show devices based commands" ]
},
{
"actionid": "show",
"sourceid": "group",
"groupid": "livetv",
"command": "(?<action>show|display|view)\\s?(?<source>live tv)?\\s?(?<text>based commands)",
"commandtemplates": [ "Show Live TV based commands" ]
}
]
},
{
"groupid": "home",
"name": "Home commands",
"items": [
{
"actionid": "show",
"sourceid": "home",
"menuid": "home",
"command": "(?<action> show|display|view)\\s?(?<menu>home)",
"commandtemplates": [ "Show home" ]
},
{
"actionid": "show",
"sourceid": "home",
"menuid": "nextup",
"command": "(?<action> show|display|view)\\s?(?<menu>next up)",
"commandtemplates": [ "Show next up" ]
},
{
"actionid": "show",
"sourceid": "home",
"menuid": "favorites",
"command": "(?<action> show|display|view)\\s?(?<menu>favorites)",
"commandtemplates": [ "Show favorites" ]
},
{
"actionid": "show",
"sourceid": "home",
"menuid": "upcoming",
"command": "(?<action> show|display|view)\\s?(?<menu>upcoming)",
"commandtemplates": [ "Show upcoming" ]
},
{
"actionid": "show",
"sourceid": "home",
"menuid": "nowplaying",
"command": "(?<action> show|display|view)\\s?(?<menu>now playing)",
"commandtemplates": [ "Show now playing" ]
}
]
},
{
"groupid": "movie",
"name": "Movie based commands",
"defaultValues": {
"sourceid": "movies",
"itemType": "Movie",
"filters": [ ],
"sortBy": "",
"sortOrder": "Ascending"
},
"items": [
{
"actionid": "show",
"sourceid": "movies",
"command": "(?<action>show|display|go to|view)\\s?(?<determiner1>my|me)?\\s?(?<source>movies)\\s?(?<MovieName>.*)?",
"altcommand": "(?<action>show|display|go to|view)\\s?(?<determiner1>the)?\\s?(?<source>movie)\\s?(?<MovieName>.*)?",
"itemName": "",
"commandtemplates": [
"Show movies",
"Show my movies",
"Show the movie [movie name]"
]
},
{
"actionid": "play",
"sourceid": "movies",
"command": "(?<action>play|Listen to)\\s?(?<determiner1>my|me)?\\s?(?<source> music)\\s?(?<ArtistName>.*)?\\s?(?<deviceaction>on device|to device)\\s?(?<Devicename>.*)",
"altcommand": "(?<action>play|Listen to)\\s?(?<determiner1>my|me)?\\s?(?<source> music)\\s?(?<ArtistName>.*)?",
"itemName": "",
"itemType": "Audio",
"shuffle": false,
"filters": [ ],
"sortBy": "",
"sortOrder": "Ascending",
"commandtemplates": [
"Play music",
"Play my music",
"Listen to my music "
]
}
]
},
{
"groupid": "music",
"name": "Music based commands",
"defaultValues": {
"itemName": "",
"itemType": "Audio",
"shuffle": false,
"filters": [ ],
"sortBy": "",
"sortOrder": "Ascending"
},
"items": [
{
"actionid": "show",
"sourceid": "music",
"command": "(?<action>show|display|go to|view)\\s?(?<determiner1>my|me)?\\s?(?<source>(music|songs))\\s?(?<SongName>.*)?",
"commandtemplates": [
"Show music",
"Show my music",
"Show my songs"
]
},
{
"actionid": "play",
"sourceid": "music",
"command": "(?<action>play|Listen to)\\s?(?<determiner1>my|me)?\\s?(?<source> music)\\s?(?<ArtistName>.*)?\\s?(?<deviceaction>on device|to device)\\s?(?<Devicename>.*)",
"altcommand": "(?<action>play|Listen to)\\s?(?<determiner1>my|me)?\\s?(?<source> music)\\s?(?<ArtistName>.*)?",
"itemName": "",
"commandtemplates": [
"Play music",
"Play my music",
"Listen to my music "
]
},
{
"actionid": "shuffle",
"sourceid": "music",
"command": "(?<action>shuffle)\\s?(?<determiner1>my|me)?\\s?(?<source> music)\\s?(?<ArtistName>.*)?\\s?(?<deviceaction>on device|to device)\\s?(?<Devicename>.*)",
"altcommand": "(?<action>shuffle)\\s?(?<determiner1>my|me)?\\s?(?<source> music)\\s?(?<ArtistName>.*)?",
"shuffle": true,
"commandtemplates": [
"Play music",
"Play my music",
"Listen to my music "
]
}
]
},
{
"groupid": "tvseries",
"name": "TV series based commands",
"defaultValues": {
"itemType": "Series",
"filters": [ ],
"sortBy": "",
"sortOrder": "Ascending"
},
"items": [
{
"actionid": "show",
"sourceid": "tvseries",
"command": "(?<action>show|display|go to|view)\\s?(?<determiner1>my|me)?\\s?(?<source>(tv series))\\s?(?<SerieName>.*)?",
"commandtemplates": [
"Show tv series",
"Show my tv series"
]
},
{
"actionid": "play",
"sourceid": "nextup",
"command": "(?<action>play|Listen to)\\s?(?<source> next up)\\s?(?<deviceaction>on device|to device)\\s?(?<Devicename>.*)",
"altcommand": "(?<action>play|Listen to)\\s?(?<source> next up)",
"commandtemplates": [ "Play next up" ]
},
{
"actionid": "play",
"sourceid": "latestepisodes",
"command": "(?<action>play)\\s?(?<determiner1>my|me)?\\s?(?<text>latest episodes)\\s?(?<deviceaction>on device|to device)\\s?(?<Devicename>.*)",
"altcommand": "(?<action>play)\\s?(?<determiner1>my|me)?\\s?(?<text>latest episodes)",
"commandtemplates": [ "Play my latest episodes" ]
}
]
},
{
"groupid": "livetv",
"name": "Live TV based commands",
"items": [
{
"actionid": "show",
"sourceid": "livetv",
"menuid": "suggestions",
"command": "(?<action>show|display|go to|view)\\s?(?<determiner1>my|me)?\\s?(?<source>Live tv|live tv suggestions)",
"commandtemplates": [ "Show live tv" ]
},
{
"actionid": "show",
"sourceid": "livetv",
"menuid": "guide",
"command": "(?<action>show|display|go to|view)\\s?(?<determiner1>my|me)?\\s?(?<source>Live tv guide)",
"commandtemplates": [ "Show live tv guide" ]
},
{
"actionid": "show",
"sourceid": "livetv",
"menuid": "channels",
"command": "(?<action>show|display|go to|view)\\s?(?<determiner1>my|me)?\\s?(?<source>Live tv channels)",
"commandtemplates": [ "Show live tv channels" ]
},
{
"actionid": "show",
"sourceid": "livetv",
"menuid": "recordings",
"command": "(?<action>show|display|go to|view)\\s?(?<determiner1>my|me)?\\s?(?<source>Live tv recordings)",
"commandtemplates": [ "Show live tv recordings" ]
},
{
"actionid": "show",
"sourceid": "livetv",
"menuid": "scheduled",
"command": "(?<action>show|display|go to|view)\\s?(?<determiner1>my|me)?\\s?(?<source>Live tv scheduled)",
"commandtemplates": [ "Show live tv scheduled" ]
},
{
"actionid": "show",
"sourceid": "livetv",
"menuid": "series",
"command": "(?<action>show|display|go to|view)\\s?(?<determiner1>my|me)?\\s?(?<source>Live tv series)",
"commandtemplates": ["Show live tv series"]
}
]
},
{
"groupid": "picture",
"name": "Picture based commands",
"defaultValues": {
"itemType": "Picture",
"shuffle": false,
"filters": [ ],
"sortBy": "",
"sortOrder": "Ascending"
},
"items": [
{
"actionid": "show",
"sourceid": "tvseries",
"command": "(?<action>show|display|go to|view)\\s?(?<determiner1>my|me)?\\s?(?<source>pictures)",
"commandtemplates": [
"Show pictures",
"Show my pictures"
]
}
]
},
{
"groupid": "devices",
"name": "Devices based commands",
"items": [
{
"actionid": "enable",
"deviceid": "displaymirroring",
"command": "(?<action> enable|turn on)\\s?(?<device>display mirroring)",
"commandtemplates": [ "Turn on display mirroring", "Enable display mirroring" ]
},
{
"actionid": "disable",
"deviceid": "displaymirroring",
"command": "(?<action> disable|turn off)\\s?(?<device>display mirroring)",
"commandtemplates": [ "Turn off display mirroring", "Disable display mirroring" ]
},
{
"actionid": "toggle",
"deviceid": "displaymirroring",
"command": "(?<action>toggle)\\s?(?<device>display mirroring)",
"commandtemplates": [ "Toggle display mirroring" ]
},
{
"actionid": "control",
"command": "(?<action>control)\\s?(?<Devicename>.*)",
"commandtemplates": [ "Control [Device Name]" ]
}
]
}
]

View file

@ -0,0 +1,241 @@
// <date>09.10.2015</date>
// <summary>grammarprocessor class</summary>
define([], function () {
/// <summary> The named register exponent. </summary>
var NamedRegExp = function (pattern, string) {
pattern = pattern.toString();
var regexp = [];
var groupRX = /\(\?\<(.*?)\>\s?(.*?)\)/i;
while (groupRX.test(pattern)) {
var match = groupRX.exec(pattern);
regexp.push({
name: match[1].trim().toLowerCase(),
pattern: match[2].trim().toLowerCase(),
value: null,
title: ''
});
pattern = pattern.replace(groupRX, '(' + match[2].trim() + ')');
}
var finalMatch = (new RegExp(pattern, "i")).exec(string);
if (finalMatch) {
for (var i = 0, len = regexp.length; i < len; i++) {
if (finalMatch[(i + 1)] !== false) {
var mth = finalMatch[(i + 1)];
if (mth)
mth = mth.trim().toLowerCase();
regexp[i].value = mth;
}
}
}
else
regexp = null;
return regexp;
};
/// <summary> Processcommands. </summary>
/// <param name="text"> The text. </param>
/// <param name="commandgroups"> The command groups. </param>
/// <returns> . </returns>
function processcommands(text, commandgroups) {
var result = {
groupid: '',
name: '',
item: {
actionid: '',
groupid: '',
sourceid: '',
menuid: '',
deviceid: '',
itemName: '',
itemType: '',
shuffle: false,
filters: [],
sortBy: '',
sortOrder: '',
item: 100,
category: '',
usedefaultvalues: true
},
defaultValues: {
sourceid: '',
deviceid: '',
itemName: '',
itemType: '',
shuffle: false,
filters: [],
sortBy: '',
sortOrder: '',
limit: 100,
category: ''
},
properties: {
movieName: null,
devicename: null,
songName: null,
artistName: null,
albumName: null,
serieName: null,
seasonName: null,
pictureName: null,
authorname: null,
},
command: null,
text: text,
userId: Dashboard.getCurrentUserId(),
success: false
};
var isvalid = false;
commandgroups.map(function (group) {
if (isvalid)
return;
if (group.defaultValues && group.defaultValues.length > 0) {
group.defaultValues.map(function (item) {
});
}
if (group.items && group.items.length > 0) {
group.items.map(function (item) {
var regex = NamedRegExp(item.command, text);
if (!regex && item.altcommand)
regex = NamedRegExp(item.altcommand, text)
if (regex && regex.length > 0) {
//Group data
if (group.groupid) result.groupid = group.groupid;
if (group.name) result.name = group.name;
if (group.defaultValues) {
result.defaultValues.sourceid = group.defaultValues.sourceid || result.defaultValues.sourceid;
result.defaultValues.deviceid = group.defaultValues.deviceid || result.defaultValues.deviceid;
result.defaultValues.itemName = group.defaultValues.itemName || result.defaultValues.itemName;
result.defaultValues.itemType = group.defaultValues.itemType || result.defaultValues.itemType;
result.defaultValues.shuffle = group.defaultValues.shuffle || result.defaultValues.shuffle;
result.defaultValues.filters = group.defaultValues.filters || result.defaultValues.filters;
result.defaultValues.sortBy = group.defaultValues.sortBy || result.defaultValues.sortBy;
result.defaultValues.sortOrder = group.defaultValues.sortOrder || result.defaultValues.sortOrder;
result.defaultValues.limit = group.defaultValues.limit || result.defaultValues.limit;
result.defaultValues.category = group.defaultValues.category || result.defaultValues.category;
}
if (group.name) result.name = group.name;
//Item data
var usegroupDefault = checkItemProperty(item.usedefaultvalues, result.item.usedefaultvalues);
result.item.usedefaultvalues = usegroupDefault;
result.item.actionid = checkItemProperty(item.actionid, result.item.actionid);
result.item.groupid = checkItemProperty(item.groupid, result.item.groupid);
result.item.menuid = checkItemProperty(item.menuid, result.item.menuid);
result.item.sourceid = checkItemProperty(item.sourceid, result.item.sourceid, usegroupDefault, result.defaultValues.sourceid);
result.item.deviceid = checkItemProperty(item.deviceid, result.item.deviceid, usegroupDefault, result.defaultValues.deviceid);
result.item.itemName = checkItemProperty(item.itemName, result.item.itemName, usegroupDefault, result.defaultValues.itemName);
result.item.itemType = checkItemProperty(item.itemType, result.item.itemType, usegroupDefault, result.defaultValues.itemType);
result.item.shuffle = checkItemProperty(item.shuffle, result.item.shuffle, usegroupDefault, result.defaultValues.shuffle);
result.item.filters = checkItemProperty(item.filters, result.item.filters, usegroupDefault, result.defaultValues.filters);
result.item.sortBy = checkItemProperty(item.sortBy, result.item.sortBy, usegroupDefault, result.defaultValues.sortBy);
result.item.sortOrder = checkItemProperty(item.sortOrder, result.item.sortOrder, usegroupDefault, result.defaultValues.sortOrder);
result.item.limit = checkItemProperty(item.limit, result.item.limit, usegroupDefault, result.defaultValues.limit);
result.command = item;
regex.map(function (regresult) {
switch (regresult.name) {
case 'moviename':
result.properties.movieName = regresult.value;
break;
case 'devicename':
result.properties.devicename = regresult.value;
break;
case 'songname':
result.properties.songName = regresult.value;
break;
case 'artistname':
result.properties.artistName = regresult.value;
break;
case 'albumname':
result.properties.albumName = regresult.value;
break;
case 'seriename':
result.properties.serieName = regresult.value;
break;
case 'seasonname':
result.properties.seasonName = regresult.value;
break;
case 'picturename':
result.properties.pictureName = regresult.value;
break;
case 'authorname':
result.properties.authorname = regresult.value;
break;
}
if (result.text)
result.text = result.text.replace(regresult.value, '').trim();
});
isvalid = true;
}
if (isvalid)
return;
});
}
});
return result;
}
/// <summary> Gets RegEx property. </summary>
/// <param name="actions"> The actions. </param>
/// <param name="property"> The property. </param>
/// <returns> The RegEx property. </returns>
function getRegExProperty(actions, property) {
var idx = -1;
idx = actions.map(function (e) { return e.name; }).indexOf(name);
if (idx > -1)
return actions[idx];
else
return null;
}
/// <summary> Check item property. </summary>
/// <param name="property"> The property. </param>
/// <param name="itemDefaultValue"> The item default value. </param>
/// <param name="useGroupDefaultValue"> The use group default value. </param>
/// <param name="groupDefaultValue"> The group default value. </param>
/// <returns> . </returns>
function checkItemProperty(property, itemDefaultValue, useGroupDefaultValue, groupDefaultValue) {
if (property)
return property;
if (useGroupDefaultValue && groupDefaultValue)
return groupDefaultValue;
return itemDefaultValue;
}
return function (commandgroups, text) {
if (commandgroups) {
var result = processcommands(text, commandgroups);
console.log(text);
console.log(commandgroups);
}
return result;
}
});

View file

@ -1,244 +0,0 @@
define([], function () {
function parseTextInternal(text) {
var result = {
action: '',
itemName: '',
itemType: '',
category: '',
filters: [],
removeWords: [],
sortby: '',
sortorder: 'Ascending',
limit: null,
userId: Dashboard.getCurrentUserId()
};
var textLower = text.toLowerCase();
var words = text.toLowerCase().split(' ');
var displayWords = [
'show',
'pull up',
'display',
'go to',
'view'
];
if (displayWords.filter(function (w) { return textLower.indexOf(w) == 0; }).length) {
if (words.indexOf('guide') != -1) {
result.action = 'show';
result.category = 'tvguide';
}
if (words.indexOf('recordings') != -1) {
result.action = 'show';
result.category = 'recordings';
}
result.removeWords = displayWords;
return result;
}
var searchWords = [
'search',
'search for',
'find',
'query'
];
if (searchWords.filter(function (w) { return textLower.indexOf(w) == 0; }).length) {
// Search
result.action = 'search';
result.removeWords = searchWords;
return result;
}
var playWords = [
'play',
'watch'
];
if (playWords.filter(function (w) { return textLower.indexOf(w) == 0; }).length) {
// Play
result.action = 'play';
result.removeWords = playWords;
return result;
}
var controlWords = [
'use',
'control'
];
if (controlWords.filter(function (w) { return textLower.indexOf(w) == 0; }).length) {
// Play
result.action = 'control';
result.removeWords = controlWords;
return result;
}
var enableWords = [
'enable',
'turn on'
];
if (enableWords.filter(function (w) { return textLower.indexOf(w) == 0; }).length) {
// Play
result.action = 'enable';
result.removeWords = enableWords;
return result;
}
var disableWords = [
'disable',
'turn off'
];
if (disableWords.filter(function (w) { return textLower.indexOf(w) == 0; }).length) {
// Play
result.action = 'disable';
result.removeWords = disableWords;
return result;
}
var toggleWords = [
'toggle'
];
if (toggleWords.filter(function (w) { return textLower.indexOf(w) == 0; }).length) {
// Play
result.action = 'toggle';
result.removeWords = toggleWords;
return result;
}
if (words.indexOf('shuffle') != -1) {
// Play
result.action = 'shuffle';
result.removeWords.push('shuffle');
return result;
}
if (words.indexOf('record') != -1) {
// Record
result.action = 'record';
result.removeWords.push('record');
return result;
}
if (words.indexOf('guide') != -1) {
result.action = 'show';
result.category = 'tvguide';
return result;
}
return result;
}
function parseContext(text, result) {
text = text.toLowerCase();
var i, length;
for (i = 0, length = result.removeWords.length; i < length; i++) {
text = text.replace(result.removeWords[i], '');
}
text = text.trim();
var removeAtStart = [
'my'
];
for (i = 0, length = removeAtStart.length; i < length; i++) {
if (text.indexOf(removeAtStart[i]) == 0) {
text = text.substring(removeAtStart[i].length);
}
}
result.what = text;
text = text.trim();
var words = text.toLowerCase().split(' ');
if (words.indexOf('favorite') != -1) {
result.filters.push('favorite');
}
if (text.indexOf('latest movies') != -1 || text.indexOf('latest films') != -1) {
result.sortby = 'datecreated';
result.sortorder = 'Descending';
result.filters.push('unplayed');
result.itemType = 'Movie';
return;
}
if (text.indexOf('latest episodes') != -1) {
result.sortby = 'datecreated';
result.sortorder = 'Descending';
result.filters.push('unplayed');
result.itemType = 'Episode';
return;
}
if (text.indexOf('next up') != -1) {
result.category = 'nextup';
return;
}
if (text.indexOf('movies') != -1 || text.indexOf('films') != -1) {
result.itemType = 'Movie';
return;
}
if (text.indexOf('shows') != -1 || text.indexOf('series') != -1) {
result.itemType = 'Series';
return;
}
if (text.indexOf('songs') != -1) {
result.itemType = 'Audio';
return;
}
}
return function (text) {
var result = parseTextInternal(text);
parseContext(text, result);
return result;
}
});

View file

@ -1,7 +1,16 @@
define(['paperdialoghelper'], function (paperDialogHelper) { define(['paperdialoghelper'], function (paperDialogHelper) {
var currentRecognition; var currentRecognition;
var lang = 'grammar';
//var lang = 'en-US';
var commandgroups = getGrammarCommands(lang);
/// <summary> Shuffle array. </summary>
/// <param name="array"> The array. </param>
/// <returns> array </returns>
function shuffleArray(array) { function shuffleArray(array) {
var currentIndex = array.length, temporaryValue, randomIndex; var currentIndex = array.length, temporaryValue, randomIndex;
@ -21,201 +30,61 @@
return array; return array;
} }
function getSampleCommands() { /// <summary> Gets sample commands. </summary>
/// <returns> The sample commands. </returns>
function getSampleCommands(groupid) {
return new Promise(function (resolve, reject) { return new Promise(function (resolve, reject) {
groupid = typeof (groupid) !== 'undefined' ? groupid : '';
var commands = []; var commands = [];
commandgroups.map(function (group) {
if ((group.items && group.items.length > 0) && (groupid == group.groupid || groupid == '')) {
//commands.push('show my movies'); group.items.map(function (item) {
//commands.push('pull up my tv shows');
commands.push('play my latest episodes'); if (item.commandtemplates && item.commandtemplates.length > 0) {
commands.push('play next up');
commands.push('shuffle my favorite songs');
commands.push('show my tv guide'); item.commandtemplates.map(function (templates) {
commands.push('pull up my recordings'); commands.push(templates);
commands.push('control chromecast'); });
commands.push('control [device name]'); }
commands.push('turn on display mirroring');
commands.push('turn off display mirroring'); });
commands.push('toggle display mirroring'); }
});
resolve(shuffleArray(commands)); resolve(shuffleArray(commands));
});
}
function processText(text) {
return new Promise(function (resolve, reject) {
require(['voice/textprocessor-en-us.js'], function (parseText) {
var result = parseText(text);
switch (result.action) {
case 'show':
showCommand(result);
break;
case 'play':
playCommand(result);
break;
case 'shuffle':
playCommand(result, true);
break;
case 'search':
playCommand(result);
break;
case 'control':
controlCommand(result);
break;
case 'enable':
enableCommand(result);
break;
case 'disable':
disableCommand(result);
break;
case 'toggle':
toggleCommand(result);
break;
default:
reject();
return;
}
var dlg = currentDialog;
if (dlg) {
paperDialogHelper.close(dlg);
}
resolve();
});
});
}
function showCommand(result) {
if (result.category == 'tvguide') {
Dashboard.navigate('livetv.html?tab=1');
return;
}
if (result.category == 'recordings') {
Dashboard.navigate('livetv.html?tab=3');
return;
}
}
function enableCommand(result) {
var what = result.what.toLowerCase();
if (what.indexOf('mirror') != -1) {
MediaController.enableDisplayMirroring(true);
}
}
function disableCommand(result) {
var what = result.what.toLowerCase();
if (what.indexOf('mirror') != -1) {
MediaController.enableDisplayMirroring(false);
}
}
function toggleCommand(result) {
var what = result.what.toLowerCase();
if (what.indexOf('mirror') != -1) {
MediaController.toggleDisplayMirroring();
}
}
function controlCommand(result) {
MediaController.trySetActiveDeviceName(result.what);
}
function playCommand(result, shuffle) {
var query = {
Limit: result.limit || 100,
UserId: result.userId,
ExcludeLocationTypes: "Virtual"
};
if (result.category == 'nextup') {
ApiClient.getNextUpEpisodes(query).then(function (queryResult) {
playItems(queryResult.Items, shuffle);
}); });
return;
}
if (shuffle) {
result.sortby = result.sortby ? 'Random,' + result.sortby : 'Random';
}
query.SortBy = result.sortby;
query.SortOrder = result.sortorder;
query.Recursive = true;
if (result.filters.indexOf('unplayed') != -1) {
query.IsPlayed = false;
}
if (result.filters.indexOf('played') != -1) {
query.IsPlayed = true;
}
if (result.filters.indexOf('favorite') != -1) {
query.Filters = 'IsFavorite';
}
if (result.itemType) {
query.IncludeItemTypes = result.itemType;
}
ApiClient.getItems(Dashboard.getCurrentUserId(), query).then(function (queryResult) {
playItems(queryResult.Items, shuffle);
});
}
function playItems(items, shuffle) {
if (shuffle) {
items = shuffleArray(items);
}
items = items.map(function (i) {
return i.Id;
});
if (items.length) {
MediaController.play({
ids: items
});
} else {
Dashboard.alert({
message: Globalize.translate('MessageNoItemsFound')
});
}
}
function searchCommand(result) {
} }
/// <summary> Gets command group. </summary>
/// <param name="groupid"> The groupid. </param>
/// <returns> The command group. </returns>
function getCommandGroup(groupid) {
if (commandgroups) {
var idx = -1;
idx = commandgroups.map(function (e) { return e.groupid; }).indexOf(groupid);
if (idx > -1)
return commandgroups[idx];
else
return null;
}
else
return null;
}
/// <summary> Renders the sample commands. </summary>
/// <param name="elem"> The element. </param>
/// <param name="commands"> The commands. </param>
/// <returns> . </returns>
function renderSampleCommands(elem, commands) { function renderSampleCommands(elem, commands) {
commands.length = Math.min(commands.length, 4); commands.length = Math.min(commands.length, 6);
commands = commands.map(function (c) { commands = commands.map(function (c) {
@ -227,7 +96,9 @@
} }
var currentDialog; var currentDialog;
function showVoiceHelp() { /// <summary> Shows the voice help. </summary>
/// <returns> . </returns>
function showVoiceHelp(groupid, title) {
var dlg = paperDialogHelper.createDialog({ var dlg = paperDialogHelper.createDialog({
size: 'medium', size: 'medium',
@ -239,12 +110,17 @@
var html = ''; var html = '';
html += '<h2 class="dialogHeader">'; html += '<h2 class="dialogHeader">';
html += '<paper-fab icon="arrow-back" mini class="btnCancelVoiceInput" tabindex="-1"></paper-fab>'; html += '<paper-fab icon="arrow-back" mini class="btnCancelVoiceInput"></paper-fab>';
if (groupid) {
var grp = getCommandGroup(groupid);
if (grp)
html += ' ' + grp.name;
}
html += '</h2>'; html += '</h2>';
html += '<div>'; html += '<div>';
var getCommandsPromise = getSampleCommands(); var getCommandsPromise = getSampleCommands(groupid);
html += '<div class="voiceHelpContent">'; html += '<div class="voiceHelpContent">';
@ -302,45 +178,75 @@
}); });
} }
function showUnrecognizedCommandHelp() { /// <summary> Hides the voice help. </summary>
/// <returns> . </returns>
function hideVoiceHelp() {
$('.voiceInputHelp').remove();
}
/// <summary> Shows the unrecognized command help. </summary>
/// <returns> . </returns>
function showUnrecognizedCommandHelp() {
//speak("I don't understend this command");
$('.unrecognizedCommand').show(); $('.unrecognizedCommand').show();
$('.defaultVoiceHelp').hide(); $('.defaultVoiceHelp').hide();
} }
function destroyCurrentRecognition() { /// <summary> Process the transcript described by text. </summary>
/// <param name="text"> The text. </param>
var recognition = currentRecognition; /// <returns> . </returns>
if (recognition) {
recognition.cancelled = true;
recognition.abort();
currentRecognition = null;
}
}
function processTranscript(text, isCancelled) { function processTranscript(text, isCancelled) {
$('.voiceInputText').html(text); $('.voiceInputText').html(text);
if (text || AppInfo.isNativeApp) { if (text || AppInfo.isNativeApp) {
$('.blockedMessage').hide(); $('.blockedMessage').hide();
} else { }
else {
$('.blockedMessage').show(); $('.blockedMessage').show();
} }
if (text) { if (text) {
processText(text).catch(showUnrecognizedCommandHelp); require(['voice/voicecommands.js', 'voice/grammarprocessor.js'], function (voicecommands, grammarprocessor) {
} else if (!isCancelled) {
var processor = grammarprocessor(commandgroups, text);
if (processor && processor.command) {
voicecommands(processor)
.then(function (result) {
if (result.item.actionid === 'show' && result.item.sourceid === 'group') {
var dlg = currentDialog;
if (dlg)
showCommands(false, result)
else
showCommands(true, result)
}
})
.catch(showUnrecognizedCommandHelp);
}
else
showUnrecognizedCommandHelp();
var dlg = currentDialog;
if (dlg) {
PaperDialogHelper.close(dlg);
}
});
}
else if (!isCancelled) {
showUnrecognizedCommandHelp(); showUnrecognizedCommandHelp();
} }
} }
/// <summary> Starts listening internal. </summary>
/// <returns> . </returns>
function startListening(createUI) { function startListening(createUI) {
destroyCurrentRecognition(); destroyCurrentRecognition();
var recognition = new (window.SpeechRecognition || window.webkitSpeechRecognition || window.mozSpeechRecognition || window.oSpeechRecognition || window.msSpeechRecognition)();
var recognition = new (window.SpeechRecognition || window.webkitSpeechRecognition)(); recognition.lang = lang;
var groupid = '';
//recognition.continuous = true; //recognition.continuous = true;
//recognition.interimResults = true; //recognition.interimResults = true;
@ -360,25 +266,114 @@
recognition.start(); recognition.start();
currentRecognition = recognition; currentRecognition = recognition;
showCommands(createUI);
}
/// <summary> Destroys the current recognition. </summary>
/// <returns> . </returns>
function destroyCurrentRecognition() {
var recognition = currentRecognition;
if (recognition) {
recognition.abort();
currentRecognition = null;
}
}
/// <summary> Cancel listener. </summary>
/// <returns> . </returns>
function cancelListener() {
destroyCurrentRecognition();
hideVoiceHelp();
}
/// <summary> Shows the commands. </summary>
/// <param name="createUI"> The create user interface. </param>
/// <returns> . </returns>
function showCommands(createUI, result) {
if (createUI !== false) { if (createUI !== false) {
require(['paper-fab', 'css!voice/voice.css'], showVoiceHelp); //speak('Hello, what can I do for you?');
require(['paper-fab', 'css!voice/voice.css'], function () {
if (result)
showVoiceHelp(result.groupid, result.name);
else
showVoiceHelp();
});
} }
} }
/// <summary> Getgrammars the given language. </summary>
/// <param name="language"> The language. </param>
/// <returns> . </returns>
function getGrammarCommands(language) {
var file = "grammar";
if (language && language.length > 0)
file = language;
var grammar = (function () {
var grm = null;
$.ajax({
async: false,
global: false,
url: "voice/grammar/" + file + ".json",
dataType: "json",
success: function (data) {
grm = data;
}
});
return grm;
})();
return grammar;
}
/// <summary> Speaks the given text. </summary>
/// <param name="text"> The text. </param>
/// <returns> . </returns>
function speak(text) {
if (!SpeechSynthesisUtterance) {
console.log('API not supported');
}
var utterance = new SpeechSynthesisUtterance(text);
utterance.lang = lang;
utterance.rate = 0.9;
utterance.pitch = 1;
utterance.addEventListener('end', function () {
console.log('Synthesizing completed');
});
utterance.addEventListener('error', function (event) {
console.log('Synthesizing error');
});
console.log('Synthesizing the text: ' + text);
speechSynthesis.speak(utterance);
}
/// <summary> An enum constant representing the window. voice input manager option. </summary>
window.VoiceInputManager = { window.VoiceInputManager = {
isSupported: function () { isSupported: function () {
if (AppInfo.isNativeApp) { if (AppInfo.isNativeApp) {
// TODO: Only return false for crosswalk // Crashes on some amazon devices
if (window.device && (device.platform || '').toLowerCase().indexOf('amazon') != -1) {
return false; return false;
} }
}
return window.SpeechRecognition || window.webkitSpeechRecognition; return window.SpeechRecognition ||
window.webkitSpeechRecognition ||
window.mozSpeechRecognition ||
window.oSpeechRecognition ||
window.msSpeechRecognition;
}, },
startListening: startListening startListening: startListening,
}; };
}); });

View file

@ -0,0 +1,61 @@
// <date>09.10.2015</date>
// <summary>voicecommands class</summary>
define([], function () {
/// <summary> Process the command. </summary>
/// <param name="commandPath"> Full pathname of the command file. </param>
/// <param name="result"> The result. </param>
/// <returns> . </returns>
function processCommand(commandPath, result) {
return new Promise(function (resolve, reject) {
require([commandPath], function (command) {
command(result);
if (result.success) {
resolve(result);
}
reject();
});
});
}
return function (result) {
return new Promise(function (resolve, reject) {
switch (result.item.actionid) {
case 'show':
processCommand('voice/commands/showcommands.js', result).then(function (result) { resolve(result); });
break;
case 'play':
processCommand('voice/commands/playcommands.js', result).then(function (result) { resolve(result); });
break;
case 'shuffle':
processCommand('voice/commands/playcommands.js', result).then(function (result) { resolve(result); });
break;
case 'search':
processCommand('voice/commands/searchcommands.js', result).then(function (result) { resolve(result); });
break;
case 'control':
processCommand('voice/commands/controlcommands.js', result).then(function (result) { resolve(result); });
break;
case 'enable':
processCommand('voice/commands/enablecommands.js', result).then(function (result) { resolve(result); });
break;
case 'disable':
processCommand('voice/commands/disablecommands.js', result).then(function (result) { resolve(result); });
break;
case 'toggle':
processCommand('voice/commands/togglecommands.js', result).then(function (result) { resolve(result); });
break;
default:
reject();
return;
}
});
}
});