mirror of
https://github.com/openhab/openhab-addons.git
synced 2025-01-25 14:55:55 +01:00
[freeboxos] Fix start/stop audio sink (#17223)
* [freeboxos] Fix start/stop audio sink Fix #17208 Signed-off-by: Laurent Garnier <lg.hc@free.fr>
This commit is contained in:
parent
39eca040d1
commit
0562b0a231
@ -87,40 +87,62 @@ public abstract class ApiConsumerHandler extends BaseThingHandler implements Api
|
|||||||
Map<String, String> properties = editProperties();
|
Map<String, String> properties = editProperties();
|
||||||
try {
|
try {
|
||||||
initializeProperties(properties);
|
initializeProperties(properties);
|
||||||
checkAirMediaCapabilities(properties);
|
|
||||||
updateProperties(properties);
|
updateProperties(properties);
|
||||||
} catch (FreeboxException e) {
|
} catch (FreeboxException e) {
|
||||||
logger.warn("Error getting thing {} properties: {}", thing.getUID(), e.getMessage());
|
logger.warn("Error getting thing {} properties: {}", thing.getUID(), e.getMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean isAudioReceiver = Boolean.parseBoolean(properties.get(MediaType.AUDIO.name()));
|
|
||||||
if (isAudioReceiver) {
|
|
||||||
configureMediaSink(bridgeHandler, properties.getOrDefault(Source.UPNP.name(), ""));
|
|
||||||
}
|
|
||||||
|
|
||||||
startRefreshJob();
|
startRefreshJob();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void configureMediaSink(FreeboxOsHandler bridgeHandler, String upnpName) {
|
protected void configureMediaSink() {
|
||||||
try {
|
try {
|
||||||
|
String upnpName = editProperties().getOrDefault(Source.UPNP.name(), "");
|
||||||
Receiver receiver = getManager(MediaReceiverManager.class).getReceiver(upnpName);
|
Receiver receiver = getManager(MediaReceiverManager.class).getReceiver(upnpName);
|
||||||
if (receiver != null && reg == null) {
|
if (receiver != null) {
|
||||||
ApiConsumerConfiguration config = getConfig().as(ApiConsumerConfiguration.class);
|
Map<String, String> properties = editProperties();
|
||||||
String callbackURL = bridgeHandler.getCallbackURL();
|
receiver.capabilities().entrySet()
|
||||||
if (!config.password.isEmpty() || !receiver.passwordProtected()) {
|
.forEach(entry -> properties.put(entry.getKey().name(), entry.getValue().toString()));
|
||||||
reg = bridgeHandler.getBundleContext().registerService(
|
updateProperties(properties);
|
||||||
AudioSink.class.getName(), new AirMediaSink(this, bridgeHandler.getAudioHTTPServer(),
|
|
||||||
callbackURL, receiver.name(), config.password, config.acceptAllMp3),
|
startAudioSink(receiver);
|
||||||
new Hashtable<>());
|
} else {
|
||||||
} else {
|
stopAudioSink();
|
||||||
logger.info("A password needs to be configured to enable Air Media capability.");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} catch (FreeboxException e) {
|
} catch (FreeboxException e) {
|
||||||
logger.warn("Unable to retrieve Media Receivers: {}", e.getMessage());
|
logger.warn("Unable to retrieve Media Receivers: {}", e.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void startAudioSink(Receiver receiver) {
|
||||||
|
FreeboxOsHandler bridgeHandler = checkBridgeHandler();
|
||||||
|
// Only video and photo is supported by the API so use VIDEO capability for audio
|
||||||
|
Boolean isAudioReceiver = receiver.capabilities().get(MediaType.VIDEO);
|
||||||
|
if (reg == null && bridgeHandler != null && isAudioReceiver != null && isAudioReceiver.booleanValue()) {
|
||||||
|
ApiConsumerConfiguration config = getConfig().as(ApiConsumerConfiguration.class);
|
||||||
|
String callbackURL = bridgeHandler.getCallbackURL();
|
||||||
|
if (!config.password.isEmpty() || !receiver.passwordProtected()) {
|
||||||
|
reg = bridgeHandler.getBundleContext()
|
||||||
|
.registerService(
|
||||||
|
AudioSink.class.getName(), new AirMediaSink(this, bridgeHandler.getAudioHTTPServer(),
|
||||||
|
callbackURL, receiver.name(), config.password, config.acceptAllMp3),
|
||||||
|
new Hashtable<>());
|
||||||
|
logger.debug("Audio sink registered for {}.", receiver.name());
|
||||||
|
} else {
|
||||||
|
logger.warn("A password needs to be configured to enable Air Media capability.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void stopAudioSink() {
|
||||||
|
ServiceRegistration<?> localReg = reg;
|
||||||
|
if (localReg != null) {
|
||||||
|
localReg.unregister();
|
||||||
|
logger.debug("Audio sink unregistered");
|
||||||
|
reg = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public <T extends RestManager> T getManager(Class<T> clazz) throws FreeboxException {
|
public <T extends RestManager> T getManager(Class<T> clazz) throws FreeboxException {
|
||||||
FreeboxOsHandler handler = checkBridgeHandler();
|
FreeboxOsHandler handler = checkBridgeHandler();
|
||||||
if (handler != null) {
|
if (handler != null) {
|
||||||
@ -159,15 +181,6 @@ public abstract class ApiConsumerHandler extends BaseThingHandler implements Api
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkAirMediaCapabilities(Map<String, String> properties) throws FreeboxException {
|
|
||||||
String upnpName = properties.getOrDefault(Source.UPNP.name(), "");
|
|
||||||
Receiver receiver = getManager(MediaReceiverManager.class).getReceiver(upnpName);
|
|
||||||
if (receiver != null) {
|
|
||||||
receiver.capabilities().entrySet()
|
|
||||||
.forEach(entry -> properties.put(entry.getKey().name(), entry.getValue().toString()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private @Nullable FreeboxOsHandler checkBridgeHandler() {
|
private @Nullable FreeboxOsHandler checkBridgeHandler() {
|
||||||
Bridge bridge = getBridge();
|
Bridge bridge = getBridge();
|
||||||
if (bridge != null) {
|
if (bridge != null) {
|
||||||
@ -192,10 +205,7 @@ public abstract class ApiConsumerHandler extends BaseThingHandler implements Api
|
|||||||
@Override
|
@Override
|
||||||
public void dispose() {
|
public void dispose() {
|
||||||
stopJobs();
|
stopJobs();
|
||||||
ServiceRegistration<?> localReg = reg;
|
stopAudioSink();
|
||||||
if (localReg != null) {
|
|
||||||
localReg.unregister();
|
|
||||||
}
|
|
||||||
super.dispose();
|
super.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -46,6 +46,10 @@ public class HostHandler extends ApiConsumerHandler {
|
|||||||
// We start in pull mode and switch to push after a first update...
|
// We start in pull mode and switch to push after a first update...
|
||||||
protected boolean pushSubscribed = false;
|
protected boolean pushSubscribed = false;
|
||||||
|
|
||||||
|
protected boolean reachable;
|
||||||
|
|
||||||
|
private int tryConfigureMediaSink = 1;
|
||||||
|
|
||||||
public HostHandler(Thing thing) {
|
public HostHandler(Thing thing) {
|
||||||
super(thing);
|
super(thing);
|
||||||
statusDrivenByBridge = false;
|
statusDrivenByBridge = false;
|
||||||
@ -78,6 +82,11 @@ public class HostHandler extends ApiConsumerHandler {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void internalPoll() throws FreeboxException {
|
protected void internalPoll() throws FreeboxException {
|
||||||
|
if (tryConfigureMediaSink > 0) {
|
||||||
|
configureMediaSink();
|
||||||
|
tryConfigureMediaSink--;
|
||||||
|
}
|
||||||
|
|
||||||
if (pushSubscribed) {
|
if (pushSubscribed) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -109,6 +118,13 @@ public class HostHandler extends ApiConsumerHandler {
|
|||||||
updateChannelDateTimeState(CONNECTIVITY, LAST_SEEN, host.getLastSeen());
|
updateChannelDateTimeState(CONNECTIVITY, LAST_SEEN, host.getLastSeen());
|
||||||
updateChannelString(CONNECTIVITY, IP_ADDRESS, host.getIpv4());
|
updateChannelString(CONNECTIVITY, IP_ADDRESS, host.getIpv4());
|
||||||
updateStatus(host.reachable() ? ThingStatus.ONLINE : ThingStatus.OFFLINE);
|
updateStatus(host.reachable() ? ThingStatus.ONLINE : ThingStatus.OFFLINE);
|
||||||
|
// We will check and configure audio sink only when the host reachability changed
|
||||||
|
if (reachable != host.reachable()) {
|
||||||
|
reachable = host.reachable();
|
||||||
|
// It can take time until the Media Receiver API returns the receiver after it becomes reachable.
|
||||||
|
// So this will be checked during the next 2 polls.
|
||||||
|
tryConfigureMediaSink = 2;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void wol() {
|
public void wol() {
|
||||||
|
Loading…
Reference in New Issue
Block a user