Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,5 @@
/dist/scripts/maketarball.sh
/debian/changelog
_codeql_detected_source_root
.qtcreator/
obj-x86_64-linux-gnu/
40 changes: 40 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,11 @@ if(UNIX AND NOT APPLE)
endif()
find_package(X11 COMPONENTS X11_xcb)
endif()
find_package(Qt6 REQUIRED COMPONENTS Protobuf)
if(NOT Protobuf_FOUND)
message(STATUS "Missing Protobuf compiler.")
endif()

pkg_check_modules(GLIB REQUIRED IMPORTED_TARGET glib-2.0)
pkg_check_modules(GOBJECT REQUIRED IMPORTED_TARGET gobject-2.0)
if(NOT APPLE)
Expand Down Expand Up @@ -352,6 +357,10 @@ optional_component(EBUR128 ON "EBU R 128 loudness normalization"
DEPENDS "libebur128" LIBEBUR128_FOUND
)

optional_component(NETWORKREMOTE ON "Network Remote"
DEPENDS "Protobuf" Protobuf_FOUND
)

if(APPLE)
optional_component(SPARKLE ON "Sparkle integration"
DEPENDS "Sparkle" SPARKLE
Expand Down Expand Up @@ -1485,6 +1494,31 @@ optional_source(HAVE_QOBUZ
src/settings/qobuzsettingspage.ui
)

optional_source(HAVE_NETWORKREMOTE
SOURCES
src/networkremote/networkremote.cpp
src/networkremote/networkremotetcpserver.cpp
src/networkremote/networkremotesettings.cpp
src/networkremote/networkremoteclient.cpp
src/networkremote/networkremoteclientmanager.cpp
src/networkremote/networkremoteincomingmsg.cpp
src/networkremote/networkremoteoutgoingmsg.cpp
src/networkremote/RemoteMessages.proto
src/settings/networkremotesettingspage.cpp
HEADERS
src/networkremote/networkremote.h
src/networkremote/networkremotetcpserver.h
src/networkremote/networkremotesettings.h
src/networkremote/networkremoteclient.h
src/networkremote/networkremoteclientmanager.h
src/networkremote/networkremoteincomingmsg.h
src/networkremote/networkremoteoutgoingmsg.h
src/settings/networkremotesettingspage.h
UI
src/settings/networkremotesettingspage.ui
)


qt_wrap_cpp(SOURCES ${HEADERS})
qt_wrap_ui(SOURCES ${UI})
qt_add_resources(SOURCES data/data.qrc data/icons.qrc)
Expand Down Expand Up @@ -1586,6 +1620,12 @@ if(APPLE)
endif()
endif()

if(HAVE_NETWORKREMOTE)
add_subdirectory(src/networkremote)
target_link_libraries(strawberry_lib PRIVATE Qt6::Protobuf)
target_link_libraries(strawberry PUBLIC strawberry_lib lib-networkremote)
endif()

target_link_libraries(strawberry PUBLIC strawberry_lib)

if(NOT APPLE)
Expand Down
4 changes: 4 additions & 0 deletions data/icons.qrc
Original file line number Diff line number Diff line change
Expand Up @@ -506,5 +506,9 @@
<file>icons/22x22/somafm.png</file>
<file>icons/22x22/radioparadise.png</file>
<file>icons/22x22/musicbrainz.png</file>
<file>icons/22x22/network-remote.png</file>
<file>icons/32x32/network-remote.png</file>
<file>icons/64x64/network-remote.png</file>
<file>icons/128x128/network-remote.png</file>
</qresource>
</RCC>
Binary file added data/icons/128x128/network-remote.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added data/icons/22x22/network-remote.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added data/icons/32x32/network-remote.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added data/icons/48x28
Binary file not shown.
Binary file added data/icons/64x64/network-remote.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added data/icons/full/network-remote.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions src/config.h.in
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
#cmakedefine HAVE_SPOTIFY
#cmakedefine HAVE_QOBUZ
#cmakedefine HAVE_DISCORD_RPC
#cmakedefine HAVE_NETWORKREMOTE

#cmakedefine HAVE_TAGLIB_DSFFILE
#cmakedefine HAVE_TAGLIB_DSDIFFFILE
Expand Down
23 changes: 22 additions & 1 deletion src/core/application.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
* Copyright 2012, David Sansome <me@davidsansome.com>
* Copyright 2012, 2014, John Maguire <john.maguire@gmail.com>
* Copyright 2018-2025, Jonas Kvinge <jonas@jkvinge.net>
* Copyright 2025, Leopold List <leo@zudiewiener.com>
*
* Strawberry is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
Expand Down Expand Up @@ -110,6 +111,10 @@
# include "moodbar/moodbarloader.h"
#endif

#ifdef HAVE_NETWORKREMOTE
# include "networkremote/networkremote.h"
#endif

#include "radios/radioservices.h"
#include "radios/radiobackend.h"

Expand Down Expand Up @@ -216,6 +221,13 @@ class ApplicationImpl {
#ifdef HAVE_MOODBAR
moodbar_loader_([app]() { return new MoodbarLoader(app); }),
moodbar_controller_([app]() { return new MoodbarController(app->player(), app->moodbar_loader()); }),
#endif
#ifdef HAVE_NETWORKREMOTE
network_remote_([app]() {
qLog(Debug) << "Moving to new thread";
NetworkRemote *remote = new NetworkRemote(app->player(), app);
app->MoveToNewThread(remote);
return remote;}),
#endif
lastfm_import_([app]() { return new LastFMImport(app->network()); })
{}
Expand All @@ -241,6 +253,9 @@ class ApplicationImpl {
#ifdef HAVE_MOODBAR
Lazy<MoodbarLoader> moodbar_loader_;
Lazy<MoodbarController> moodbar_controller_;
#endif
#ifdef HAVE_NETWORKREMOTE
Lazy<NetworkRemote> network_remote_;
#endif
Lazy<LastFMImport> lastfm_import_;

Expand All @@ -261,7 +276,7 @@ Application::Application(QObject *parent)
device_finders()->Init();
collection()->Init();
tagreader_client();

network_remote()->Init();
}

Application::~Application() {
Expand Down Expand Up @@ -324,6 +339,9 @@ void Application::Exit() {
<< &*albumcover_loader()
<< &*device_manager()
<< &*streaming_services()
#ifdef HAVE_NETWORKREMOTE
<< &*network_remote()
#endif
<< &*radio_services()->radio_backend();

QObject::connect(&*tagreader_client(), &TagReaderClient::ExitFinished, this, &Application::ExitReceived);
Expand Down Expand Up @@ -390,3 +408,6 @@ SharedPtr<LastFMImport> Application::lastfm_import() const { return p_->lastfm_i
SharedPtr<MoodbarController> Application::moodbar_controller() const { return p_->moodbar_controller_.ptr(); }
SharedPtr<MoodbarLoader> Application::moodbar_loader() const { return p_->moodbar_loader_.ptr(); }
#endif
#ifdef HAVE_NETWORKREMOTE
SharedPtr<NetworkRemote> Application::network_remote() const { return p_->network_remote_.ptr();}
#endif
7 changes: 7 additions & 0 deletions src/core/application.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
* Copyright 2012, David Sansome <me@davidsansome.com>
* Copyright 2012, 2014, John Maguire <john.maguire@gmail.com>
* Copyright 2018-2024, Jonas Kvinge <jonas@jkvinge.net>
* Copyright 2025, Leopold List <leo@zudiewiener.com>
*
* Strawberry is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
Expand Down Expand Up @@ -63,6 +64,9 @@ class RadioServices;
class MoodbarController;
class MoodbarLoader;
#endif
#ifdef HAVE_NETWORKREMOTE
class NetworkRemote;
#endif

class Application : public QObject {
Q_OBJECT
Expand Down Expand Up @@ -103,6 +107,9 @@ class Application : public QObject {
SharedPtr<MoodbarLoader> moodbar_loader() const;
#endif

#ifdef HAVE_NETWORKREMOTE
SharedPtr<NetworkRemote> network_remote() const;
#endif
SharedPtr<LastFMImport> lastfm_import() const;

void Exit();
Expand Down
25 changes: 25 additions & 0 deletions src/networkremote/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
add_library(lib-networkremote STATIC)

qt_add_protobuf(lib-networkremote
PROTO_FILES RemoteMessages.proto
)

target_include_directories(lib-networkremote SYSTEM PRIVATE
${GLIB_INCLUDE_DIRS}
${PROTOBUF_INCLUDE_DIRS}
)

target_include_directories(lib-networkremote PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_CURRENT_BINARY_DIR}
${CMAKE_SOURCE_DIR}/src
${CMAKE_BINARY_DIR}/src
)

target_link_libraries(lib-networkremote PRIVATE
${GLIB_LIBRARIES}
${Protobuf_LIBRARIES}
Qt${QT_VERSION_MAJOR}::Core
Qt${QT_VERSION_MAJOR}::Network
Qt${QT_VERSION_MAJOR}::Gui
)
131 changes: 131 additions & 0 deletions src/networkremote/RemoteMessages.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
syntax = "proto3";

package nw.remote;

option java_multiple_files = true;

enum MsgType {
MSG_TYPE_UNSPECIFIED = 0;

// Client message
MSG_TYPE_REQUEST_SONG_INFO = 1;
MSG_TYPE_REQUEST_PLAY = 2;
MSG_TYPE_REQUEST_NEXT = 3;
MSG_TYPE_REQUEST_PREVIOUS = 4;
MSG_TYPE_REQUEST_PAUSE = 5;
MSG_TYPE_REQUEST_STOP = 6;
MSG_TYPE_REQUEST_FINISH = 7;


// Server messages
MSG_TYPE_REPLY_SONG_INFO = 8;
MSG_TYPE_REPLY_PLAY = 9;
MSG_TYPE_REPLY_NEXT = 10;
MSG_TYPE_REPLY_PREVIOUS = 11;
MSG_TYPE_REPLY_PAUSE = 12;
MSG_TYPE_REPLY_STOP = 13;
MSG_TYPE_REPLY_FINISH = 14;
MSG_TYPE_ENGINE_STATE_CHANGE = 15;

// Bidirectional messages
MSG_TYPE_DISCONNECT = 16;
}

enum PlayerState{
PLAYER_STATUS_UNSPECIFIED = 0;
PLAYER_STATUS_PLAYING = 1;
}

enum EngineState {
ENGINE_STATE_EMPTY = 0;
ENGINE_STATE_IDELE = 1;
ENGINE_STATE_PLAYING = 2;
ENGINE_STATE_PAUSED = 3;
}

enum ReasonDisconnect {
REASON_DISCONNECT_SERVER_SHUTDOWN = 0;
REASON_DISCONNECT_CLIENT_SHUTDOWN = 1;
}

message RequestDisconnect {
ReasonDisconnect reason_disconnect = 1;
}

message SongMetadata{
uint32 id = 1;
string title = 2;
string album = 3;
string artist = 4;
string albumartist = 5;
uint32 track = 6;
string stryear = 7;
string genre = 8;
uint32 playcount = 9;
string songlength = 10;
}
message RequestSongMetadata {
bool send = 1;
}

message ResponseSongMetadata {
SongMetadata song_metadata = 1;
PlayerState player_state = 2;
}

message RequestNextTrack {
bool next = 1;
}

message ResponseNextTrack {
bool next = 1;
}

message RequestPreviousTrack {
bool previous = 1;
}

message ResponsePreviousTrack {
bool previous = 1;
}

message RequestPlay {
bool play = 1;
}

message ResponsePlay {
bool play = 1;
}

message RequestPause {
bool pause = 1;
}

message ResponsePause {
bool pause = 1;
}

message RequestStop {
bool stop = 1;
}

message EngineStateChange {
EngineState state = 1;
}
message Message {
MsgType type = 1;
RequestSongMetadata request_song_metadata = 2;
ResponseSongMetadata response_song_metadata = 3;
RequestNextTrack request_next_track = 4;
RequestPreviousTrack request_previous_track = 5;
RequestPlay request_play = 6;
RequestPause request_pause = 7;
RequestStop request_stop = 8;
EngineStateChange engine_state_change = 9;
RequestDisconnect request_disconnect = 10;
ResponseNextTrack response_next_track = 11;
ResponsePreviousTrack response_previous_track = 12;
ResponsePlay response_play = 13;
ResponsePause response_pause = 14;
}

Loading