mirror of
https://github.com/jellyfin/jellyfin-desktop.git
synced 2026-10-26 16:45:24 +00:00
Add basic support for Roku HTTP protocol
This commit is contained in:
1 parent
c2842aa430
commit
732498a8d8
8 files changed
+203
-28
No files matched your search
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"name": "Roku HTTP input",
|
||||
"idmatcher": "roku",
|
||||
"mapping": {
|
||||
"Up": "up",
|
||||
"Down": "down",
|
||||
"Left": "left",
|
||||
"Right": "right",
|
||||
"Select": "enter",
|
||||
"Play": "play_pause",
|
||||
"Home": "home",
|
||||
"Back": "back",
|
||||
"Fwd": "seek_forward",
|
||||
"Rev": "seek_backward",
|
||||
"Info": "host:toggleDebug",
|
||||
"Backspace": "back",
|
||||
"Enter": "enter",
|
||||
"Lit_([0-9])": "%1",
|
||||
"Lit_([A-Za-z])": "jump+%1"
|
||||
}
|
||||
}
|
||||
@@ -13,7 +13,6 @@
|
||||
#include "system/UpdaterComponent.h"
|
||||
#include "settings/SettingsComponent.h"
|
||||
#include "remote/RemoteComponent.h"
|
||||
#include "remote/RokuRemoteComponent.h"
|
||||
|
||||
#include "server/HTTPServer.h"
|
||||
|
||||
@@ -70,7 +69,6 @@ void ComponentManager::initialize()
|
||||
registerComponent(&RemoteComponent::Get());
|
||||
registerComponent(&PlayerComponent::Get());
|
||||
registerComponent(&PowerComponent::Get());
|
||||
registerComponent(&RokuRemoteComponent::Get());
|
||||
|
||||
#if KONVERGO_OPENELEC
|
||||
registerComponent(&OESystemComponent::Get());
|
||||
|
||||
@@ -6,6 +6,8 @@ set(INPUT_SRCS
|
||||
InputKeyboard.h
|
||||
InputSocket.h
|
||||
InputSocket.cpp
|
||||
InputRoku.cpp
|
||||
InputRoku.h
|
||||
)
|
||||
|
||||
if(APPLE)
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#include "power/PowerComponent.h"
|
||||
#include "InputKeyboard.h"
|
||||
#include "InputSocket.h"
|
||||
#include "InputRoku.h"
|
||||
|
||||
#ifdef Q_OS_MAC
|
||||
#include "apple/InputAppleRemote.h"
|
||||
@@ -58,6 +59,7 @@ bool InputComponent::componentInitialize()
|
||||
|
||||
addInput(&InputKeyboard::Get());
|
||||
addInput(new InputSocket(this));
|
||||
addInput(new InputRoku(this));
|
||||
|
||||
#ifdef Q_OS_MAC
|
||||
addInput(new InputAppleRemote(this));
|
||||
|
||||
@@ -0,0 +1,149 @@
|
||||
//
|
||||
// Created by Tobias Hieta on 02/02/16.
|
||||
//
|
||||
|
||||
#include "InputRoku.h"
|
||||
#include "QsLog.h"
|
||||
|
||||
#include "qhttpserverresponse.hpp"
|
||||
#include "qhttpserverrequest.hpp"
|
||||
|
||||
#include <QUrl>
|
||||
#include <QXmlStreamWriter>
|
||||
|
||||
using namespace qhttp::server;
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////
|
||||
bool InputRoku::initInput()
|
||||
{
|
||||
m_server = new QHttpServer(this);
|
||||
|
||||
if (!m_server->listen(QHostAddress::Any, 8060))
|
||||
{
|
||||
QLOG_WARN() << "Failed to start roku component on port 8060";
|
||||
return false;
|
||||
}
|
||||
|
||||
connect(m_server, &QHttpServer::newRequest, this, &InputRoku::handleRequest);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////
|
||||
void InputRoku::handleRequest(QHttpRequest* request, QHttpResponse* response)
|
||||
{
|
||||
if (request->url().path() == "/query/apps")
|
||||
{
|
||||
handleQueryApps(request, response);
|
||||
}
|
||||
else if (request->url().path() == "/query/device-info")
|
||||
{
|
||||
handleQueryDeviceInfo(request, response);
|
||||
}
|
||||
else if (request->url().path().startsWith("/keypress/"))
|
||||
{
|
||||
handleKeyPress(request, response);
|
||||
}
|
||||
else
|
||||
{
|
||||
response->setStatusCode(qhttp::ESTATUS_NOT_FOUND);
|
||||
response->end();
|
||||
}
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////
|
||||
void InputRoku::handleQueryApps(QHttpRequest* request, QHttpResponse* response)
|
||||
{
|
||||
if (request->method() != qhttp::EHTTP_GET)
|
||||
{
|
||||
response->setStatusCode(qhttp::ESTATUS_METHOD_NOT_ALLOWED);
|
||||
response->end();
|
||||
return;
|
||||
}
|
||||
|
||||
QByteArray data;
|
||||
QXmlStreamWriter writer(&data);
|
||||
writer.setAutoFormatting(true);
|
||||
writer.writeStartDocument();
|
||||
writer.writeStartElement("apps");
|
||||
writer.writeStartElement("app");
|
||||
writer.writeAttribute("id", "1");
|
||||
writer.writeCharacters("Plex Media Player");
|
||||
writer.writeEndElement(); // app
|
||||
writer.writeEndElement(); // apps
|
||||
writer.writeEndDocument();
|
||||
|
||||
response->setStatusCode(qhttp::ESTATUS_OK);
|
||||
response->write(data);
|
||||
response->end();
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////
|
||||
void InputRoku::handleQueryDeviceInfo(QHttpRequest* request, QHttpResponse* response)
|
||||
{
|
||||
|
||||
QByteArray data;
|
||||
QXmlStreamWriter writer(&data);
|
||||
writer.setAutoFormatting(true);
|
||||
|
||||
writer.writeStartDocument();
|
||||
writer.writeStartElement("device-info");
|
||||
writer.writeEndElement(); // device-info
|
||||
writer.writeEndDocument();
|
||||
|
||||
response->setStatusCode(qhttp::ESTATUS_OK);
|
||||
response->write(data);
|
||||
response->end();
|
||||
|
||||
/*
|
||||
<device-info>
|
||||
<udn>015e5108-9000-1046-8035-b0a737964dfb</udn>
|
||||
<serial-number>1GU48T017973</serial-number>
|
||||
<device-id>1GU48T017973</device-id>
|
||||
<vendor-name>Roku</vendor-name>
|
||||
<model-number>4200X</model-number>
|
||||
<model-name>Roku 3</model-name>
|
||||
<wifi-mac>b0:a7:37:96:4d:fb</wifi-mac>
|
||||
<ethernet-mac>b0:a7:37:96:4d:fa</ethernet-mac>
|
||||
<network-type>ethernet</network-type>
|
||||
<user-device-name/>
|
||||
<software-version>7.00</software-version>
|
||||
<software-build>09021</software-build>
|
||||
<secure-device>true</secure-device>
|
||||
<language>en</language>
|
||||
<country>US</country>
|
||||
<locale>en_US</locale>
|
||||
<time-zone>US/Pacific</time-zone>
|
||||
<time-zone-offset>-480</time-zone-offset>
|
||||
<power-mode>PowerOn</power-mode>
|
||||
<developer-enabled>true</developer-enabled>
|
||||
<keyed-developer-id>70f6ed9c90cf60718a26f3a7c3e5af1c3ec29558</keyed-developer-id>
|
||||
<search-enabled>true</search-enabled>
|
||||
<voice-search-enabled>true</voice-search-enabled>
|
||||
<notifications-enabled>true</notifications-enabled>
|
||||
<notifications-first-use>false</notifications-first-use>
|
||||
<headphones-connected>false</headphones-connected>
|
||||
</device-info>
|
||||
*/
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////
|
||||
void InputRoku::handleKeyPress(QHttpRequest* request, QHttpResponse* response)
|
||||
{
|
||||
QString path = request->url().path();
|
||||
QStringList pathsplit = path.split("/");
|
||||
if (pathsplit.count() != 3)
|
||||
{
|
||||
response->setStatusCode(qhttp::ESTATUS_BAD_REQUEST);
|
||||
response->end();
|
||||
return;
|
||||
}
|
||||
|
||||
QLOG_DEBUG() << "We got roku input:" << pathsplit.value(2);
|
||||
|
||||
emit receivedInput("roku", pathsplit.value(2));
|
||||
|
||||
response->setStatusCode(qhttp::ESTATUS_OK);
|
||||
response->end();
|
||||
return;
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
//
|
||||
// Created by Tobias Hieta on 02/02/16.
|
||||
//
|
||||
|
||||
#ifndef PLEXMEDIAPLAYER_ROKUREMOTECOMPONENT_H
|
||||
#define PLEXMEDIAPLAYER_ROKUREMOTECOMPONENT_H
|
||||
|
||||
#include "input/InputComponent.h"
|
||||
#include "qhttpserver.hpp"
|
||||
|
||||
class InputRoku : public InputBase
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit InputRoku(QObject* parent = 0) : InputBase(parent) { }
|
||||
virtual bool initInput() override;
|
||||
virtual const char* inputName() override { return "roku"; };
|
||||
|
||||
private:
|
||||
void handleRequest(qhttp::server::QHttpRequest* request, qhttp::server::QHttpResponse* response);
|
||||
void handleQueryApps(qhttp::server::QHttpRequest* request, qhttp::server::QHttpResponse* response);
|
||||
void handleKeyPress(qhttp::server::QHttpRequest* request, qhttp::server::QHttpResponse* response);
|
||||
void handleQueryDeviceInfo(qhttp::server::QHttpRequest* request, qhttp::server::QHttpResponse* response);
|
||||
|
||||
qhttp::server::QHttpServer* m_server;
|
||||
};
|
||||
|
||||
#endif //PLEXMEDIAPLAYER_ROKUREMOTECOMPONENT_H
|
||||
@@ -1,5 +0,0 @@
|
||||
//
|
||||
// Created by Tobias Hieta on 02/02/16.
|
||||
//
|
||||
|
||||
#include "RokuRemoteComponent.h"
|
||||
@@ -1,21 +0,0 @@
|
||||
//
|
||||
// Created by Tobias Hieta on 02/02/16.
|
||||
//
|
||||
|
||||
#ifndef PLEXMEDIAPLAYER_ROKUREMOTECOMPONENT_H
|
||||
#define PLEXMEDIAPLAYER_ROKUREMOTECOMPONENT_H
|
||||
|
||||
#include "ComponentManager.h"
|
||||
|
||||
class RokuRemoteComponent : public ComponentBase
|
||||
{
|
||||
Q_OBJECT
|
||||
DEFINE_SINGLETON(RokuRemoteComponent);
|
||||
|
||||
public:
|
||||
virtual bool componentInitialize() override { return true; };
|
||||
virtual const char* componentName() override { return "rokuremote"; };
|
||||
virtual bool componentExport() override { return false; };
|
||||
};
|
||||
|
||||
#endif //PLEXMEDIAPLAYER_ROKUREMOTECOMPONENT_H
|
||||
Reference in new issue
Block a user