mirror of
https://github.com/hyperion-project/hyperion.ng.git
synced 2023-10-10 13:36:59 +02:00
New XBMC checker functionality: 3D video detection (filename based) and screensaver detection
Former-commit-id: ea95e4ecde3ab9378bdf9c4c60950713947bd0ac
This commit is contained in:
parent
e1a60e6944
commit
78795b9fa8
@ -1 +1 @@
|
|||||||
c358364291c2377c26ef2912042fae6d7fe50d08
|
42debced0ba50d4c1801b25ae3ce1a546ec7a94e
|
@ -9,6 +9,7 @@
|
|||||||
#include <utils/ColorRgb.h>
|
#include <utils/ColorRgb.h>
|
||||||
#include <utils/ColorRgba.h>
|
#include <utils/ColorRgba.h>
|
||||||
#include <utils/GrabbingMode.h>
|
#include <utils/GrabbingMode.h>
|
||||||
|
#include <utils/VideoMode.h>
|
||||||
|
|
||||||
// Forward class declaration
|
// Forward class declaration
|
||||||
class DispmanxFrameGrabber;
|
class DispmanxFrameGrabber;
|
||||||
@ -61,6 +62,12 @@ public slots:
|
|||||||
///
|
///
|
||||||
void setGrabbingMode(const GrabbingMode mode);
|
void setGrabbingMode(const GrabbingMode mode);
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Set the video mode (2D/3D)
|
||||||
|
/// @param[in] mode The new video mode
|
||||||
|
///
|
||||||
|
void setVideoMode(const VideoMode videoMode);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/// The update rate [Hz]
|
/// The update rate [Hz]
|
||||||
const int _updateInterval_ms;
|
const int _updateInterval_ms;
|
||||||
|
@ -118,6 +118,22 @@ public:
|
|||||||
return _pixels[toIndex(x,y)];
|
return _pixels[toIndex(x,y)];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Resize the image
|
||||||
|
/// @param width The width of the image
|
||||||
|
/// @param height The height of the image
|
||||||
|
void resize(const unsigned width, const unsigned height)
|
||||||
|
{
|
||||||
|
if ((width*height) > (_endOfPixels-_pixels))
|
||||||
|
{
|
||||||
|
delete[] _pixels;
|
||||||
|
_pixels = new Pixel_T[width*height + 1];
|
||||||
|
_endOfPixels = _pixels + width*height;
|
||||||
|
}
|
||||||
|
|
||||||
|
_width = width;
|
||||||
|
_height = height;
|
||||||
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Copies another image into this image. The images should have exactly the same size.
|
/// Copies another image into this image. The images should have exactly the same size.
|
||||||
///
|
///
|
||||||
@ -165,9 +181,9 @@ private:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
/// The width of the image
|
/// The width of the image
|
||||||
const unsigned _width;
|
unsigned _width;
|
||||||
/// The height of the image
|
/// The height of the image
|
||||||
const unsigned _height;
|
unsigned _height;
|
||||||
|
|
||||||
/// The pixels of the image
|
/// The pixels of the image
|
||||||
Pixel_T* _pixels;
|
Pixel_T* _pixels;
|
||||||
|
11
include/utils/VideoMode.h
Normal file
11
include/utils/VideoMode.h
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enumeration of the possible modes in which video can be playing (2D, 3D)
|
||||||
|
*/
|
||||||
|
enum VideoMode
|
||||||
|
{
|
||||||
|
VIDEO_2D,
|
||||||
|
VIDEO_3DSBS,
|
||||||
|
VIDEO_3DTAB
|
||||||
|
};
|
@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
// Utils includes
|
// Utils includes
|
||||||
#include <utils/GrabbingMode.h>
|
#include <utils/GrabbingMode.h>
|
||||||
|
#include <utils/VideoMode.h>
|
||||||
|
|
||||||
///
|
///
|
||||||
/// This class will check if XBMC is playing something. When it does not, this class will send all black data to Hyperion.
|
/// This class will check if XBMC is playing something. When it does not, this class will send all black data to Hyperion.
|
||||||
@ -33,13 +34,14 @@ public:
|
|||||||
///
|
///
|
||||||
/// @param address Network address of the XBMC instance
|
/// @param address Network address of the XBMC instance
|
||||||
/// @param port Port number to use (XBMC default = 9090)
|
/// @param port Port number to use (XBMC default = 9090)
|
||||||
/// @param interval The interval at which XBMC is polled
|
|
||||||
/// @param grabVideo Whether or not to grab when the XBMC video player is playing
|
/// @param grabVideo Whether or not to grab when the XBMC video player is playing
|
||||||
/// @param grabPhoto Whether or not to grab when the XBMC photo player is playing
|
/// @param grabPhoto Whether or not to grab when the XBMC photo player is playing
|
||||||
/// @param grabAudio Whether or not to grab when the XBMC audio player is playing
|
/// @param grabAudio Whether or not to grab when the XBMC audio player is playing
|
||||||
/// @param grabMenu Whether or not to grab when nothing is playing (in XBMC menu)
|
/// @param grabMenu Whether or not to grab when nothing is playing (in XBMC menu)
|
||||||
|
/// @param grabScreensaver Whether or not to grab when the XBMC screensaver is activated
|
||||||
|
/// @param enable3DDetection Wheter or not to enable the detection of 3D movies playing
|
||||||
///
|
///
|
||||||
XBMCVideoChecker(const std::string & address, uint16_t port, uint64_t interval, bool grabVideo, bool grabPhoto, bool grabAudio, bool grabMenu);
|
XBMCVideoChecker(const std::string & address, uint16_t port, bool grabVideo, bool grabPhoto, bool grabAudio, bool grabMenu, bool grabScreensaver, bool enable3DDetection);
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Start polling XBMC
|
/// Start polling XBMC
|
||||||
@ -47,19 +49,34 @@ public:
|
|||||||
void start();
|
void start();
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
|
/// Signal emitted when the grabbing mode changes
|
||||||
void grabbingMode(GrabbingMode grabbingMode);
|
void grabbingMode(GrabbingMode grabbingMode);
|
||||||
|
|
||||||
private slots:
|
/// Signal emitted when a 3D movie is detected
|
||||||
///
|
void videoMode(VideoMode videoMode);
|
||||||
/// Send a request to XBMC
|
|
||||||
///
|
|
||||||
void sendRequest();
|
|
||||||
|
|
||||||
///
|
private slots:
|
||||||
/// Receive a reply from XBMC
|
/// Receive a reply from XBMC
|
||||||
///
|
|
||||||
void receiveReply();
|
void receiveReply();
|
||||||
|
|
||||||
|
/// Called when connected to XBMC
|
||||||
|
void connected();
|
||||||
|
|
||||||
|
/// Called when disconnected from XBMC
|
||||||
|
void disconnected();
|
||||||
|
|
||||||
|
/// Called when a connection error was encountered
|
||||||
|
void connectionError(QAbstractSocket::SocketError error);
|
||||||
|
|
||||||
|
private:
|
||||||
|
/// Set the grabbing mode
|
||||||
|
void setGrabbingMode(GrabbingMode grabbingMode);
|
||||||
|
|
||||||
|
void setScreensaverMode(bool isOnScreensaver);
|
||||||
|
|
||||||
|
/// Set the video mode
|
||||||
|
void setVideoMode(VideoMode videoMode);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/// The network address of the XBMC instance
|
/// The network address of the XBMC instance
|
||||||
const QString _address;
|
const QString _address;
|
||||||
@ -67,27 +84,42 @@ private:
|
|||||||
/// The port number of XBMC
|
/// The port number of XBMC
|
||||||
const uint16_t _port;
|
const uint16_t _port;
|
||||||
|
|
||||||
/// The JSON-RPC request message
|
/// The JSON-RPC message to check the active player
|
||||||
const QByteArray _request;
|
const QString _activePlayerRequest;
|
||||||
|
|
||||||
/// The timer that schedules XBMC queries
|
/// The JSON-RPC message to check the currently playing file
|
||||||
QTimer _timer;
|
const QString _currentPlayingItemRequest;
|
||||||
|
|
||||||
|
/// The JSON-RPC message to check the screensaver
|
||||||
|
const QString _checkScreensaverRequest;
|
||||||
|
|
||||||
/// The QT TCP Socket with connection to XBMC
|
/// The QT TCP Socket with connection to XBMC
|
||||||
QTcpSocket _socket;
|
QTcpSocket _socket;
|
||||||
|
|
||||||
/// Flag indicating whether or not to grab when the XBMC video player is playing
|
/// Flag indicating whether or not to grab when the XBMC video player is playing
|
||||||
bool _grabVideo;
|
const bool _grabVideo;
|
||||||
|
|
||||||
/// Flag indicating whether or not to grab when the XBMC photo player is playing
|
/// Flag indicating whether or not to grab when the XBMC photo player is playing
|
||||||
bool _grabPhoto;
|
const bool _grabPhoto;
|
||||||
|
|
||||||
/// Flag indicating whether or not to grab when the XBMC audio player is playing
|
/// Flag indicating whether or not to grab when the XBMC audio player is playing
|
||||||
bool _grabAudio;
|
const bool _grabAudio;
|
||||||
|
|
||||||
/// Flag indicating whether or not to grab when XBMC is playing nothing (in menu)
|
/// Flag indicating whether or not to grab when XBMC is playing nothing (in menu)
|
||||||
bool _grabMenu;
|
const bool _grabMenu;
|
||||||
|
|
||||||
/// Previous emitted grab state
|
/// Flag inidcating whether or not to grab when the XBMC screensaver is activated
|
||||||
GrabbingMode _previousMode;
|
const bool _grabScreensaver;
|
||||||
|
|
||||||
|
/// Flag indicating wheter or not to enable the detection of 3D movies playing
|
||||||
|
const bool _enable3DDetection;
|
||||||
|
|
||||||
|
/// Flag indicating if XBMC is on screensaver
|
||||||
|
bool _previousScreensaverMode;
|
||||||
|
|
||||||
|
/// Previous emitted grab mode
|
||||||
|
GrabbingMode _previousGrabbingMode;
|
||||||
|
|
||||||
|
/// Previous emitted video mode
|
||||||
|
VideoMode _previousVideoMode;
|
||||||
};
|
};
|
||||||
|
@ -61,10 +61,29 @@ void DispmanxFrameGrabber::setFlags(const int vc_flags)
|
|||||||
_vc_flags = vc_flags;
|
_vc_flags = vc_flags;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DispmanxFrameGrabber::setVideoMode(const VideoMode videoMode)
|
||||||
|
{
|
||||||
|
switch (videoMode) {
|
||||||
|
case VIDEO_3DSBS:
|
||||||
|
vc_dispmanx_rect_set(&_rectangle, 0, 0, _width/2, _height);
|
||||||
|
break;
|
||||||
|
case VIDEO_3DTAB:
|
||||||
|
vc_dispmanx_rect_set(&_rectangle, 0, 0, _width, _height/2);
|
||||||
|
break;
|
||||||
|
case VIDEO_2D:
|
||||||
|
default:
|
||||||
|
vc_dispmanx_rect_set(&_rectangle, 0, 0, _width, _height);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void DispmanxFrameGrabber::grabFrame(Image<ColorRgba> & image)
|
void DispmanxFrameGrabber::grabFrame(Image<ColorRgba> & image)
|
||||||
{
|
{
|
||||||
// Sanity check of the given image size
|
// resize the given image if needed
|
||||||
assert(image.width() == _width && image.height() == _height);
|
if (image.width() != unsigned(_rectangle.width) || image.height() != unsigned(_rectangle.height))
|
||||||
|
{
|
||||||
|
image.resize(_rectangle.width, _rectangle.height);
|
||||||
|
}
|
||||||
|
|
||||||
// Open the connection to the display
|
// Open the connection to the display
|
||||||
_vc_display = vc_dispmanx_display_open(0);
|
_vc_display = vc_dispmanx_display_open(0);
|
||||||
@ -74,7 +93,7 @@ void DispmanxFrameGrabber::grabFrame(Image<ColorRgba> & image)
|
|||||||
|
|
||||||
// Read the snapshot into the memory
|
// Read the snapshot into the memory
|
||||||
void* image_ptr = image.memptr();
|
void* image_ptr = image.memptr();
|
||||||
const unsigned destPitch = _width * sizeof(ColorRgba);
|
const unsigned destPitch = _rectangle.width * sizeof(ColorRgba);
|
||||||
vc_dispmanx_resource_read_data(_vc_resource, &_rectangle, image_ptr, destPitch);
|
vc_dispmanx_resource_read_data(_vc_resource, &_rectangle, image_ptr, destPitch);
|
||||||
|
|
||||||
// Close the displaye
|
// Close the displaye
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
// Utils includes
|
// Utils includes
|
||||||
#include <utils/Image.h>
|
#include <utils/Image.h>
|
||||||
#include <utils/ColorRgba.h>
|
#include <utils/ColorRgba.h>
|
||||||
|
#include <utils/VideoMode.h>
|
||||||
|
|
||||||
///
|
///
|
||||||
/// The DispmanxFrameGrabber is used for creating snapshots of the display (screenshots) with a
|
/// The DispmanxFrameGrabber is used for creating snapshots of the display (screenshots) with a
|
||||||
@ -34,6 +35,12 @@ public:
|
|||||||
///
|
///
|
||||||
void setFlags(const int vc_flags);
|
void setFlags(const int vc_flags);
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Set the video mode (2D/3D)
|
||||||
|
/// @param[in] mode The new video mode
|
||||||
|
///
|
||||||
|
void setVideoMode(const VideoMode videoMode);
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Captures a single snapshot of the display and writes the data to the given image. The
|
/// Captures a single snapshot of the display and writes the data to the given image. The
|
||||||
/// provided image should have the same dimensions as the configured values (_width and
|
/// provided image should have the same dimensions as the configured values (_width and
|
||||||
@ -58,8 +65,7 @@ private:
|
|||||||
int _vc_flags;
|
int _vc_flags;
|
||||||
|
|
||||||
/// With of the captured snapshot [pixels]
|
/// With of the captured snapshot [pixels]
|
||||||
unsigned _width;
|
const unsigned _width;
|
||||||
/// Height of the captured snapshot [pixels]
|
/// Height of the captured snapshot [pixels]
|
||||||
unsigned _height;
|
const unsigned _height;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
@ -81,3 +81,8 @@ void DispmanxWrapper::setGrabbingMode(const GrabbingMode mode)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DispmanxWrapper::setVideoMode(const VideoMode mode)
|
||||||
|
{
|
||||||
|
_frameGrabber->setVideoMode(mode);
|
||||||
|
}
|
||||||
|
@ -255,6 +255,14 @@
|
|||||||
"grabMenu" : {
|
"grabMenu" : {
|
||||||
"type" : "boolean",
|
"type" : "boolean",
|
||||||
"required" : true
|
"required" : true
|
||||||
|
},
|
||||||
|
"grabScreensaver" : {
|
||||||
|
"type" : "boolean",
|
||||||
|
"required" : false
|
||||||
|
},
|
||||||
|
"enable3DDetection" : {
|
||||||
|
"type" : "boolean",
|
||||||
|
"required" : false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"additionalProperties" : false
|
"additionalProperties" : false
|
||||||
|
@ -1,52 +1,50 @@
|
|||||||
// Qt includes
|
// Qt includes
|
||||||
#include <QUrl>
|
#include <QUrl>
|
||||||
|
#include <QRegExp>
|
||||||
|
#include <QStringRef>
|
||||||
|
|
||||||
#include <xbmcvideochecker/XBMCVideoChecker.h>
|
#include <xbmcvideochecker/XBMCVideoChecker.h>
|
||||||
|
|
||||||
XBMCVideoChecker::XBMCVideoChecker(const std::string & address, uint16_t port, uint64_t interval_ms, bool grabVideo, bool grabPhoto, bool grabAudio, bool grabMenu) :
|
// Request player example:
|
||||||
|
// {"id":666,"jsonrpc":"2.0","method":"Player.GetActivePlayers"}
|
||||||
|
// {"id":666,"jsonrpc":"2.0","result":[{"playerid":1,"type":"video"}]}
|
||||||
|
|
||||||
|
// Request playing item example:
|
||||||
|
// {"id":667,"jsonrpc":"2.0","method":"Player.GetItem","params":{"playerid":1,"properties":["file"]}}
|
||||||
|
// {"id":667,"jsonrpc":"2.0","result":{"item":{"file":"smb://xbmc:xbmc@192.168.53.12/video/Movies/Avatar (2009)/Avatar.mkv","label":"Avatar","type":"unknown"}}}
|
||||||
|
|
||||||
|
// Request if screensaver is on
|
||||||
|
// {"id":668,"jsonrpc":"2.0","method":"XBMC.GetInfoBooleans","params":{"booleans":["System.ScreenSaverActive"]}}
|
||||||
|
// {"id":668,"jsonrpc":"2.0","result":{"System.ScreenSaverActive":false}}
|
||||||
|
|
||||||
|
XBMCVideoChecker::XBMCVideoChecker(const std::string & address, uint16_t port, bool grabVideo, bool grabPhoto, bool grabAudio, bool grabMenu, bool grabScreensaver, bool enable3DDetection) :
|
||||||
QObject(),
|
QObject(),
|
||||||
_address(QString::fromStdString(address)),
|
_address(QString::fromStdString(address)),
|
||||||
_port(port),
|
_port(port),
|
||||||
_request(R"({"jsonrpc":"2.0","method":"Player.GetActivePlayers","id":666})"),
|
_activePlayerRequest(R"({"id":666,"jsonrpc":"2.0","method":"Player.GetActivePlayers"})"),
|
||||||
_timer(),
|
_currentPlayingItemRequest(R"({"id":667,"jsonrpc":"2.0","method":"Player.GetItem","params":{"playerid":%1,"properties":["file"]}})"),
|
||||||
|
_checkScreensaverRequest(R"({"id":668,"jsonrpc":"2.0","method":"XBMC.GetInfoBooleans","params":{"booleans":["System.ScreenSaverActive"]}})"),
|
||||||
_socket(),
|
_socket(),
|
||||||
_grabVideo(grabVideo),
|
_grabVideo(grabVideo),
|
||||||
_grabPhoto(grabPhoto),
|
_grabPhoto(grabPhoto),
|
||||||
_grabAudio(grabAudio),
|
_grabAudio(grabAudio),
|
||||||
_grabMenu(grabMenu),
|
_grabMenu(grabMenu),
|
||||||
_previousMode(GRABBINGMODE_INVALID)
|
_grabScreensaver(grabScreensaver),
|
||||||
|
_enable3DDetection(enable3DDetection),
|
||||||
|
_previousScreensaverMode(false),
|
||||||
|
_previousGrabbingMode(GRABBINGMODE_INVALID),
|
||||||
|
_previousVideoMode(VIDEO_2D)
|
||||||
{
|
{
|
||||||
// setup timer
|
|
||||||
_timer.setSingleShot(false);
|
|
||||||
_timer.setInterval(interval_ms);
|
|
||||||
connect(&_timer, SIGNAL(timeout()), this, SLOT(sendRequest()));
|
|
||||||
|
|
||||||
// setup socket
|
// setup socket
|
||||||
connect(&_socket, SIGNAL(readyRead()), this, SLOT(receiveReply()));
|
connect(&_socket, SIGNAL(readyRead()), this, SLOT(receiveReply()));
|
||||||
|
connect(&_socket, SIGNAL(disconnected()), this, SLOT(disconnected()));
|
||||||
|
connect(&_socket, SIGNAL(connected()), this, SLOT(connected()));
|
||||||
|
connect(&_socket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(connectionError(QAbstractSocket::SocketError)));
|
||||||
}
|
}
|
||||||
|
|
||||||
void XBMCVideoChecker::start()
|
void XBMCVideoChecker::start()
|
||||||
{
|
{
|
||||||
_timer.start();
|
disconnected();
|
||||||
}
|
|
||||||
|
|
||||||
void XBMCVideoChecker::sendRequest()
|
|
||||||
{
|
|
||||||
switch (_socket.state())
|
|
||||||
{
|
|
||||||
case QTcpSocket::UnconnectedState:
|
|
||||||
// not connected. try to connect
|
|
||||||
std::cout << "Connecting to " << _address.toStdString() << ":" << _port << " to check XBMC player status" << std::endl;
|
|
||||||
_socket.connectToHost(_address, _port);
|
|
||||||
break;
|
|
||||||
case QTcpSocket::ConnectedState:
|
|
||||||
// write the request on the socket
|
|
||||||
_socket.write(_request);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
// whatever. let's check again at the next timer tick
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void XBMCVideoChecker::receiveReply()
|
void XBMCVideoChecker::receiveReply()
|
||||||
@ -54,62 +52,195 @@ void XBMCVideoChecker::receiveReply()
|
|||||||
// expect that the reply is received as a single message. Probably oke considering the size of the expected reply
|
// expect that the reply is received as a single message. Probably oke considering the size of the expected reply
|
||||||
QString reply(_socket.readAll());
|
QString reply(_socket.readAll());
|
||||||
|
|
||||||
// check if the resply is a reply to one of my requests
|
std::cout << "Message from XBMC: " << reply.toStdString() << std::endl;
|
||||||
if (!reply.contains("\"id\":666"))
|
|
||||||
|
if (reply.contains("\"method\":\"Player.OnPlay\""))
|
||||||
{
|
{
|
||||||
// probably not. Leave this mreply as is and don't act on it
|
// send a request for the current player state
|
||||||
|
_socket.write(_activePlayerRequest.toUtf8());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
else if (reply.contains("\"method\":\"Player.OnStop\""))
|
||||||
|
{
|
||||||
|
// the player has stopped
|
||||||
|
setGrabbingMode(_grabMenu ? GRABBINGMODE_MENU : GRABBINGMODE_OFF);
|
||||||
|
setVideoMode(VIDEO_2D);
|
||||||
|
}
|
||||||
|
else if (reply.contains("\"method\":\"GUI.OnScreensaverActivated\""))
|
||||||
|
{
|
||||||
|
setScreensaverMode(!_grabScreensaver);
|
||||||
|
}
|
||||||
|
else if (reply.contains("\"method\":\"GUI.OnScreensaverDeactivated\""))
|
||||||
|
{
|
||||||
|
setScreensaverMode(false);
|
||||||
|
}
|
||||||
|
else if (reply.contains("\"id\":666"))
|
||||||
|
{
|
||||||
|
// Result of Player.GetActivePlayers
|
||||||
|
|
||||||
GrabbingMode newMode = GRABBINGMODE_INVALID;
|
// always start a new video in 2D mode
|
||||||
if (reply.contains("video"))
|
emit videoMode(VIDEO_2D);
|
||||||
{
|
|
||||||
// video is playing
|
|
||||||
newMode = _grabVideo ? GRABBINGMODE_VIDEO : GRABBINGMODE_OFF;
|
|
||||||
}
|
|
||||||
else if (reply.contains("picture"))
|
|
||||||
{
|
|
||||||
// picture viewer is playing
|
|
||||||
newMode = _grabPhoto ? GRABBINGMODE_PHOTO : GRABBINGMODE_OFF;
|
|
||||||
}
|
|
||||||
else if (reply.contains("audio"))
|
|
||||||
{
|
|
||||||
// audio is playing
|
|
||||||
newMode = _grabAudio ? GRABBINGMODE_AUDIO : GRABBINGMODE_OFF;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Nothing is playing.
|
|
||||||
newMode = _grabMenu ? GRABBINGMODE_MENU : GRABBINGMODE_OFF;
|
|
||||||
}
|
|
||||||
|
|
||||||
// emit new state if applicable
|
if (reply.contains("video"))
|
||||||
if (newMode != _previousMode && newMode != GRABBINGMODE_INVALID)
|
|
||||||
{
|
|
||||||
switch (newMode)
|
|
||||||
{
|
{
|
||||||
case GRABBINGMODE_VIDEO:
|
// video is playing
|
||||||
std::cout << "XBMC checker: switching to VIDEO mode" << std::endl;
|
setGrabbingMode(_grabVideo ? GRABBINGMODE_VIDEO : GRABBINGMODE_OFF);
|
||||||
break;
|
|
||||||
case GRABBINGMODE_PHOTO:
|
|
||||||
std::cout << "XBMC checker: switching to PHOTO mode" << std::endl;
|
|
||||||
break;
|
|
||||||
case GRABBINGMODE_AUDIO:
|
|
||||||
std::cout << "XBMC checker: switching to AUDIO mode" << std::endl;
|
|
||||||
break;
|
|
||||||
case GRABBINGMODE_MENU:
|
|
||||||
std::cout << "XBMC checker: switching to MENU mode" << std::endl;
|
|
||||||
break;
|
|
||||||
case GRABBINGMODE_OFF:
|
|
||||||
std::cout << "XBMC checker: switching to OFF mode" << std::endl;
|
|
||||||
break;
|
|
||||||
case GRABBINGMODE_INVALID:
|
|
||||||
std::cout << "XBMC checker: switching to INVALID mode" << std::endl;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
emit grabbingMode(newMode);
|
// we need to get the filename
|
||||||
_previousMode = newMode;
|
// first retrieve the playerid
|
||||||
|
QString key = "\"playerid\":";
|
||||||
|
QRegExp regex(key + "(\\d+)");
|
||||||
|
int pos = regex.indexIn(reply);
|
||||||
|
if (pos > 0)
|
||||||
|
{
|
||||||
|
// now request info of the playing item
|
||||||
|
QStringRef idText(&reply, pos + key.length(), regex.matchedLength() - key.length());
|
||||||
|
_socket.write(_currentPlayingItemRequest.arg(idText.toString()).toUtf8());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (reply.contains("picture"))
|
||||||
|
{
|
||||||
|
// picture viewer is playing
|
||||||
|
setGrabbingMode(_grabPhoto ? GRABBINGMODE_PHOTO : GRABBINGMODE_OFF);
|
||||||
|
}
|
||||||
|
else if (reply.contains("audio"))
|
||||||
|
{
|
||||||
|
// audio is playing
|
||||||
|
setGrabbingMode(_grabAudio ? GRABBINGMODE_AUDIO : GRABBINGMODE_OFF);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Nothing is playing.
|
||||||
|
setGrabbingMode(_grabMenu ? GRABBINGMODE_MENU : GRABBINGMODE_OFF);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (reply.contains("\"id\":667"))
|
||||||
|
{
|
||||||
|
// result of Player.GetItem
|
||||||
|
// TODO: what if the filename contains a '"'. In Json this should have been escaped
|
||||||
|
QRegExp regex("\"file\":\"((?!\").)*\"");
|
||||||
|
int pos = regex.indexIn(reply);
|
||||||
|
if (pos > 0)
|
||||||
|
{
|
||||||
|
QStringRef filename = QStringRef(&reply, pos+8, regex.matchedLength()-9);
|
||||||
|
if (filename.contains("3DSBS", Qt::CaseInsensitive) || filename.contains("HSBS", Qt::CaseInsensitive))
|
||||||
|
{
|
||||||
|
setVideoMode(VIDEO_3DSBS);
|
||||||
|
}
|
||||||
|
else if (filename.contains("3DTAB", Qt::CaseInsensitive) || filename.contains("HTAB", Qt::CaseInsensitive))
|
||||||
|
{
|
||||||
|
setVideoMode(VIDEO_3DTAB);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
setVideoMode(VIDEO_2D);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (reply.contains("\"id\":668"))
|
||||||
|
{
|
||||||
|
// result of System.ScreenSaverActive
|
||||||
|
bool active = reply.contains("\"System.ScreenSaverActive\":true");
|
||||||
|
setScreensaverMode(!_grabScreensaver && active);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void XBMCVideoChecker::connected()
|
||||||
|
{
|
||||||
|
std::cout << "XBMC Connected" << std::endl;
|
||||||
|
|
||||||
|
// send a request for the current player state
|
||||||
|
_socket.write(_activePlayerRequest.toUtf8());
|
||||||
|
_socket.write(_checkScreensaverRequest.toUtf8());
|
||||||
|
}
|
||||||
|
|
||||||
|
void XBMCVideoChecker::disconnected()
|
||||||
|
{
|
||||||
|
std::cout << "XBMC Disconnected" << std::endl;
|
||||||
|
|
||||||
|
// try to connect
|
||||||
|
_socket.connectToHost(_address, _port);
|
||||||
|
}
|
||||||
|
|
||||||
|
void XBMCVideoChecker::connectionError(QAbstractSocket::SocketError)
|
||||||
|
{
|
||||||
|
std::cout << "XBMC Connection error" << std::endl;
|
||||||
|
|
||||||
|
// try to connect again in 1 second
|
||||||
|
QTimer::singleShot(1000, this, SLOT(disconnected()));
|
||||||
|
}
|
||||||
|
|
||||||
|
void XBMCVideoChecker::setGrabbingMode(GrabbingMode newGrabbingMode)
|
||||||
|
{
|
||||||
|
if (newGrabbingMode == _previousGrabbingMode)
|
||||||
|
{
|
||||||
|
// no change
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (newGrabbingMode)
|
||||||
|
{
|
||||||
|
case GRABBINGMODE_VIDEO:
|
||||||
|
std::cout << "XBMC checker: switching to VIDEO mode" << std::endl;
|
||||||
|
break;
|
||||||
|
case GRABBINGMODE_PHOTO:
|
||||||
|
std::cout << "XBMC checker: switching to PHOTO mode" << std::endl;
|
||||||
|
break;
|
||||||
|
case GRABBINGMODE_AUDIO:
|
||||||
|
std::cout << "XBMC checker: switching to AUDIO mode" << std::endl;
|
||||||
|
break;
|
||||||
|
case GRABBINGMODE_MENU:
|
||||||
|
std::cout << "XBMC checker: switching to MENU mode" << std::endl;
|
||||||
|
break;
|
||||||
|
case GRABBINGMODE_OFF:
|
||||||
|
std::cout << "XBMC checker: switching to OFF mode" << std::endl;
|
||||||
|
break;
|
||||||
|
case GRABBINGMODE_INVALID:
|
||||||
|
std::cout << "XBMC checker: switching to INVALID mode" << std::endl;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// only emit the new state when we want to grab in screensaver mode or when the screensaver is deactivated
|
||||||
|
if (!_previousScreensaverMode)
|
||||||
|
{
|
||||||
|
emit grabbingMode(newGrabbingMode);
|
||||||
|
}
|
||||||
|
_previousGrabbingMode = newGrabbingMode;
|
||||||
|
}
|
||||||
|
|
||||||
|
void XBMCVideoChecker::setScreensaverMode(bool isOnScreensaver)
|
||||||
|
{
|
||||||
|
if (isOnScreensaver == _previousScreensaverMode)
|
||||||
|
{
|
||||||
|
// no change
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
emit grabbingMode(isOnScreensaver ? GRABBINGMODE_OFF : _previousGrabbingMode);
|
||||||
|
_previousScreensaverMode = isOnScreensaver;
|
||||||
|
}
|
||||||
|
|
||||||
|
void XBMCVideoChecker::setVideoMode(VideoMode newVideoMode)
|
||||||
|
{
|
||||||
|
if (newVideoMode == _previousVideoMode)
|
||||||
|
{
|
||||||
|
// no change
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (newVideoMode)
|
||||||
|
{
|
||||||
|
case VIDEO_2D:
|
||||||
|
std::cout << "XBMC checker: switching to 2D mode" << std::endl;
|
||||||
|
break;
|
||||||
|
case VIDEO_3DSBS:
|
||||||
|
std::cout << "XBMC checker: switching to 3D SBS mode" << std::endl;
|
||||||
|
break;
|
||||||
|
case VIDEO_3DTAB:
|
||||||
|
std::cout << "XBMC checker: switching to 3D TAB mode" << std::endl;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
emit videoMode(newVideoMode);
|
||||||
|
_previousVideoMode = newVideoMode;
|
||||||
|
}
|
||||||
|
@ -123,11 +123,12 @@ int main(int argc, char** argv)
|
|||||||
xbmcVideoChecker = new XBMCVideoChecker(
|
xbmcVideoChecker = new XBMCVideoChecker(
|
||||||
videoCheckerConfig["xbmcAddress"].asString(),
|
videoCheckerConfig["xbmcAddress"].asString(),
|
||||||
videoCheckerConfig["xbmcTcpPort"].asUInt(),
|
videoCheckerConfig["xbmcTcpPort"].asUInt(),
|
||||||
1000,
|
|
||||||
videoCheckerConfig["grabVideo"].asBool(),
|
videoCheckerConfig["grabVideo"].asBool(),
|
||||||
videoCheckerConfig["grabPictures"].asBool(),
|
videoCheckerConfig["grabPictures"].asBool(),
|
||||||
videoCheckerConfig["grabAudio"].asBool(),
|
videoCheckerConfig["grabAudio"].asBool(),
|
||||||
videoCheckerConfig["grabMenu"].asBool());
|
videoCheckerConfig["grabMenu"].asBool(),
|
||||||
|
videoCheckerConfig.get("grabScreensaver", true).asBool(),
|
||||||
|
videoCheckerConfig.get("enable3DDetection", true).asBool());
|
||||||
|
|
||||||
xbmcVideoChecker->start();
|
xbmcVideoChecker->start();
|
||||||
std::cout << "XBMC video checker created and started" << std::endl;
|
std::cout << "XBMC video checker created and started" << std::endl;
|
||||||
@ -148,6 +149,7 @@ int main(int argc, char** argv)
|
|||||||
if (xbmcVideoChecker != nullptr)
|
if (xbmcVideoChecker != nullptr)
|
||||||
{
|
{
|
||||||
QObject::connect(xbmcVideoChecker, SIGNAL(grabbingMode(GrabbingMode)), dispmanx, SLOT(setGrabbingMode(GrabbingMode)));
|
QObject::connect(xbmcVideoChecker, SIGNAL(grabbingMode(GrabbingMode)), dispmanx, SLOT(setGrabbingMode(GrabbingMode)));
|
||||||
|
QObject::connect(xbmcVideoChecker, SIGNAL(videoMode(VideoMode)), dispmanx, SLOT(setVideoMode(VideoMode)));
|
||||||
}
|
}
|
||||||
|
|
||||||
dispmanx->start();
|
dispmanx->start();
|
||||||
|
@ -12,8 +12,8 @@ public:
|
|||||||
// empty
|
// empty
|
||||||
}
|
}
|
||||||
|
|
||||||
int write(const std::vector<ColorRgb> &ledValues) {}
|
int write(const std::vector<ColorRgb> &ledValues) { return 0; }
|
||||||
int switchOff() {};
|
int switchOff() { return 0; }
|
||||||
|
|
||||||
void writeTestSequence()
|
void writeTestSequence()
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user