hzeller / gmrender-resurrect

Resource efficient UPnP/DLNA renderer, optimal for Raspberry Pi, CuBox or a general MediaServer. Fork of GMediaRenderer to add some features to make it usable.
GNU General Public License v2.0
850 stars 207 forks source link

Roughly usable but not visible on NetEase Music #246

Open ltrsunny opened 2 years ago

ltrsunny commented 2 years ago

I build & run it on an Alpine Linux (armv7). Tested with BubleUpnp and QQ Music, working smoothly. But NetEase Cloud Music (Android) cannot discover it.

# /usr/local/bin/gmediarender  -f "Grender" --gstout-audiosink=alsasink --gstout-audiodevice=hw:0,0  --gstout-buffer-duration=10
--mime-filter audio,+audio/dsd --logfile=stdout
INFO  [2022-03-08 20:44:19.127370 | (null)]main gmediarender 0.0.9 log started [ gmediarender 0.0.9_git2021-03-14_4ac7d89 (libupnp-1.14.12; glib-2.70.1; gstreamer-1.18.5) ]
INFO  [2022-03-08 20:44:19.127635 | (null)]output Using output module: gst (GStreamer multimedia framework)
INFO  [2022-03-08 20:44:19.359408 | (null)]gstreamer Setting buffer duration to 10000ms
INFO  [2022-03-08 20:44:19.359698 | (null)]gstreamer Setting audio sink to alsasink; device=hw:0,0
INFO  [2022-03-08 20:44:19.389065 | (null)]gstreamer Set mute to off
INFO  [2022-03-08 20:44:19.389960 | (null)]connmgr Registering support for 'audio/*'
INFO  [2022-03-08 20:44:19.390110 | (null)]connmgr Registering support for 'audio/AMR'
…
…
INFO  [2022-03-08 20:44:19.396989 | (null)]connmgr Registering support for 'audio/x-xm'
INFO  [2022-03-08 20:44:19.397173 | (null)]webserver Provide /upnp/grender-64x64.png (image/png) from /usr/local/share/gmediarender/grender-64x64.png
INFO  [2022-03-08 20:44:19.400044 | (null)]webserver Provide /upnp/grender-128x128.png (image/png) from /usr/local/share/gmediarender/grender-128x128.png
INFO  [2022-03-08 20:44:19.410573 | (null)]webserver Provide /upnp/rendertransportSCPD.xml (text/xml) from buffer
INFO  [2022-03-08 20:44:19.412521 | (null)]webserver Provide /upnp/renderconnmgrSCPD.xml (text/xml) from buffer
INFO  [2022-03-08 20:44:19.417974 | (null)]webserver Provide /upnp/rendercontrolSCPD.xml (text/xml) from buffer
INFO  [2022-03-08 20:44:19.420100 | (null)]upnp Registered IP=192.168.50.243 port=49494
INFO  [2022-03-08 20:44:19.529793 | (null)]gstreamer Query volume fraction: 1.000000
INFO  [2022-03-08 20:44:19.529897 | (null)]control Output initial volume is 1.000000; setting control variables accordingly.
INFO  [2022-03-08 20:44:19.529972 | (null)]control Setting volume-db to 0.00db == #100
INFO  [2022-03-08 20:44:19.530669 | (null)]main Ready for rendering.
Ready for rendering.

How should I debug it? I tried using different upnp port, doesn't work.

ltrsunny commented 2 years ago

Logs for ./autogen.sh

autoreconf: export WARNINGS=
autoreconf: Entering directory '.'
autoreconf: configure.ac: not using Gettext
autoreconf: running: aclocal --force
autoreconf: configure.ac: tracing
autoreconf: configure.ac: not using Libtool
autoreconf: configure.ac: not using Intltool
autoreconf: configure.ac: not using Gtkdoc
autoreconf: running: /usr/bin/autoconf --force
configure.ac:12: warning: The macro `AC_PROG_CC_STDC' is obsolete.
configure.ac:12: You should run autoupdate.
./lib/autoconf/c.m4:1666: AC_PROG_CC_STDC is expanded from...
configure.ac:12: the top level
configure.ac:50: warning: The macro `AC_HELP_STRING' is obsolete.
configure.ac:50: You should run autoupdate.
./lib/autoconf/general.m4:204: AC_HELP_STRING is expanded from...
configure.ac:50: the top level
configure.ac:88: warning: The macro `AC_HELP_STRING' is obsolete.
configure.ac:88: You should run autoupdate.
./lib/autoconf/general.m4:204: AC_HELP_STRING is expanded from...
configure.ac:88: the top level
configure.ac:110: warning: The macro `AC_HEADER_STDC' is obsolete.
configure.ac:110: You should run autoupdate.
./lib/autoconf/headers.m4:704: AC_HEADER_STDC is expanded from...
configure.ac:110: the top level
autoreconf: running: /usr/bin/autoheader --force
autoreconf: running: automake --add-missing --copy --force-missing
autoreconf: Leaving directory '.'

for make


make  all-recursive
make[1]: Entering directory '/root/gmrender-resurrect'
Making all in src
make[2]: Entering directory '/root/gmrender-resurrect/src'
(echo "#define GM_COMPILE_VERSION \"0.0.9_git2021-03-14_4ac7d89\"" > git-version.h-new; \
cmp -s git-version.h git-version.h-new || cp git-version.h-new git-version.h; \
rm git-version.h-new)
gcc -DHAVE_CONFIG_H -I. -I..  -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include -pthread  -I/usr/include/gstreamer-1.0 -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include -pthread  -I/usr/include/upnp  -DPKG_DATADIR=\"/usr/local/share/gmediarender\"   -g -O2 -MT main.o -MD -MP -MF .deps/main.Tpo -c -o main.o main.c
mv -f .deps/main.Tpo .deps/main.Po
gcc -DHAVE_CONFIG_H -I. -I..  -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include -pthread  -I/usr/include/gstreamer-1.0 -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include -pthread  -I/usr/include/upnp  -DPKG_DATADIR=\"/usr/local/share/gmediarender\"   -g -O2 -MT upnp_service.o -MD -MP -MF .deps/upnp_service.Tpo -c -o upnp_service.o upnp_service.c
mv -f .deps/upnp_service.Tpo .deps/upnp_service.Po
gcc -DHAVE_CONFIG_H -I. -I..  -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include -pthread  -I/usr/include/gstreamer-1.0 -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include -pthread  -I/usr/include/upnp  -DPKG_DATADIR=\"/usr/local/share/gmediarender\"   -g -O2 -MT upnp_control.o -MD -MP -MF .deps/upnp_control.Tpo -c -o upnp_control.o upnp_control.c
mv -f .deps/upnp_control.Tpo .deps/upnp_control.Po
gcc -DHAVE_CONFIG_H -I. -I..  -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include -pthread  -I/usr/include/gstreamer-1.0 -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include -pthread  -I/usr/include/upnp  -DPKG_DATADIR=\"/usr/local/share/gmediarender\"   -g -O2 -MT upnp_connmgr.o -MD -MP -MF .deps/upnp_connmgr.Tpo -c -o upnp_connmgr.o upnp_connmgr.c
mv -f .deps/upnp_connmgr.Tpo .deps/upnp_connmgr.Po
gcc -DHAVE_CONFIG_H -I. -I..  -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include -pthread  -I/usr/include/gstreamer-1.0 -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include -pthread  -I/usr/include/upnp  -DPKG_DATADIR=\"/usr/local/share/gmediarender\"   -g -O2 -MT upnp_transport.o -MD -MP -MF .deps/upnp_transport.Tpo -c -o upnp_transport.o upnp_transport.c
mv -f .deps/upnp_transport.Tpo .deps/upnp_transport.Po
gcc -DHAVE_CONFIG_H -I. -I..  -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include -pthread  -I/usr/include/gstreamer-1.0 -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include -pthread  -I/usr/include/upnp  -DPKG_DATADIR=\"/usr/local/share/gmediarender\"   -g -O2 -MT song-meta-data.o -MD -MP -MF .deps/song-meta-data.Tpo -c -o song-meta-data.o song-meta-data.c
mv -f .deps/song-meta-data.Tpo .deps/song-meta-data.Po
gcc -DHAVE_CONFIG_H -I. -I..  -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include -pthread  -I/usr/include/gstreamer-1.0 -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include -pthread  -I/usr/include/upnp  -DPKG_DATADIR=\"/usr/local/share/gmediarender\"   -g -O2 -MT variable-container.o -MD -MP -MF .deps/variable-container.Tpo -c -o variable-container.o variable-container.c
mv -f .deps/variable-container.Tpo .deps/variable-container.Po
gcc -DHAVE_CONFIG_H -I. -I..  -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include -pthread  -I/usr/include/gstreamer-1.0 -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include -pthread  -I/usr/include/upnp  -DPKG_DATADIR=\"/usr/local/share/gmediarender\"   -g -O2 -MT upnp_device.o -MD -MP -MF .deps/upnp_device.Tpo -c -o upnp_device.o upnp_device.c
mv -f .deps/upnp_device.Tpo .deps/upnp_device.Po
gcc -DHAVE_CONFIG_H -I. -I..  -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include -pthread  -I/usr/include/gstreamer-1.0 -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include -pthread  -I/usr/include/upnp  -DPKG_DATADIR=\"/usr/local/share/gmediarender\"   -g -O2 -MT upnp_renderer.o -MD -MP -MF .deps/upnp_renderer.Tpo -c -o upnp_renderer.o upnp_renderer.c
mv -f .deps/upnp_renderer.Tpo .deps/upnp_renderer.Po
gcc -DHAVE_CONFIG_H -I. -I..  -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include -pthread  -I/usr/include/gstreamer-1.0 -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include -pthread  -I/usr/include/upnp  -DPKG_DATADIR=\"/usr/local/share/gmediarender\"   -g -O2 -MT webserver.o -MD -MP -MF .deps/webserver.Tpo -c -o webserver.o webserver.c
webserver.c: In function 'webserver_register_callbacks':
webserver.c:293:41: warning: passing argument 1 of 'UpnpVirtualDir_set_GetInfoCallback' from incompatible pointer type [-Wincompatible-pointer-types]
  293 |     (UpnpVirtualDir_set_GetInfoCallback(webserver_get_info) == UPNP_E_SUCCESS
      |                                         ^~~~~~~~~~~~~~~~~~
      |                                         |
      |                                         int (*)(const char *, UpnpFileInfo *, const void *) {aka int (*)(const char *, struct s_UpnpFileInfo *, const void *)}
In file included from webserver.c:38:
/usr/include/upnp/upnp.h:2626:71: note: expected 'VDCallback_GetInfo' {aka 'int (*)(const char *, struct s_UpnpFileInfo *, const void *, const void **)'} but argument is of type 'int (*)(const char *, UpnpFileInfo *, const void *)' {aka 'int (*)(const char *, struct s_UpnpFileInfo *, const void *)'}
 2626 | EXPORT_SPEC int UpnpVirtualDir_set_GetInfoCallback(VDCallback_GetInfo callback);
      |                                                    ~~~~~~~~~~~~~~~~~~~^~~~~~~~
webserver.c:294:41: warning: passing argument 1 of 'UpnpVirtualDir_set_OpenCallback' from incompatible pointer type [-Wincompatible-pointer-types]
  294 |      && UpnpVirtualDir_set_OpenCallback(webserver_open) == UPNP_E_SUCCESS
      |                                         ^~~~~~~~~~~~~~
      |                                         |
      |                                         void * (*)(const char *, enum UpnpOpenFileMode,  const void *)
In file included from webserver.c:38:
/usr/include/upnp/upnp.h:2650:65: note: expected 'VDCallback_Open' {aka 'void * (*)(const char *, enum UpnpOpenFileMode,  const void *, const void *)'} but argument is of type 'void * (*)(const char *, enum UpnpOpenFileMode,  const void *)'
 2650 | EXPORT_SPEC int UpnpVirtualDir_set_OpenCallback(VDCallback_Open callback);
      |                                                 ~~~~~~~~~~~~~~~~^~~~~~~~
webserver.c:295:41: warning: passing argument 1 of 'UpnpVirtualDir_set_ReadCallback' from incompatible pointer type [-Wincompatible-pointer-types]
  295 |      && UpnpVirtualDir_set_ReadCallback(webserver_read) == UPNP_E_SUCCESS
      |                                         ^~~~~~~~~~~~~~
      |                                         |
      |                                         int (*)(void *, char *, size_t,  const void *) {aka int (*)(void *, char *, unsigned int,  const void *)}
In file included from webserver.c:38:
/usr/include/upnp/upnp.h:2675:65: note: expected 'VDCallback_Read' {aka 'int (*)(void *, char *, unsigned int,  const void *, const void *)'} but argument is of type 'int (*)(void *, char *, size_t,  const void *)' {aka 'int (*)(void *, char *, unsigned int,  const void *)'}
 2675 | EXPORT_SPEC int UpnpVirtualDir_set_ReadCallback(VDCallback_Read callback);
      |                                                 ~~~~~~~~~~~~~~~~^~~~~~~~
webserver.c:296:42: warning: passing argument 1 of 'UpnpVirtualDir_set_WriteCallback' from incompatible pointer type [-Wincompatible-pointer-types]
  296 |      && UpnpVirtualDir_set_WriteCallback(webserver_write) == UPNP_E_SUCCESS
      |                                          ^~~~~~~~~~~~~~~
      |                                          |
      |                                          int (*)(void *, char *, size_t,  const void *) {aka int (*)(void *, char *, unsigned int,  const void *)}
In file included from webserver.c:38:
/usr/include/upnp/upnp.h:2700:67: note: expected 'VDCallback_Write' {aka 'int (*)(void *, char *, unsigned int,  const void *, const void *)'} but argument is of type 'int (*)(void *, char *, size_t,  const void *)' {aka 'int (*)(void *, char *, unsigned int,  const void *)'}
 2700 | EXPORT_SPEC int UpnpVirtualDir_set_WriteCallback(VDCallback_Write callback);
      |                                                  ~~~~~~~~~~~~~~~~~^~~~~~~~
webserver.c:297:41: warning: passing argument 1 of 'UpnpVirtualDir_set_SeekCallback' from incompatible pointer type [-Wincompatible-pointer-types]
  297 |      && UpnpVirtualDir_set_SeekCallback(webserver_seek) == UPNP_E_SUCCESS
      |                                         ^~~~~~~~~~~~~~
      |                                         |
      |                                         int (*)(void *, off_t,  int,  const void *) {aka int (*)(void *, long long int,  int,  const void *)}
In file included from webserver.c:38:
/usr/include/upnp/upnp.h:2730:65: note: expected 'VDCallback_Seek' {aka 'int (*)(void *, long long int,  int,  const void *, const void *)'} but argument is of type 'int (*)(void *, off_t,  int,  const void *)' {aka 'int (*)(void *, long long int,  int,  const void *)'}
 2730 | EXPORT_SPEC int UpnpVirtualDir_set_SeekCallback(VDCallback_Seek callback);
      |                                                 ~~~~~~~~~~~~~~~~^~~~~~~~
webserver.c:298:42: warning: passing argument 1 of 'UpnpVirtualDir_set_CloseCallback' from incompatible pointer type [-Wincompatible-pointer-types]
  298 |      && UpnpVirtualDir_set_CloseCallback(webserver_close) == UPNP_E_SUCCESS);
      |                                          ^~~~~~~~~~~~~~~
      |                                          |
      |                                          int (*)(void *, const void *)
In file included from webserver.c:38:
/usr/include/upnp/upnp.h:2751:67: note: expected 'VDCallback_Close' {aka 'int (*)(void *, const void *, const void *)'} but argument is of type 'int (*)(void *, const void *)'
 2751 | EXPORT_SPEC int UpnpVirtualDir_set_CloseCallback(VDCallback_Close callback);
      |                                                  ~~~~~~~~~~~~~~~~~^~~~~~~~
mv -f .deps/webserver.Tpo .deps/webserver.Po
gcc -DHAVE_CONFIG_H -I. -I..  -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include -pthread  -I/usr/include/gstreamer-1.0 -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include -pthread  -I/usr/include/upnp  -DPKG_DATADIR=\"/usr/local/share/gmediarender\"   -g -O2 -MT output.o -MD -MP -MF .deps/output.Tpo -c -o output.o output.c
mv -f .deps/output.Tpo .deps/output.Po
gcc -DHAVE_CONFIG_H -I. -I..  -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include -pthread  -I/usr/include/gstreamer-1.0 -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include -pthread  -I/usr/include/upnp  -DPKG_DATADIR=\"/usr/local/share/gmediarender\"   -g -O2 -MT logging.o -MD -MP -MF .deps/logging.Tpo -c -o logging.o logging.c
mv -f .deps/logging.Tpo .deps/logging.Po
gcc -DHAVE_CONFIG_H -I. -I..  -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include -pthread  -I/usr/include/gstreamer-1.0 -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include -pthread  -I/usr/include/upnp  -DPKG_DATADIR=\"/usr/local/share/gmediarender\"   -g -O2 -MT xmldoc.o -MD -MP -MF .deps/xmldoc.Tpo -c -o xmldoc.o xmldoc.c
mv -f .deps/xmldoc.Tpo .deps/xmldoc.Po
gcc -DHAVE_CONFIG_H -I. -I..  -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include -pthread  -I/usr/include/gstreamer-1.0 -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include -pthread  -I/usr/include/upnp  -DPKG_DATADIR=\"/usr/local/share/gmediarender\"   -g -O2 -MT xmlescape.o -MD -MP -MF .deps/xmlescape.Tpo -c -o xmlescape.o xmlescape.c
mv -f .deps/xmlescape.Tpo .deps/xmlescape.Po
gcc -DHAVE_CONFIG_H -I. -I..  -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include -pthread  -I/usr/include/gstreamer-1.0 -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include -pthread  -I/usr/include/upnp  -DPKG_DATADIR=\"/usr/local/share/gmediarender\"   -g -O2 -MT output_gstreamer.o -MD -MP -MF .deps/output_gstreamer.Tpo -c -o output_gstreamer.o output_gstreamer.c
mv -f .deps/output_gstreamer.Tpo .deps/output_gstreamer.Po
gcc  -g -O2   -o gmediarender main.o upnp_service.o upnp_control.o upnp_connmgr.o upnp_transport.o song-meta-data.o variable-container.o upnp_device.o upnp_renderer.o webserver.o output.o logging.o xmldoc.o xmlescape.o output_gstreamer.o -lgthread-2.0 -pthread -lglib-2.0 -lintl  -lgstreamer-1.0 -lgobject-2.0 -lglib-2.0 -lintl  -lupnp -lixml  -lm
make[2]: Leaving directory '/root/gmrender-resurrect/src'
Making all in data
make[2]: Entering directory '/root/gmrender-resurrect/data'
make[2]: Nothing to be done for 'all'.
make[2]: Leaving directory '/root/gmrender-resurrect/data'
make[2]: Entering directory '/root/gmrender-resurrect'
make[2]: Leaving directory '/root/gmrender-resurrect'
make[1]: Leaving directory '/root/gmrender-resurrect'
mill1000 commented 2 years ago

It appears I don't have access to NetEase Cloud Music in my country, so I won' be of much help.

UPnP discovery occurs via the SSDP protocol. You could use Wireshark to view the SSDP packets in your network and compare how BubbleUPnP and NetEase performs their search/discovery.

ltrsunny commented 2 years ago

It appears I don't have access to NetEase Cloud Music in my country, so I won' be of much help.

UPnP discovery occurs via the SSDP protocol. You could use Wireshark to view the SSDP packets in your network and compare how BubbleUPnP and NetEase performs their search/discovery.

I tried to build under Debian, it works fine and there are no warnings in compilation. I guess it comes from the libraries provided by Alpine Linux.

Alpine: gmediarender 0.0.9 started [ gmediarender 0.0.9_git2021-03-14_4ac7d89 (libupnp-1.14.12; glib-2.70.1; gstreamer-1.18.5) ]. Debian: gmediarender 0.0.9 started [ gmediarender 0.0.9_git2021-03-14_4ac7d89 (libupnp-1.8.4; glib-2.66.8; gstreamer-1.18.4) ].