FD- / RPiPlay

An open-source AirPlay mirroring server for the Raspberry Pi. Supports iOS 9 and up.
GNU General Public License v3.0
4.93k stars 353 forks source link

build issues for macOS #208

Open lewisxy opened 3 years ago

lewisxy commented 3 years ago

I tried to build this on macOS 10.14.6 and I installed all dependencies using brew

brew install cmake libplist nss gstreamer gst-plugins-bad gst-plugins-base

but the build failed. After a bit research, I fixed the issue by adding the following lines to top level CMakeList.txt

include_directories(/usr/local/include)
link_directories(/usr/local/lib)

and add the following lines to lib/raop_rtp_mirror.c after all the "#include" (see this)

#if !defined(SOL_TCP) && defined(IPPROTO_TCP)
#define SOL_TCP IPPROTO_TCP
#endif
#if !defined(TCP_KEEPIDLE) && defined(TCP_KEEPALIVE)
#define TCP_KEEPIDLE TCP_KEEPALIVE
#endif

I am not entirely sure of how to modify the makefile and c source code so that it can be build on both Linux and macOS, so I am not going to submit a PR for this. If anyone know how to do it, please fix this.


Now I am able to run the binary on macOS, but when I mirror the screen of my iPhone or iPad, nothing showed up (unlike on Linux, which opened a new window). I am not sure why this is the case. Are there any other ways to get the stream out?

pigworlds commented 3 years ago

I hit the same issue. The missing window turn out to because of this.

You need to add Glib main event loop. I added it to the main() and does popup the window.

alyyousuf7 commented 3 years ago

https://github.com/FD-/RPiPlay/pull/155 -- This PR adds Glib main event loop

diff --git a/CMakeLists.txt b/CMakeLists.txt
index b920d6f..06c44dd 100755
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -12,6 +12,9 @@ project(rpiplay)

 set (CMAKE_CXX_STANDARD 11)

+include_directories(/usr/local/include)
+link_directories(/usr/local/lib)
+
 set (RENDERER_FLAGS "")

 add_subdirectory(lib/playfair)
@@ -23,6 +26,9 @@ add_subdirectory(renderers)
 set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${RENDERER_FLAGS}" )

 add_executable( rpiplay rpiplay.cpp)
+if (APPLE)
+  include_directories ( rpiplay ${GST_INCLUDE_DIRS} )
+endif()
 target_link_libraries ( rpiplay renderers airplay )

 install(TARGETS rpiplay RUNTIME DESTINATION bin)
diff --git a/lib/raop_rtp_mirror.c b/lib/raop_rtp_mirror.c
index 2040d7e..16f9d07 100755
--- a/lib/raop_rtp_mirror.c
+++ b/lib/raop_rtp_mirror.c
@@ -30,6 +30,12 @@
 #include "mirror_buffer.h"
 #include "stream.h"

+#if !defined(SOL_TCP) && defined(IPPROTO_TCP)
+#define SOL_TCP IPPROTO_TCP
+#endif
+#if !defined(TCP_KEEPIDLE) && defined(TCP_KEEPALIVE)
+#define TCP_KEEPIDLE TCP_KEEPALIVE
+#endif

 struct h264codec_s {
     unsigned char compatibility;
diff --git a/rpiplay.cpp b/rpiplay.cpp
index c5a6774..42a67a1 100755
--- a/rpiplay.cpp
+++ b/rpiplay.cpp
@@ -33,6 +33,12 @@
 #include "renderers/video_renderer.h"
 #include "renderers/audio_renderer.h"

+#ifdef __APPLE__
+#include <glib-unix.h>
+#include <gst/gst.h>
+#include <gst/app/gstappsrc.h>
+#endif
+
 #define VERSION "1.2"

 #define DEFAULT_NAME "RPiPlay"
@@ -97,6 +103,35 @@ static const audio_renderer_list_entry_t audio_renderers[] = {
 #endif
 };

+#ifdef __APPLE__
+static GMainLoop *loop;
+static guint signal_watch_intr_id;
+static guint signal_watch_term_id;
+
+void intr_main_loop(gpointer user_data) {
+    signal_watch_intr_id = 0;
+    g_main_loop_quit(loop);
+}
+
+void term_main_loop(gpointer user_data) {
+    signal_watch_term_id = 0;
+    g_main_loop_quit(loop);
+}
+
+void main_loop() {
+    GstElement *pipeline = gst_pipeline_new(NULL);
+    signal_watch_intr_id = g_unix_signal_add(SIGINT, (GSourceFunc) intr_main_loop, pipeline);
+    signal_watch_term_id = g_unix_signal_add(SIGTERM, (GSourceFunc) term_main_loop, pipeline);
+    loop = g_main_loop_new(NULL, FALSE);
+    g_main_loop_run(loop);
+
+    gst_element_set_state(pipeline, GST_STATE_NULL);
+    gst_object_unref(pipeline);
+    if (signal_watch_intr_id > 0) g_source_remove(signal_watch_intr_id);
+    if (signal_watch_term_id > 0) g_source_remove(signal_watch_term_id);
+    g_main_loop_unref(loop);
+}
+#else
 static void signal_handler(int sig) {
     switch (sig) {
         case SIGINT:
@@ -115,6 +150,7 @@ static void init_signals(void) {
     sigaction(SIGINT, &sigact, NULL);
     sigaction(SIGTERM, &sigact, NULL);
 }
+#endif

 static int parse_hw_addr(std::string str, std::vector<char> &hw_addr) {
     for (int i = 0; i < str.length(); i += 3) {
@@ -177,7 +213,9 @@ void print_info(char *name) {
 }

 int main(int argc, char *argv[]) {
+    #ifndef __APPLE__
     init_signals();
+    #endif

     std::string server_name = DEFAULT_NAME;
     std::vector<char> server_hw_addr = DEFAULT_HW_ADDRESS;
@@ -270,10 +308,14 @@ int main(int argc, char *argv[]) {
         return 1;
     }

+#ifdef __APPLE__
+    main_loop();
+#else
     running = true;
     while (running) {
         sleep(1);
     }
+#endif

     LOGI("Stopping...");
     stop_server();