mirror of
https://github.com/danieldemus/openhab-core.git
synced 2025-01-11 05:41:52 +01:00
adapted Audio action to new ESH TTS interfaces (#53)
Signed-off-by: Kai Kreuzer <kai@openhab.org>
This commit is contained in:
parent
795aab9b19
commit
33b6032405
@ -22,6 +22,8 @@ Import-Package: com.google.common.base,
|
|||||||
org.eclipse.emf.common.util,
|
org.eclipse.emf.common.util,
|
||||||
org.eclipse.emf.ecore,
|
org.eclipse.emf.ecore,
|
||||||
org.eclipse.emf.ecore.resource,
|
org.eclipse.emf.ecore.resource,
|
||||||
|
org.eclipse.smarthome.config.core,
|
||||||
|
org.eclipse.smarthome.core.audio,
|
||||||
org.eclipse.smarthome.core.autoupdate,
|
org.eclipse.smarthome.core.autoupdate,
|
||||||
org.eclipse.smarthome.core.common.registry,
|
org.eclipse.smarthome.core.common.registry,
|
||||||
org.eclipse.smarthome.core.events,
|
org.eclipse.smarthome.core.events,
|
||||||
@ -32,7 +34,7 @@ Import-Package: com.google.common.base,
|
|||||||
org.eclipse.smarthome.core.persistence,
|
org.eclipse.smarthome.core.persistence,
|
||||||
org.eclipse.smarthome.core.transform,
|
org.eclipse.smarthome.core.transform,
|
||||||
org.eclipse.smarthome.core.types,
|
org.eclipse.smarthome.core.types,
|
||||||
org.eclipse.smarthome.io.voice.tts,
|
org.eclipse.smarthome.core.voice,
|
||||||
org.eclipse.smarthome.model.item,
|
org.eclipse.smarthome.model.item,
|
||||||
org.eclipse.smarthome.model.persistence,
|
org.eclipse.smarthome.model.persistence,
|
||||||
org.eclipse.smarthome.model.script.engine,
|
org.eclipse.smarthome.model.script.engine,
|
||||||
@ -89,7 +91,6 @@ Export-Package: org.codehaus.jackson,
|
|||||||
org.openhab.core.types,
|
org.openhab.core.types,
|
||||||
org.openhab.io.console,
|
org.openhab.io.console,
|
||||||
org.openhab.io.multimedia.actions,
|
org.openhab.io.multimedia.actions,
|
||||||
org.openhab.io.multimedia.tts,
|
|
||||||
org.openhab.io.net.actions,
|
org.openhab.io.net.actions,
|
||||||
org.openhab.io.net.exec,
|
org.openhab.io.net.exec,
|
||||||
org.openhab.io.net.http,
|
org.openhab.io.net.http,
|
||||||
@ -104,3 +105,4 @@ Bundle-ClassPath: lib/jl1.0.1.jar,
|
|||||||
lib/jackson-core-asl-1.9.2.jar,
|
lib/jackson-core-asl-1.9.2.jar,
|
||||||
lib/jackson-mapper-asl-1.9.2.jar
|
lib/jackson-mapper-asl-1.9.2.jar
|
||||||
Service-Component: OSGI-INF/*.xml
|
Service-Component: OSGI-INF/*.xml
|
||||||
|
Bundle-ActivationPolicy: lazy
|
||||||
|
@ -9,9 +9,10 @@
|
|||||||
http://www.eclipse.org/legal/epl-v10.html
|
http://www.eclipse.org/legal/epl-v10.html
|
||||||
|
|
||||||
-->
|
-->
|
||||||
<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" name="org.openhab.action.audio">
|
<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" immediate="true" name="org.openhab.action.audio">
|
||||||
<implementation class="org.openhab.io.multimedia.actions.AudioActionService"/>
|
<implementation class="org.openhab.io.multimedia.actions.AudioActionService"/>
|
||||||
<service>
|
<service>
|
||||||
<provide interface="org.openhab.core.scriptengine.action.ActionService"/>
|
<provide interface="org.openhab.core.scriptengine.action.ActionService"/>
|
||||||
</service>
|
</service>
|
||||||
|
<reference bind="setVoiceManager" cardinality="1..1" interface="org.eclipse.smarthome.core.voice.VoiceManager" name="VoiceManager" policy="static" unbind="unsetVoiceManager"/>
|
||||||
</scr:component>
|
</scr:component>
|
||||||
|
@ -1,15 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<!--
|
|
||||||
|
|
||||||
Copyright (c) 2015-2016 by the respective copyright holders.
|
|
||||||
|
|
||||||
All rights reserved. This program and the accompanying materials
|
|
||||||
are made available under the terms of the Eclipse Public License v1.0
|
|
||||||
which accompanies this distribution, and is available at
|
|
||||||
http://www.eclipse.org/legal/epl-v10.html
|
|
||||||
|
|
||||||
-->
|
|
||||||
<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" activate="activate" deactivate="deactivate" name="org.openhab.core.compat1x.ttsservicefactory">
|
|
||||||
<implementation class="org.openhab.io.multimedia.tts.internal.TTSServiceFactory"/>
|
|
||||||
<reference bind="addTTSService" cardinality="0..n" interface="org.openhab.io.multimedia.tts.TTSService" name="TTSService" policy="dynamic" unbind="removeTTSService"/>
|
|
||||||
</scr:component>
|
|
@ -3,14 +3,6 @@ bin.includes = META-INF/,\
|
|||||||
.,\
|
.,\
|
||||||
lib/,\
|
lib/,\
|
||||||
OSGI-INF/,\
|
OSGI-INF/,\
|
||||||
OSGI-INF/autoupdateproviderdelegate.xml,\
|
|
||||||
OSGI-INF/eventbridge.xml,\
|
|
||||||
OSGI-INF/eventpublisherdelegate.xml,\
|
|
||||||
OSGI-INF/bindingconfigreaderfactory.xml,\
|
|
||||||
OSGI-INF/actionservicefactory.xml,\
|
|
||||||
OSGI-INF/itemuiregistry.xml,\
|
|
||||||
OSGI-INF/chartproviderfactory.xml,\
|
|
||||||
OSGI-INF/ttsservicefactory.xml,\
|
|
||||||
lib/jackson-core-asl-1.9.2.jar,\
|
lib/jackson-core-asl-1.9.2.jar,\
|
||||||
lib/jackson-mapper-asl-1.9.2.jar
|
lib/jackson-mapper-asl-1.9.2.jar
|
||||||
source.. = src/main/java/
|
source.. = src/main/java/
|
||||||
|
@ -18,7 +18,6 @@ import java.net.MalformedURLException;
|
|||||||
import java.net.Socket;
|
import java.net.Socket;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.net.URLConnection;
|
import java.net.URLConnection;
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
@ -33,15 +32,10 @@ import javax.sound.sampled.UnsupportedAudioFileException;
|
|||||||
|
|
||||||
import org.apache.commons.collections.Closure;
|
import org.apache.commons.collections.Closure;
|
||||||
import org.apache.commons.io.IOUtils;
|
import org.apache.commons.io.IOUtils;
|
||||||
import org.apache.commons.lang.StringUtils;
|
import org.eclipse.smarthome.config.core.ConfigConstants;
|
||||||
import org.eclipse.smarthome.io.voice.tts.TTSService;
|
|
||||||
import org.openhab.core.compat1x.internal.CompatibilityActivator;
|
|
||||||
import org.openhab.core.library.types.PercentType;
|
import org.openhab.core.library.types.PercentType;
|
||||||
import org.openhab.core.scriptengine.action.ActionDoc;
|
import org.openhab.core.scriptengine.action.ActionDoc;
|
||||||
import org.openhab.core.scriptengine.action.ParamDoc;
|
import org.openhab.core.scriptengine.action.ParamDoc;
|
||||||
import org.osgi.framework.BundleContext;
|
|
||||||
import org.osgi.framework.InvalidSyntaxException;
|
|
||||||
import org.osgi.framework.ServiceReference;
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
@ -50,7 +44,6 @@ import javazoom.jl.player.Player;
|
|||||||
|
|
||||||
public class Audio {
|
public class Audio {
|
||||||
|
|
||||||
private static final String RUNTIME_DIR = "runtime";
|
|
||||||
private static final String SOUND_DIR = "sounds";
|
private static final String SOUND_DIR = "sounds";
|
||||||
private static final Logger logger = LoggerFactory.getLogger(Audio.class);
|
private static final Logger logger = LoggerFactory.getLogger(Audio.class);
|
||||||
|
|
||||||
@ -65,7 +58,8 @@ public class Audio {
|
|||||||
@ActionDoc(text = "plays a sound from the sounds folder")
|
@ActionDoc(text = "plays a sound from the sounds folder")
|
||||||
static public void playSound(@ParamDoc(name = "filename", text = "the filename with extension") String filename) {
|
static public void playSound(@ParamDoc(name = "filename", text = "the filename with extension") String filename) {
|
||||||
try {
|
try {
|
||||||
InputStream is = new FileInputStream(RUNTIME_DIR + File.separator + SOUND_DIR + File.separator + filename);
|
InputStream is = new FileInputStream(
|
||||||
|
ConfigConstants.getConfigFolder() + File.separator + SOUND_DIR + File.separator + filename);
|
||||||
if (filename.toLowerCase().endsWith(".mp3")) {
|
if (filename.toLowerCase().endsWith(".mp3")) {
|
||||||
Player player = new Player(is);
|
Player player = new Player(is);
|
||||||
playInThread(player);
|
playInThread(player);
|
||||||
@ -168,7 +162,7 @@ public class Audio {
|
|||||||
*/
|
*/
|
||||||
@ActionDoc(text = "says a given text through the default TTS service")
|
@ActionDoc(text = "says a given text through the default TTS service")
|
||||||
static public void say(@ParamDoc(name = "text") Object text) {
|
static public void say(@ParamDoc(name = "text") Object text) {
|
||||||
say(text.toString(), null);
|
AudioActionService.voiceManager.say(text.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -185,7 +179,7 @@ public class Audio {
|
|||||||
*/
|
*/
|
||||||
@ActionDoc(text = "says a given text through the default TTS service with a given voice")
|
@ActionDoc(text = "says a given text through the default TTS service with a given voice")
|
||||||
static public void say(@ParamDoc(name = "text") Object text, @ParamDoc(name = "voice") String voice) {
|
static public void say(@ParamDoc(name = "text") Object text, @ParamDoc(name = "voice") String voice) {
|
||||||
say(text, voice, null);
|
AudioActionService.voiceManager.say(text.toString(), voice);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -204,18 +198,8 @@ public class Audio {
|
|||||||
*/
|
*/
|
||||||
@ActionDoc(text = "says a given text through the default TTS service with a given voice")
|
@ActionDoc(text = "says a given text through the default TTS service with a given voice")
|
||||||
static public void say(@ParamDoc(name = "text") Object text, @ParamDoc(name = "voice") String voice,
|
static public void say(@ParamDoc(name = "text") Object text, @ParamDoc(name = "voice") String voice,
|
||||||
@ParamDoc(name = "device") String device) {
|
@ParamDoc(name = "sink") String sink) {
|
||||||
if (StringUtils.isNotBlank(text.toString())) {
|
AudioActionService.voiceManager.say(text.toString(), voice, sink);
|
||||||
TTSService ttsService = getTTSService(CompatibilityActivator.getContext(), System.getProperty("osgi.os"));
|
|
||||||
if (ttsService == null) {
|
|
||||||
ttsService = getTTSService(CompatibilityActivator.getContext(), "any");
|
|
||||||
}
|
|
||||||
if (ttsService != null) {
|
|
||||||
ttsService.say(text.toString(), voice, device);
|
|
||||||
} else {
|
|
||||||
logger.error("No TTS service available - tried to say: {}", text);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ActionDoc(text = "sets the master volume of the host")
|
@ActionDoc(text = "sets the master volume of the host")
|
||||||
@ -387,31 +371,6 @@ public class Audio {
|
|||||||
}.start();
|
}.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Queries the OSGi service registry for a service that provides a TTS implementation
|
|
||||||
* for a given platform.
|
|
||||||
*
|
|
||||||
* @param context the bundle context to access the OSGi service registry
|
|
||||||
* @param os a valid osgi.os string value or "any" if service should be platform-independent
|
|
||||||
* @return a service instance or null, if none could be found
|
|
||||||
*/
|
|
||||||
static private TTSService getTTSService(BundleContext context, String os) {
|
|
||||||
if (context != null) {
|
|
||||||
String filter = os != null ? "(os=" + os + ")" : null;
|
|
||||||
try {
|
|
||||||
Collection<ServiceReference<TTSService>> refs = context.getServiceReferences(TTSService.class, filter);
|
|
||||||
if (refs != null && refs.size() > 0) {
|
|
||||||
return context.getService(refs.iterator().next());
|
|
||||||
} else {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
} catch (InvalidSyntaxException e) {
|
|
||||||
// this should never happen
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static boolean isMacOSX() {
|
private static boolean isMacOSX() {
|
||||||
return System.getProperty("osgi.os").equals("macosx");
|
return System.getProperty("osgi.os").equals("macosx");
|
||||||
}
|
}
|
||||||
|
@ -8,10 +8,13 @@
|
|||||||
*/
|
*/
|
||||||
package org.openhab.io.multimedia.actions;
|
package org.openhab.io.multimedia.actions;
|
||||||
|
|
||||||
|
import org.eclipse.smarthome.core.voice.VoiceManager;
|
||||||
import org.openhab.core.scriptengine.action.ActionService;
|
import org.openhab.core.scriptengine.action.ActionService;
|
||||||
|
|
||||||
public class AudioActionService implements ActionService {
|
public class AudioActionService implements ActionService {
|
||||||
|
|
||||||
|
public static VoiceManager voiceManager;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getActionClassName() {
|
public String getActionClassName() {
|
||||||
return Audio.class.getCanonicalName();
|
return Audio.class.getCanonicalName();
|
||||||
@ -22,5 +25,11 @@ public class AudioActionService implements ActionService {
|
|||||||
return Audio.class;
|
return Audio.class;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected void setVoiceManager(VoiceManager voiceManager) {
|
||||||
|
AudioActionService.voiceManager = voiceManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected void unsetVoiceManager(VoiceManager voiceManager) {
|
||||||
|
AudioActionService.voiceManager = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -1,33 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) 2015-2016 by the respective copyright holders.
|
|
||||||
*
|
|
||||||
* All rights reserved. This program and the accompanying materials
|
|
||||||
* are made available under the terms of the Eclipse Public License v1.0
|
|
||||||
* which accompanies this distribution, and is available at
|
|
||||||
* http://www.eclipse.org/legal/epl-v10.html
|
|
||||||
*/
|
|
||||||
package org.openhab.io.multimedia.tts;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This is the interface that a text-to-speech service has to implement.
|
|
||||||
*
|
|
||||||
* @author Kai Kreuzer - Initial contribution and API
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public interface TTSService {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Speaks the text with a given voice
|
|
||||||
*
|
|
||||||
* @param text
|
|
||||||
* the text to speak
|
|
||||||
* @param voice
|
|
||||||
* the name of the voice to use or null, if the default voice
|
|
||||||
* should be used
|
|
||||||
* @param device
|
|
||||||
* the name of audio device to be used to play the audio or null,
|
|
||||||
* if the default output device should be used
|
|
||||||
*/
|
|
||||||
void say(String text, String voice, String outputDevice);
|
|
||||||
|
|
||||||
}
|
|
@ -1,33 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) 2015-2016 by the respective copyright holders.
|
|
||||||
*
|
|
||||||
* All rights reserved. This program and the accompanying materials
|
|
||||||
* are made available under the terms of the Eclipse Public License v1.0
|
|
||||||
* which accompanies this distribution, and is available at
|
|
||||||
* http://www.eclipse.org/legal/epl-v10.html
|
|
||||||
*/
|
|
||||||
package org.openhab.io.multimedia.tts.internal;
|
|
||||||
|
|
||||||
import org.eclipse.smarthome.io.voice.tts.TTSService;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This class serves as a mapping from the "old" org.openhab namespace to the
|
|
||||||
* new org.eclipse.smarthome namespace for the action service. It wraps an
|
|
||||||
* instance with the old interface into a class with the new interface.
|
|
||||||
*
|
|
||||||
* @author Tobias Bräutigam - Initial contribution and API
|
|
||||||
*/
|
|
||||||
public class TTSServiceDelegate implements TTSService {
|
|
||||||
|
|
||||||
private org.openhab.io.multimedia.tts.TTSService service;
|
|
||||||
|
|
||||||
public TTSServiceDelegate(org.openhab.io.multimedia.tts.TTSService service) {
|
|
||||||
this.service = service;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void say(String text, String voice, String outputDevice) {
|
|
||||||
service.say(text, voice, outputDevice);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,87 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) 2015-2016 by the respective copyright holders.
|
|
||||||
*
|
|
||||||
* All rights reserved. This program and the accompanying materials
|
|
||||||
* are made available under the terms of the Eclipse Public License v1.0
|
|
||||||
* which accompanies this distribution, and is available at
|
|
||||||
* http://www.eclipse.org/legal/epl-v10.html
|
|
||||||
*/
|
|
||||||
package org.openhab.io.multimedia.tts.internal;
|
|
||||||
|
|
||||||
import java.util.Dictionary;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Hashtable;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import org.openhab.io.multimedia.tts.TTSService;
|
|
||||||
import org.osgi.framework.BundleContext;
|
|
||||||
import org.osgi.framework.ServiceRegistration;
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This class listens for services that implement the old tts service interface
|
|
||||||
* and registers an according service for each under the new interface.
|
|
||||||
*
|
|
||||||
* @author Tobias Bräutigam - Initial contribution and API (copied from
|
|
||||||
* ActionServiceFactory)
|
|
||||||
*/
|
|
||||||
public class TTSServiceFactory {
|
|
||||||
private static final Logger logger = LoggerFactory.getLogger(TTSServiceFactory.class);
|
|
||||||
|
|
||||||
private Map<String, ServiceRegistration<org.eclipse.smarthome.io.voice.tts.TTSService>> delegates = new HashMap<>();
|
|
||||||
private BundleContext context;
|
|
||||||
|
|
||||||
private Map<TTSService, Map> ttsServices = new HashMap<>();
|
|
||||||
|
|
||||||
public void activate(BundleContext context) {
|
|
||||||
this.context = context;
|
|
||||||
for (TTSService service : ttsServices.keySet()) {
|
|
||||||
registerDelegateService(service, ttsServices.get(service));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void deactivate() {
|
|
||||||
for (ServiceRegistration<org.eclipse.smarthome.io.voice.tts.TTSService> serviceReg : delegates.values()) {
|
|
||||||
serviceReg.unregister();
|
|
||||||
}
|
|
||||||
delegates.clear();
|
|
||||||
this.context = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void addTTSService(TTSService service, Map prop) {
|
|
||||||
if (context != null) {
|
|
||||||
registerDelegateService(service, prop);
|
|
||||||
} else {
|
|
||||||
ttsServices.put(service, prop);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void removeTTSService(TTSService service) {
|
|
||||||
if (context != null) {
|
|
||||||
unregisterDelegateService(service);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void registerDelegateService(TTSService ttsService, Map properties) {
|
|
||||||
if (!delegates.containsKey(ttsService.getClass().getName())) {
|
|
||||||
TTSServiceDelegate service = new TTSServiceDelegate(ttsService);
|
|
||||||
Dictionary<String, Object> props = new Hashtable<String, Object>();
|
|
||||||
if (properties != null && properties.containsKey("os")) {
|
|
||||||
props.put("os", properties.get("os"));
|
|
||||||
}
|
|
||||||
ServiceRegistration<org.eclipse.smarthome.io.voice.tts.TTSService> serviceReg = context
|
|
||||||
.registerService(org.eclipse.smarthome.io.voice.tts.TTSService.class, service, props);
|
|
||||||
delegates.put(ttsService.getClass().getName(), serviceReg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void unregisterDelegateService(TTSService service) {
|
|
||||||
if (delegates.containsKey(service.getClass().getName())) {
|
|
||||||
ServiceRegistration<org.eclipse.smarthome.io.voice.tts.TTSService> serviceReg = delegates
|
|
||||||
.get(service.getClass().getName());
|
|
||||||
delegates.remove(service.getClass().getName());
|
|
||||||
serviceReg.unregister();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user