micro-nova / AmpliPi

Whole House Audio System 🔊
https://amplipi.com
GNU General Public License v3.0
286 stars 23 forks source link

Feature: Add TIDAL support #87

Open mwbrink opened 3 years ago

mwbrink commented 3 years ago

Would be great if Tidal could be added with HiTide.

https://github.com/shawaj/HiTide

linknum23 commented 3 years ago

It looks like the most up to date Linux Tidal support is from https://github.com/seniorgod/ifi-tidal-release (HiTide is based on this). Looking into this a little closer at ifi-tidal, Tidal support looks fairly easy to implement with that implementation. Here's what their command line interface looks like:

tidal_connect_application \
            --tc-certificate-path "/usr/ifi/ifi-tidal-release/id_certificate/IfiAudio_ZenStream.dat" \
            --netif-for-deviceid eth0 \
            -f "DietPi stream to project“ \
            --codec-mpegh true \
            --codec-mqa false \
            --model-name "DietPi Streamer" \
            --disable-app-security false \
            --disable-web-security false \
            --enable-mqa-passthrough false \
            --playback-device "Project RS USB Audio 2.0: - (hw:1,0)" \
            --log-level 3

It should be rather easy to launch this, changing the playback device to ch0-ch3 and the model name to the specific stream's configuration. We have not tested this yet because it requires a Tidal account. @mwbrink I assume you have a Tidal account. Would you be willing to help us test this?

One thing to note is the underlying tidal_connect_application is only in closed source binary form, so this will need to be optionally downloaded and installed like a plugin.

linknum23 commented 3 years ago

Here are a list of steps that are needed to integrate TIDAL:

mwbrink commented 3 years ago

I will do what I can to help.

eyeduck commented 3 years ago

I would be interested in Tidal support also

linknum23 commented 3 years ago

Cool are either of you guys able to try out the tidal_connect_application on Linux? You can use the output of aplay -L to give you the audio output device strings available on your system. You can use this for the --playback-device parameter.

linknum23 commented 3 years ago

Is there anyone with a Tidal subscription than can help us move forward on this?

mwbrink commented 2 years ago

Okay, I've received my amplipi. I would like to have a go ath this, but need a little push to figure this out. I can ssh into the system. how do I best install the binaries?

linknum23 commented 2 years ago

The easiest way to start playing with it would be to use the HiTide installer that installs ifi-tidal-release and uses it in the HiTide service.

curl -sSL https://raw.githubusercontent.com/shawaj/HiTide/main/install.sh | sudo bash

Then you should probably disable the service so you can play with with command line:

sudo systemctl stop ifi-streamer-tidal-connect.service 
sudo systemctl disable ifi-streamer-tidal-connect.service 

Looking at the service, its being run with the following comand line args:

/usr/ifi/ifi-tidal-release/bin/tidal_connect_application --tc-certificate-path /usr/ifi/ifi-tidal-release/id_certificate/IfiAudio_ZenStream.dat --netif-for-deviceid eth0 -f AmpliPi-TiDAL --codec-mpegh true --codec-mqa false --model-name Pi-Streamer --disable-app-security false --disable-web-security false --enable-mqa-passthrough false --playback-device ch1 --log-level 3

For now it looks like sources 2, 3, 4 (named 'ch1', 'ch2', 'ch3' respectively) can be used to playback audio. Source 1 is not being detected initially. Also it looks like the connect application is failing to create a socket on some unknown already used port.

To test on source 2 go to the the '2' tab in the app and select the blank input. This will configure the AmpliPi to use its Digital 2 input. Any zones connected to source 2 will play whatever TiDal is playing.

mwbrink commented 2 years ago

it worked! Got the same errors and some warnings on stream start as follows: [2021-12-20 18:38:51.514] [tisoc] [error] [SpkconServer.cpp:173] socket bind error. fd=4 errorno=98 error=Address already in use [2021-12-20 18:38:51.514] [tisoc] [error] [SpkconServer.cpp:54] already connected state:1 [2021-12-20 18:38:51.514] [tisoc] [critical] [SpeakerCommunicatorImpl.cpp:77] [ASSERT] start(ret) STARTED TidalConnect services. [2021-12-20 18:40:49.575] [tisoc] [warning] [PlaybackControllerImpl.cpp:472] Illegal state:1 [2021-12-20 18:40:50.252] [tisoc] [warning] [logger.cpp:22] [audio_worker.cpp:321] Attempting to initialize a decoder without initial data!

mwbrink commented 2 years ago

On song change it spit out this error: [2021-12-20 18:43:19.372] [tisoc] [error] [logger.cpp:25] [operation_curl.cpp:258] curl_easy_perform failed: Timeout was reached - Resolving timed out after 5513 milliseconds [2021-12-20 18:43:19.372] [tisoc] [error] [logger.cpp:25] [http_stream_fetcher.cpp:162] Content-Range is missing from response!

mwbrink commented 2 years ago

it's still playing

linknum23 commented 2 years ago

Can you try launching TiDAL on 2 different sources? Maybe ch1 and ch2? I'm assuming TiDAL allows multiple concurrent streams...

mwbrink commented 2 years ago

I don't have a family account, thus I'm limited to one stream.

I restarted the unit to add an extender. do I simply start the service or am I going to have to stop and disable the service?

mwbrink commented 2 years ago

I tried running a second instance, but it didn't work. My linux is poor, here is what I did:

pi@amplipi:~ $ /usr/ifi/ifi-tidal-release/bin/tidal_connect_application --tc-certificate-path /usr/ifi/ifi-tidal-release/id_certificate/IfiAudio_ZenStream.dat --netif-for-deviceid eth0 -f AmpliPi-TiDAL-ch2 --codec-mpegh true --codec-mqa fal se --model-name Pi-Streamer --disable-app-security false --disable-web-security false --enable-mqa-passthrough false --p layback-device ch2 --log-level 3 STARTING TidalConnect services, version: 1.1.3 Expression 'alsa_snd_pcm_hw_params_set_period_size_near( pcm, hwParams, &alsaPeriodFrames, &dir )' failed in 'src/hostapi/alsa/pa_linux_alsa.c', line: 924 Expression 'alsa_snd_pcm_hw_params_set_period_size_near( pcm, hwParams, &alsaPeriodFrames, &dir )' failed in 'src/hostapi/alsa/pa_linux_alsa.c', line: 924 ALSA lib confmisc.c:1281:(snd_func_refer) Unable to find definition 'cards.bcm2835_headpho.pcm.front.0:CARD=0' ALSA lib conf.c:4568:(_snd_config_evaluate) function snd_func_refer returned error: No such file or directory ALSA lib conf.c:5047:(snd_config_expand) Evaluate error: No such file or directory ALSA lib pcm.c:2565:(snd_pcm_open_noupdate) Unknown PCM front ALSA lib pcm.c:2565:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.rear ALSA lib pcm.c:2565:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.center_lfe ALSA lib pcm.c:2565:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.side ALSA lib confmisc.c:1281:(snd_func_refer) Unable to find definition 'cards.bcm2835_headpho.pcm.surround51.0:CARD=0' ALSA lib conf.c:4568:(_snd_config_evaluate) function snd_func_refer returned error: No such file or directory ALSA lib conf.c:5047:(snd_config_expand) Evaluate error: No such file or directory ALSA lib pcm.c:2565:(snd_pcm_open_noupdate) Unknown PCM surround21 ALSA lib confmisc.c:1281:(snd_func_refer) Unable to find definition 'cards.bcm2835_headpho.pcm.surround51.0:CARD=0' ALSA lib conf.c:4568:(_snd_config_evaluate) function snd_func_refer returned error: No such file or directory ALSA lib conf.c:5047:(snd_config_expand) Evaluate error: No such file or directory ALSA lib pcm.c:2565:(snd_pcm_open_noupdate) Unknown PCM surround21 ALSA lib confmisc.c:1281:(snd_func_refer) Unable to find definition 'cards.bcm2835_headpho.pcm.surround40.0:CARD=0' ALSA lib conf.c:4568:(_snd_config_evaluate) function snd_func_refer returned error: No such file or directory ALSA lib conf.c:5047:(snd_config_expand) Evaluate error: No such file or directory ALSA lib pcm.c:2565:(snd_pcm_open_noupdate) Unknown PCM surround40 ALSA lib confmisc.c:1281:(snd_func_refer) Unable to find definition 'cards.bcm2835_headpho.pcm.surround51.0:CARD=0' ALSA lib conf.c:4568:(_snd_config_evaluate) function snd_func_refer returned error: No such file or directory ALSA lib conf.c:5047:(snd_config_expand) Evaluate error: No such file or directory ALSA lib pcm.c:2565:(snd_pcm_open_noupdate) Unknown PCM surround41 ALSA lib confmisc.c:1281:(snd_func_refer) Unable to find definition 'cards.bcm2835_headpho.pcm.surround51.0:CARD=0' ALSA lib conf.c:4568:(_snd_config_evaluate) function snd_func_refer returned error: No such file or directory ALSA lib conf.c:5047:(snd_config_expand) Evaluate error: No such file or directory ALSA lib pcm.c:2565:(snd_pcm_open_noupdate) Unknown PCM surround50 ALSA lib confmisc.c:1281:(snd_func_refer) Unable to find definition 'cards.bcm2835_headpho.pcm.surround51.0:CARD=0' ALSA lib conf.c:4568:(_snd_config_evaluate) function snd_func_refer returned error: No such file or directory ALSA lib conf.c:5047:(snd_config_expand) Evaluate error: No such file or directory ALSA lib pcm.c:2565:(snd_pcm_open_noupdate) Unknown PCM surround51 ALSA lib confmisc.c:1281:(snd_func_refer) Unable to find definition 'cards.bcm2835_headpho.pcm.surround71.0:CARD=0' ALSA lib conf.c:4568:(_snd_config_evaluate) function snd_func_refer returned error: No such file or directory ALSA lib conf.c:5047:(snd_config_expand) Evaluate error: No such file or directory ALSA lib pcm.c:2565:(snd_pcm_open_noupdate) Unknown PCM surround71 ALSA lib confmisc.c:1281:(snd_func_refer) Unable to find definition 'cards.bcm2835_headpho.pcm.iec958.0:CARD=0,AES0=4,AES1=130,AES2=0,AES3=2' ALSA lib conf.c:4568:(_snd_config_evaluate) function snd_func_refer returned error: No such file or directory ALSA lib conf.c:5047:(snd_config_expand) Evaluate error: No such file or directory ALSA lib pcm.c:2565:(snd_pcm_open_noupdate) Unknown PCM iec958 ALSA lib confmisc.c:1281:(snd_func_refer) Unable to find definition 'cards.bcm2835_headpho.pcm.iec958.0:CARD=0,AES0=4,AES1=130,AES2=0,AES3=2' ALSA lib conf.c:4568:(_snd_config_evaluate) function snd_func_refer returned error: No such file or directory ALSA lib conf.c:5047:(snd_config_expand) Evaluate error: No such file or directory ALSA lib pcm.c:2565:(snd_pcm_open_noupdate) Unknown PCM spdif ALSA lib confmisc.c:1281:(snd_func_refer) Unable to find definition 'cards.bcm2835_headpho.pcm.iec958.0:CARD=0,AES0=4,AES1=130,AES2=0,AES3=2' ALSA lib conf.c:4568:(_snd_config_evaluate) function snd_func_refer returned error: No such file or directory ALSA lib conf.c:5047:(snd_config_expand) Evaluate error: No such file or directory ALSA lib pcm.c:2565:(snd_pcm_open_noupdate) Unknown PCM spdif ALSA lib pcm.c:2565:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.hdmi ALSA lib pcm.c:2565:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.hdmi ALSA lib pcm.c:2565:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.modem ALSA lib pcm.c:2565:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.modem ALSA lib pcm.c:2565:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.phoneline ALSA lib pcm.c:2565:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.phoneline ALSA lib confmisc.c:1281:(snd_func_refer) Unable to find definition 'defaults.bluealsa.device' ALSA lib conf.c:4568:(_snd_config_evaluate) function snd_func_refer returned error: No such file or directory ALSA lib conf.c:5036:(snd_config_expand) Args evaluate error: No such file or directory ALSA lib pcm.c:2565:(snd_pcm_open_noupdate) Unknown PCM bluealsa ALSA lib confmisc.c:1281:(snd_func_refer) Unable to find definition 'defaults.bluealsa.device' ALSA lib conf.c:4568:(_snd_config_evaluate) function snd_func_refer returned error: No such file or directory ALSA lib conf.c:5036:(snd_config_expand) Args evaluate error: No such file or directory ALSA lib pcm.c:2565:(snd_pcm_open_noupdate) Unknown PCM bluealsa ALSA lib pcm_dmix.c:1043:(snd_pcm_dmix_open) The dmix plugin supports only playback stream ALSA lib pcm_dmix.c:1043:(snd_pcm_dmix_open) The dmix plugin supports only playback stream ALSA lib pcm_dmix.c:1043:(snd_pcm_dmix_open) The dmix plugin supports only playback stream ALSA lib pcm_dmix.c:1043:(snd_pcm_dmix_open) The dmix plugin supports only playback stream Cannot connect to server socket err = No such file or directory Cannot connect to server request channel jack server is not running or cannot be started JackShmReadWritePtr::~JackShmReadWritePtr - Init not done for -1, skipping unlock JackShmReadWritePtr::~JackShmReadWritePtr - Init not done for -1, skipping unlock [2021-12-22 12:39:35.723] [tisoc] [error] [avahiImpl.cpp:184] avahi_entry_group_add_service() err_code : -8 [2021-12-22 12:39:35.723] [tisoc] [error] [avahiImpl.cpp:144] MdnsServerImpl::createService() FAILED! tidal_connect_application: thread-watch.c:162: avahi_threaded_poll_quit: Assertion `p' failed. Aborted

linknum23 commented 2 years ago

Hmm looks like a duplicate name conflict:

Can you try the following in 2 separate ssh sessions. The commands use different names and outputs:

session1:

/usr/ifi/ifi-tidal-release/bin/tidal_connect_application --tc-certificate-path /usr/ifi/ifi-tidal-release/id_certificate/IfiAudio_ZenStream.dat --netif-for-deviceid eth0 -f AmpliPi-TiDAL1 --codec-mpegh true --codec-mqa false --model-name Pi-Streamer --disable-app-security false --disable-web-security false --enable-mqa-passthrough false --playback-device ch2 --log-level 3

session 2:

/usr/ifi/ifi-tidal-release/bin/tidal_connect_application --tc-certificate-path /usr/ifi/ifi-tidal-release/id_certificate/IfiAudio_ZenStream.dat --netif-for-deviceid eth0 -f AmpliPi-TiDAL2 --codec-mpegh true --codec-mqa false --model-name Pi-Streamer --disable-app-security false --disable-web-security false --enable-mqa-passthrough false --playback-device ch3 --log-level 3

Verify that you can play to each of these, switching between them. No need to try simultaneous playback yet.

mwbrink commented 2 years ago

The second command ran, always errors and aborts.

in this case session1 command was run second and output this:

pi@amplipi:~ $ /usr/ifi/ifi-tidal-release/bin/tidal_connect_application --tc-certificate-path /usr/ifi/ifi-tidal-release/id_certificate/IfiAudio_ZenStream.dat --netif-for-deviceid eth0 -f AmpliPi-TiDAL1 --codec-mpegh true --codec-mqa false --model-name Pi-Streamer --disable-app-security false --disable-web-security false --enable-mqa-passthrough false --playback-device ch2 --log-level 3 STARTING TidalConnect services, version: 1.1.3 Expression 'alsa_snd_pcm_hw_params_set_period_size_near( pcm, hwParams, &alsaPeriodFrames, &dir )' failed in 'src/hostapi/alsa/pa_linux_alsa.c', line: 924 Expression 'alsa_snd_pcm_hw_params_set_period_size_near( pcm, hwParams, &alsaPeriodFrames, &dir )' failed in 'src/hostapi/alsa/pa_linux_alsa.c', line: 924 ALSA lib confmisc.c:1281:(snd_func_refer) Unable to find definition 'cards.bcm2835_headpho.pcm.front.0:CARD=0' ALSA lib conf.c:4568:(_snd_config_evaluate) function snd_func_refer returned error: No such file or directory ALSA lib conf.c:5047:(snd_config_expand) Evaluate error: No such file or directory ALSA lib pcm.c:2565:(snd_pcm_open_noupdate) Unknown PCM front ALSA lib pcm.c:2565:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.rear ALSA lib pcm.c:2565:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.center_lfe ALSA lib pcm.c:2565:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.side ALSA lib confmisc.c:1281:(snd_func_refer) Unable to find definition 'cards.bcm2835_headpho.pcm.surround51.0:CARD=0' ALSA lib conf.c:4568:(_snd_config_evaluate) function snd_func_refer returned error: No such file or directory ALSA lib conf.c:5047:(snd_config_expand) Evaluate error: No such file or directory ALSA lib pcm.c:2565:(snd_pcm_open_noupdate) Unknown PCM surround21 ALSA lib confmisc.c:1281:(snd_func_refer) Unable to find definition 'cards.bcm2835_headpho.pcm.surround51.0:CARD=0' ALSA lib conf.c:4568:(_snd_config_evaluate) function snd_func_refer returned error: No such file or directory ALSA lib conf.c:5047:(snd_config_expand) Evaluate error: No such file or directory ALSA lib pcm.c:2565:(snd_pcm_open_noupdate) Unknown PCM surround21 ALSA lib confmisc.c:1281:(snd_func_refer) Unable to find definition 'cards.bcm2835_headpho.pcm.surround40.0:CARD=0' ALSA lib conf.c:4568:(_snd_config_evaluate) function snd_func_refer returned error: No such file or directory ALSA lib conf.c:5047:(snd_config_expand) Evaluate error: No such file or directory ALSA lib pcm.c:2565:(snd_pcm_open_noupdate) Unknown PCM surround40 ALSA lib confmisc.c:1281:(snd_func_refer) Unable to find definition 'cards.bcm2835_headpho.pcm.surround51.0:CARD=0' ALSA lib conf.c:4568:(_snd_config_evaluate) function snd_func_refer returned error: No such file or directory ALSA lib conf.c:5047:(snd_config_expand) Evaluate error: No such file or directory ALSA lib pcm.c:2565:(snd_pcm_open_noupdate) Unknown PCM surround41 ALSA lib confmisc.c:1281:(snd_func_refer) Unable to find definition 'cards.bcm2835_headpho.pcm.surround51.0:CARD=0' ALSA lib conf.c:4568:(_snd_config_evaluate) function snd_func_refer returned error: No such file or directory ALSA lib conf.c:5047:(snd_config_expand) Evaluate error: No such file or directory ALSA lib pcm.c:2565:(snd_pcm_open_noupdate) Unknown PCM surround50 ALSA lib confmisc.c:1281:(snd_func_refer) Unable to find definition 'cards.bcm2835_headpho.pcm.surround51.0:CARD=0' ALSA lib conf.c:4568:(_snd_config_evaluate) function snd_func_refer returned error: No such file or directory ALSA lib conf.c:5047:(snd_config_expand) Evaluate error: No such file or directory ALSA lib pcm.c:2565:(snd_pcm_open_noupdate) Unknown PCM surround51 ALSA lib confmisc.c:1281:(snd_func_refer) Unable to find definition 'cards.bcm2835_headpho.pcm.surround71.0:CARD=0' ALSA lib conf.c:4568:(_snd_config_evaluate) function snd_func_refer returned error: No such file or directory ALSA lib conf.c:5047:(snd_config_expand) Evaluate error: No such file or directory ALSA lib pcm.c:2565:(snd_pcm_open_noupdate) Unknown PCM surround71 ALSA lib confmisc.c:1281:(snd_func_refer) Unable to find definition 'cards.bcm2835_headpho.pcm.iec958.0:CARD=0,AES0=4,AES1=130,AES2=0,AES3=2' ALSA lib conf.c:4568:(_snd_config_evaluate) function snd_func_refer returned error: No such file or directory ALSA lib conf.c:5047:(snd_config_expand) Evaluate error: No such file or directory ALSA lib pcm.c:2565:(snd_pcm_open_noupdate) Unknown PCM iec958 ALSA lib confmisc.c:1281:(snd_func_refer) Unable to find definition 'cards.bcm2835_headpho.pcm.iec958.0:CARD=0,AES0=4,AES1=130,AES2=0,AES3=2' ALSA lib conf.c:4568:(_snd_config_evaluate) function snd_func_refer returned error: No such file or directory ALSA lib conf.c:5047:(snd_config_expand) Evaluate error: No such file or directory ALSA lib pcm.c:2565:(snd_pcm_open_noupdate) Unknown PCM spdif ALSA lib confmisc.c:1281:(snd_func_refer) Unable to find definition 'cards.bcm2835_headpho.pcm.iec958.0:CARD=0,AES0=4,AES1=130,AES2=0,AES3=2' ALSA lib conf.c:4568:(_snd_config_evaluate) function snd_func_refer returned error: No such file or directory ALSA lib conf.c:5047:(snd_config_expand) Evaluate error: No such file or directory ALSA lib pcm.c:2565:(snd_pcm_open_noupdate) Unknown PCM spdif ALSA lib pcm.c:2565:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.hdmi ALSA lib pcm.c:2565:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.hdmi ALSA lib pcm.c:2565:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.modem ALSA lib pcm.c:2565:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.modem ALSA lib pcm.c:2565:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.phoneline ALSA lib pcm.c:2565:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.phoneline ALSA lib confmisc.c:1281:(snd_func_refer) Unable to find definition 'defaults.bluealsa.device' ALSA lib conf.c:4568:(_snd_config_evaluate) function snd_func_refer returned error: No such file or directory ALSA lib conf.c:5036:(snd_config_expand) Args evaluate error: No such file or directory ALSA lib pcm.c:2565:(snd_pcm_open_noupdate) Unknown PCM bluealsa ALSA lib confmisc.c:1281:(snd_func_refer) Unable to find definition 'defaults.bluealsa.device' ALSA lib conf.c:4568:(_snd_config_evaluate) function snd_func_refer returned error: No such file or directory ALSA lib conf.c:5036:(snd_config_expand) Args evaluate error: No such file or directory ALSA lib pcm.c:2565:(snd_pcm_open_noupdate) Unknown PCM bluealsa ALSA lib pcm_dmix.c:1043:(snd_pcm_dmix_open) The dmix plugin supports only playback stream ALSA lib pcm_dmix.c:1043:(snd_pcm_dmix_open) The dmix plugin supports only playback stream ALSA lib pcm_dmix.c:1043:(snd_pcm_dmix_open) The dmix plugin supports only playback stream ALSA lib pcm_dmix.c:1043:(snd_pcm_dmix_open) The dmix plugin supports only playback stream Cannot connect to server socket err = No such file or directory Cannot connect to server request channel jack server is not running or cannot be started JackShmReadWritePtr::~JackShmReadWritePtr - Init not done for -1, skipping unlock JackShmReadWritePtr::~JackShmReadWritePtr - Init not done for -1, skipping unlock [2021-12-23 01:32:42.650] [tisoc] [error] [avahiImpl.cpp:184] avahi_entry_group_add_service() err_code : -8 [2021-12-23 01:32:42.651] [tisoc] [error] [avahiImpl.cpp:144] MdnsServerImpl::createService() FAILED! tidal_connect_application: thread-watch.c:162: avahi_threaded_poll_quit: Assertion `p' failed. Aborted pi@amplipi:~ $

Both commands seem to work on their own, but not together.

zjs commented 2 years ago

I have a Tidal subscription and would be happy to help validate — is there something that'd be helpful for me to try? I can't quite tell if there was conclusion from the experiment above.

(There's also a 30 day trial if being able to try things yourself would be easier.)

linknum23 commented 2 years ago

I think this integration just fell off our radar and it didn't help that is was using a closed source binary that didn't allow us to gain any insight. Would you mind testing this a little bit to try to see if there are any ways to get multiple TIDAL streams working at once?

If you are testing on AmpliPi it has 4 strereo outputs you can play with: ch0 -> Tab/Source 1 ch1 -> Tab/Source 2 ch2 -> Tab/Source 3 ch3 -> Tab/Source 4

When you are testing TIDAL and want to verify audio playback set the input the blank input, that will configure it to play whatever is being played out the selected stereo output.

Try using this command to play out Source 3:

/usr/ifi/ifi-tidal-release/bin/tidal_connect_application --tc-certificate-path /usr/ifi/ifi-tidal-release/id_certificate/IfiAudio_ZenStream.dat --netif-for-deviceid eth0 -f AmpliPi-TiDAL1 --codec-mpegh true --codec-mqa false --model-name Pi-Streamer --disable-app-security false --disable-web-security false --enable-mqa-passthrough false --playback-device ch2 --log-level 3

I hope this helps!

mwbrink commented 2 years ago

The problem I had was my Tidal sub only allows 1 stream at a time, forbidding me to test concurrent streams.

linknum23 commented 2 years ago

Also I don't remember did anyone look into how feasible it was to get album art?

charliesjc commented 2 years ago

Unix socket /tmp/tisoc-controller has everything we need. It supplies all the now playing information and seems to control Tidal Connect. I can't use it without breaking the Tidal Service requiring a restart, though. I'm no expert in using sockets, maybe someone else knows what's going on?

If I try to use Tidal AFTER I run my socket sniffing script, it hangs and this is the most I can get out of it:

/bin/python /root/anotherAttempt.py

b'\xff\x02\x00`{"appInfo": {"appId": "tidal", "appName": "TIDAL"}, "command": "notifySessionState", "state": 1}\xff\x03' b'\xff\x02\x00\x1f{"command": "requestResources"}\xff\x03' b'\xff\x02\x00-{"command": "notifySessionState", "state": 4}\xff\x03'

But if you connect your phone first and then run the script to intercept messages:

/bin/python /root/anotherAttempt.py

b'\xff\x02\x00k{"command": "notifyPlayerStatusChanged", "duration": 310000, "playerState": "BUFFERING", "progress": 82198}\xff\x03' b'\xff\x02\x00k{"command": "notifyPlayerStatusChanged", "duration": 310000, "playerState": "BUFFERING", "progress": 82198}\xff\x03' b'\xff\x02\x00i{"command": "notifyPlayerStatusChanged", "duration": 310000, "playerState": "PLAYING", "progress": 82198}\xff\x03' b'\xff\x02\x00\xbd{"audioBitPerSample": 16, "audioBitrate": 1411200, "audioChannels": 2, "audioCodec": 4, "audioSamplingRate": 44100, "command": "notifyAudioFormatUpdated", "mediaformat": 6, "streamType": 0}\xff\x03' b'\xff\x02\x00k{"command": "notifyPlayerStatusChanged", "duration": 310000, "playerState": "BUFFERING", "progress": 82198}\xff\x03' b'\xff\x02\x00k{"command": "notifyPlayerStatusChanged", "duration": 309803, "playerState": "BUFFERING", "progress": 82197}\xff\x03' b'\xff\x02\x00]{"command": "notifyPlayerStatusChanged", "duration": 0, "playerState": "IDLE", "progress": 0}\xff\x03' b'\xff\x02\x00]{"command": "notifyPlayerStatusChanged", "duration": 0, "playerState": "IDLE", "progress": 0}\xff\x03' b'\xff\x02\x02m{"command": "notifyMediaChanged", "mediaInfo": {"itemId": "4c469e5c-1f75-4d63-abab-448418d596fd", "mediaId": "208020638", "mediaType": 0, "metadata": {"albumTitle": "Enhanced Music Best of 2021, mixed by Tritonal", "artists": ["Praana"], "duration": 390000, "images": {"high": {"url": "https://resources.tidal.com/images/cd6c82ca/da13/4499/bc38/fc4b5c394836/1280x1280.jpg"}, "low": {"url": "https://resources.tidal.com/images/cd6c82ca/da13/4499/bc38/fc4b5c394836/320x320.jpg"}, "medium": {"url": "https://resources.tidal.com/images/cd6c82ca/da13/4499/bc38/fc4b5c394836/640x640.jpg"}}, "title": "Becoming Earth (Mixed)"}}}\xff\x03' b'\xff\x02\x00g{"command": "notifyPlayerStatusChanged", "duration": 390000, "playerState": "BUFFERING", "progress": 0}\xff\x03' b'\xff\x02\x02\xba{"command": "notifyMediaChanged", "mediaInfo": {"customData": "{\"audioMode\": \"STEREO\", \"audioQuality\": \"LOSSLESS\"}", "itemId": "4c469e5c-1f75-4d63-abab-448418d596fd", "mediaId": "208020638", "mediaType": 0, "metadata": {"albumTitle": "Enhanced Music Best of 2021, mixed by Tritonal", "artists": ["Praana"], "duration": 390000, "images": {"high": {"url": "https://resources.tidal.com/images/cd6c82ca/da13/4499/bc38/fc4b5c394836/1280x1280.jpg"}, "low": {"url": "https://resources.tidal.com/images/cd6c82ca/da13/4499/bc38/fc4b5c394836/320x320.jpg"}, "medium": {"url": "https://resources.tidal.com/images/cd6c82ca/da13/4499/bc38/fc4b5c394836/640x640.jpg"}}, "title": "Becoming Earth (Mixed)"}}}\xff\x03' b'\xff\x02\x00d{"command": "notifyPlayerStatusChanged", "duration": 390000, "playerState": "PAUSED", "progress": 0}\xff\x03' b'\xff\x02\x00g{"command": "notifyPlayerStatusChanged", "duration": 390000, "playerState": "BUFFERING", "progress": 0}\xff\x03' b'\xff\x02\x00g{"command": "notifyPlayerStatusChanged", "duration": 390000, "playerState": "BUFFERING", "progress": 0}\xff\x03' b'\xff\x02\x00\xbd{"audioBitPerSample": 16, "audioBitrate": 1411200, "audioChannels": 2, "audioCodec": 4, "audioSamplingRate": 44100, "command": "notifyAudioFormatUpdated", "mediaformat": 6, "streamType": 0}\xff\x03' b'\xff\x02\x00e{"command": "notifyPlayerStatusChanged", "duration": 390000, "playerState": "PLAYING", "progress": 0}\xff\x03' b'\xff\x02\x00g{"command": "notifyPlayerStatusChanged", "duration": 390000, "playerState": "BUFFERING", "progress": 0}\xff\x03' b'\xff\x02\x00e{"command": "notifyPlayerStatusChanged", "duration": 390000, "playerState": "PLAYING", "progress": 0}\xff\x03' b'\xff\x02\x00g{"command": "notifyPlayerStatusChanged", "duration": 390000, "playerState": "PLAYING", "progress": 500}\xff\x03' b'\xff\x02\x00h{"command": "notifyPlayerStatusChanged", "duration": 390000, "playerState": "PLAYING", "progress": 1000}\xff\x03' b'\xff\x02\x00h{"command": "notifyPlayerStatusChanged", "duration": 390000, "playerState": "PLAYING", "progress": 1500}\xff\x03' b'\xff\x02\x00h{"command": "notifyPlayerStatusChanged", "duration": 390000, "playerState": "PLAYING", "progress": 2000}\xff\x03' b'\xff\x02\x00h{"command": "notifyPlayerStatusChanged", "duration": 390000, "playerState": "PLAYING", "progress": 2500}\xff\x03' b'\xff\x02\x00g{"command": "notifyPlayerStatusChanged", "duration": 390000, "playerState": "PAUSED", "progress": 2500}\xff\x03' b'\xff\x02\x00]{"command": "notifyPlayerStatusChanged", "duration": 0, "playerState": "IDLE", "progress": 0}\xff\x03' b'\xff\x02\x00]{"command": "notifyPlayerStatusChanged", "duration": 0, "playerState": "IDLE", "progress": 0}\xff\x03' b'\xff\x02\x02\x84{"command": "notifyMediaChanged", "mediaInfo": {"itemId": "da6b982d-2747-4272-9c1b-00c2339e830a", "mediaId": "208020639", "mediaType": 0, "metadata": {"albumTitle": "Enhanced Music Best of 2021, mixed by Tritonal", "artists": ["Tritonal", "Cristina Soto"], "duration": 278000, "images": {"high": {"url": "https://resources.tidal.com/images/cd6c82ca/da13/4499/bc38/fc4b5c394836/1280x1280.jpg"}, "low": {"url": "https://resources.tidal.com/images/cd6c82ca/da13/4499/bc38/fc4b5c394836/320x320.jpg"}, "medium": {"url": "https://resources.tidal.com/images/cd6c82ca/da13/4499/bc38/fc4b5c394836/640x640.jpg"}}, "title": "Everafter (Cubicore Remix)"}}}\xff\x03' b'\xff\x02\x00d{"command": "notifyPlayerStatusChanged", "duration": 278000, "playerState": "PAUSED", "progress": 0}\xff\x03' b'\xff\x02\x00g{"command": "notifyPlayerStatusChanged", "duration": 278000, "playerState": "BUFFERING", "progress": 0}\xff\x03' b'\xff\x02\x02\xd1{"command": "notifyMediaChanged", "mediaInfo": {"customData": "{\"audioMode\": \"STEREO\", \"audioQuality\": \"LOSSLESS\"}", "itemId": "da6b982d-2747-4272-9c1b-00c2339e830a", "mediaId": "208020639", "mediaType": 0, "metadata": {"albumTitle": "Enhanced Music Best of 2021, mixed by Tritonal", "artists": ["Tritonal", "Cristina Soto"], "duration": 278000, "images": {"high": {"url": "https://resources.tidal.com/images/cd6c82ca/da13/4499/bc38/fc4b5c394836/1280x1280.jpg"}, "low": {"url": "https://resources.tidal.com/images/cd6c82ca/da13/4499/bc38/fc4b5c394836/320x320.jpg"}, "medium": {"url": "https://resources.tidal.com/images/cd6c82ca/da13/4499/bc38/fc4b5c394836/640x640.jpg"}}, "title": "Everafter (Cubicore Remix)"}}}\xff\x03' b'\xff\x02\x00d{"command": "notifyPlayerStatusChanged", "duration": 278000, "playerState": "PAUSED", "progress": 0}\xff\x03' b'\xff\x02\x00g{"command": "notifyPlayerStatusChanged", "duration": 278000, "playerState": "BUFFERING", "progress": 0}\xff\x03' b'\xff\x02\x00g{"command": "notifyPlayerStatusChanged", "duration": 278000, "playerState": "BUFFERING", "progress": 0}\xff\x03' b'\xff\x02\x00e{"command": "notifyPlayerStatusChanged", "duration": 278000, "playerState": "PLAYING", "progress": 0}\xff\x03' b'\xff\x02\x00\xbd{"audioBitPerSample": 16, "audioBitrate": 1411200, "audioChannels": 2, "audioCodec": 4, "audioSamplingRate": 44100, "command": "notifyAudioFormatUpdated", "mediaformat": 6, "streamType": 0}\xff\x03' b'\xff\x02\x00g{"command": "notifyPlayerStatusChanged", "duration": 277981, "playerState": "PLAYING", "progress": 500}\xff\x03' b'\xff\x02\x00h{"command": "notifyPlayerStatusChanged", "duration": 277981, "playerState": "PLAYING", "progress": 1000}\xff\x03' b'\xff\x02\x00h{"command": "notifyPlayerStatusChanged", "duration": 277981, "playerState": "PLAYING", "progress": 1500}\xff\x03' b'\xff\x02\x00h{"command": "notifyPlayerStatusChanged", "duration": 277981, "playerState": "PLAYING", "progress": 2000}\xff\x03' b'\xff\x02\x00h{"command": "notifyPlayerStatusChanged", "duration": 277981, "playerState": "PLAYING", "progress": 2500}\xff\x03' b'\xff\x02\x00h{"command": "notifyPlayerStatusChanged", "duration": 277981, "playerState": "PLAYING", "progress": 3000}\xff\x03' b'\xff\x02\x00h{"command": "notifyPlayerStatusChanged", "duration": 277981, "playerState": "PLAYING", "progress": 3500}\xff\x03' b'\xff\x02\x00h{"command": "notifyPlayerStatusChanged", "duration": 277981, "playerState": "PLAYING", "progress": 4000}\xff\x03' b'\xff\x02\x00g{"command": "notifyPlayerStatusChanged", "duration": 277981, "playerState": "PAUSED", "progress": 4000}\xff\x03' b'\xff\x02\x001{"command": "setRepeatMode", "repeatMode": "OFF"}\xff\x03' b'\xff\x02\x00+{"command": "setShuffle", "shuffle": false}\xff\x03' b'\xff\x02\x00]{"command": "notifyPlayerStatusChanged", "duration": 0, "playerState": "IDLE", "progress": 0}\xff\x03' b'\xff\x02\x02>{"command": "notifyMediaChanged", "mediaInfo": {"itemId": "79fabdad-59c5-4072-a5c5-6ea2705c8e33", "mediaId": "234352257", "mediaType": 0, "metadata": {"albumTitle": "Sharks", "artists": ["Imagine Dragons"], "duration": 191000, "images": {"high": {"url": "https://resources.tidal.com/images/ac26a272/8436/4e89/82f6/68b0ae9bd6a9/1280x1280.jpg"}, "low": {"url": "https://resources.tidal.com/images/ac26a272/8436/4e89/82f6/68b0ae9bd6a9/320x320.jpg"}, "medium": {"url": "https://resources.tidal.com/images/ac26a272/8436/4e89/82f6/68b0ae9bd6a9/640x640.jpg"}}, "title": "Sharks"}}}\xff\x03' b'\xff\x02\x00d{"command": "notifyPlayerStatusChanged", "duration": 191000, "playerState": "PAUSED", "progress": 0}\xff\x03' b'\xff\x02\x00g{"command": "notifyPlayerStatusChanged", "duration": 191000, "playerState": "BUFFERING", "progress": 0}\xff\x03' b'\xff\x02\x02\x89{"command": "notifyMediaChanged", "mediaInfo": {"customData": "{\"audioMode\": \"STEREO\", \"audioQuality\": \"HI_RES\"}", "itemId": "79fabdad-59c5-4072-a5c5-6ea2705c8e33", "mediaId": "234352257", "mediaType": 0, "metadata": {"albumTitle": "Sharks", "artists": ["Imagine Dragons"], "duration": 191000, "images": {"high": {"url": "https://resources.tidal.com/images/ac26a272/8436/4e89/82f6/68b0ae9bd6a9/1280x1280.jpg"}, "low": {"url": "https://resources.tidal.com/images/ac26a272/8436/4e89/82f6/68b0ae9bd6a9/320x320.jpg"}, "medium": {"url": "https://resources.tidal.com/images/ac26a272/8436/4e89/82f6/68b0ae9bd6a9/640x640.jpg"}}, "title": "Sharks"}}}\xff\x03' b'\xff\x02\x00d{"command": "notifyPlayerStatusChanged", "duration": 191000, "playerState": "PAUSED", "progress": 0}\xff\x03' b'\xff\x02\x00g{"command": "notifyPlayerStatusChanged", "duration": 191000, "playerState": "BUFFERING", "progress": 0}\xff\x03' b'\xff\x02\x00g{"command": "notifyPlayerStatusChanged", "duration": 191000, "playerState": "BUFFERING", "progress": 0}\xff\x03' b'\xff\x02\x00e{"command": "notifyPlayerStatusChanged", "duration": 191000, "playerState": "PLAYING", "progress": 0}\xff\x03' b'\xff\x02\x00\xbd{"audioBitPerSample": 24, "audioBitrate": 2116800, "audioChannels": 2, "audioCodec": 7, "audioSamplingRate": 44100, "command": "notifyAudioFormatUpdated", "mediaformat": 6, "streamType": 0}\xff\x03' b'\xff\x02\x00g{"command": "notifyPlayerStatusChanged", "duration": 190883, "playerState": "PLAYING", "progress": 500}\xff\x03' b'\xff\x02\x00h{"command": "notifyPlayerStatusChanged", "duration": 190883, "playerState": "PLAYING", "progress": 1000}\xff\x03' b'\xff\x02\x00h{"command": "notifyPlayerStatusChanged", "duration": 190883, "playerState": "PLAYING", "progress": 1500}\xff\x03' b'\xff\x02\x00h{"command": "notifyPlayerStatusChanged", "duration": 190883, "playerState": "PLAYING", "progress": 2000}\xff\x03' b'\xff\x02\x00h{"command": "notifyPlayerStatusChanged", "duration": 190883, "playerState": "PLAYING", "progress": 2500}\xff\x03' b'\xff\x02\x00h{"command": "notifyPlayerStatusChanged", "duration": 190883, "playerState": "PLAYING", "progress": 3000}\xff\x03' b'\xff\x02\x00h{"command": "notifyPlayerStatusChanged", "duration": 190883, "playerState": "PLAYING", "progress": 3500}\xff\x03' b'\xff\x02\x00g{"command": "notifyPlayerStatusChanged", "duration": 190883, "playerState": "PAUSED", "progress": 3500}\xff\x03'

Information we can use for metadata!

It appears to have 4 header bytes, a message, and 2 trailing bytes.

linknum23 commented 2 years ago

That metadata looks very promising

charliesjc commented 2 years ago

Indeed it is. I forgot to mention that the speaker_controller_application that's included with these binaries also uses the same socket because that also completely breaks when you connect to it.

SteveMicroNova commented 5 months ago

I'd like to bump this thread and let everyone know that we're actively working on this now, hopefully we'll see this in an upcoming release in a reasonably short timeframe.

In the meantime, have any of you had luck continuing to use your custom implementations personally? I'm having troubles with that ifi-tidal-release repo, seems a few of the apt dependencies are deprecated and I may have to bark up a different tree.