dheijl / swyh-rs

Stream What You Hear written in rust, inspired by SWYH.
MIT License
353 stars 15 forks source link

Not picked up as a stream by Roon Radio #55

Closed privacyguy123 closed 5 months ago

privacyguy123 commented 2 years ago

Yet the regular SWYH is - going to the IP link prompts for a .wav download rather than stream too ... am I missing something here? :S

dheijl commented 2 years ago

I'm not familiar with Roon. I suppose it does not support raw pcm audio. SWYH can stream mp3, but swyh-rs can only stream raw pcm, with or without a WAV header.

privacyguy123 commented 2 years ago

Hmm ... both options in original swyh work, MP3 & PCM/L16 - is this an easy fix or not something that's going to be considered?

dheijl commented 2 years ago

I have no idea, it can be something as simple as some parameter in a http header, but I don't have Roon so I can not test...

privacyguy123 commented 2 years ago

Can we deduct what it is from the fact that Roon is compatible with the original swyh and go from there perhaps?

EDIT: here's what I see, the Roon client does try to connect and gets dumped immediately

Configuration { server_port: Some(5901), auto_resume: true, sound_source: "Headphones (Realtek(R) Audio)", log_level: Debug, ssdp_interval_mins: 0.5, auto_reconnect: true, disable_chunked: false, use_wave_format: false, bits_per_sample: Some(16), monitor_rms: true, last_renderer: "None", last_network: "192.168.1.250", config_dir: "C:\\Users\\Alex\\.swyh-rs" }
Setup audio sources
Now running at ABOVE_NORMAL_PRIORITY_CLASS
Capturing audio from: Headphones (Realtek(R) Audio)
Default audio SupportedStreamConfig { channels: 2, sample_rate: SampleRate(48000), buffer_size: Unknown, sample_format: F32 }
Discover networks
Starting SSDP discovery
The wave_reader is now receiving samples
The streaming server is listening on http://192.168.1.250:5901/stream/swyh.wav
Sample rate: 48000, sample format: audio/L16 (PCM)
Received request /stream/swyh.wav from 192.168.1.250:2569
Streaming audio/L16 (LPCM), input sample format F32, channels=2, rate=48000, disable chunked=false to 192.168.1.250:2569
Streaming to 192.168.1.250:2569 has ended
Received request /stream/swyh.wav from 192.168.1.250:2570
Streaming audio/L16 (LPCM), input sample format F32, channels=2, rate=48000, disable chunked=false to 192.168.1.250:2570
Streaming to 192.168.1.250:2570 has ended
dheijl commented 2 years ago

The thing that is most likely to allow me to pinpoint the cause is a Wireshark sniffer trace of both a (successful) SWYH PCM/L16 session and an (unsuccessful) swyh-rs session. I suppose you have already tried swyh-rs with and without the WAV header, and with and without chunked transfer encoding, and that no combination of options works?

privacyguy123 commented 2 years ago

I know a little bit but not a total computer wizard ... would I just filter out Wireshark to 192.168.1.250 in this case and post it?

Yes no combination is playing nice - worth noting that I can't seem to get anything to open the stream to be honest, my FireFox tries to download the file instead of playing it resulting in a never ending download and VLC/JRiver just crash.

dheijl commented 2 years ago

If you save the sniffer traces to file and zip them you can attach them to your comment here.

privacyguy123 commented 2 years ago

Could you walk me through how to filter out these requests? Wireshark is full of requests ...

EDIT: Think I've got what you need ... a failed swyh-rs connection and a good swyh one

dheijl commented 2 years ago

Thanks! let's hope I'll find what I'm looking for...

dheijl commented 2 years ago

I'm sorry but there's nothing of interest in the trace file...It looks like you filtered out all interesting bits? The only thing I could find is a HTTP GET request from 192.168.1.250 to itself (ip source == ip destination).

privacyguy123 commented 2 years ago

Did it not capture Roon accessing /stream/stream.mp3 correctly from original swyh and the connection getting dumped immediately on swyh-rs? swyh port is 13337 swyh-rs is 5901, I left plenty of info on it in there - I am connecting via loopback on the same machine so localhost stuff is all you need.

Perhaps you could talk me through how to capture what you need specifically ...

dheijl commented 2 years ago

I'm sorry but there is nothing of interest to see on 127.0.0.1. No sign of swyh mp3 either, but then this would not be relevant anyway because I'm only interested in a pcm audio/l16 request from swyh, not in mp3 requests.

privacyguy123 commented 2 years ago

I am using swyh to loopback audio on the same machine, ip.addr == 192.168.1.250 (my local ip) is all you need - I didn't have it in PCM mode though yes you are right.

dheijl commented 2 years ago

So in reality SWYH is not streaming PCM/L16 but "float64le" using the "raw" HQPlayer protocol of Roon:

HTTP/1.1 200 OK
Content-Length: 0
Content-Type: application/x-hqplayer-raw
X-HQPlayer-Raw-Title: Roon
X-HQPlayer-Raw-SampleRate: 48000
X-HQPlayer-Raw-Channels: 2
X-HQPlayer-Raw-Format: float64le

Conclusion: or the moment swyh-rs can not support Roon, as it only streams PCM/L16. Sorry about that but thanks for going through the trouble to help debugging this issue.

privacyguy123 commented 2 years ago

Understood - thanks for looking into it :)

oldsweatyman commented 2 years ago

+1 to requesting support for roon. immense feature for me and probably many other users.

dheijl commented 2 years ago

I'm sorry but it's not going to happen. Roon is closed source and a commercial product. Swyh-rs is open source and free, and I don't have Roon and have no need or use for it, so I can not support it. It looks like the original SWYH supports Roon, have you tried it?

dheijl commented 2 years ago

I would appreciate it very much if you could try the latest release (1.4.1) with the new support for FLAC format, and if you could let me know if it works or not.

DrCWO commented 5 months ago

Hi @dheijl tested today with some other things and found the FLAC output of swyh-rs is still not accepted by Roon. In the past I built a FLAC Radio station with node.js that worked with Roon. So if I find time I will send you the headers of both, the working node.js and the not working from swyh-rs so you can find out the difference. Please stay tuned... Best DrCWO

DrCWO commented 5 months ago

So here we go: capture1.flac is a curl dump of the 24/96 FLAC stream accepted by Roon. capture1.flac is a 24/48 curl dump from sywh-rs not accepted by Roon. I hope you can do a modification to make Roon accept your FLAC stream. Best DrCWO

root@rooExtend:/home/pi/rooExtend# hexdump capture1.flac  | more
0000000 4c66 4361 0000 2200 8004 8004 0000 0000
0000010 0000 7017 7003 0000 0000 0000 0000 0000
0000020 0000 0000 0000 0000 0000 0084 2800 0020
0000030 0000 6572 6566 6572 636e 2065 696c 4662
0000040 414c 2043 2e31 2e33 2033 3032 3931 3830
0000050 3430 0000 0000 f8ff 1c3b 2c00 0410 6735
0000060 dfcd cc24 3ca5 6996 b92e dd49 2d49 33df
0000070 4932 f6a5 d4f9 a7b2 3979 caa6 4966 4faf
0000080 4b36 e9a5 94a7 5b9a 6fd2 a4f3 eeb9 5cba
0000090 9e93 a66e d994 37bd 27cf f5d2 9f99 6649
00000a0 3593 ee32 957c d737 f749 7932 254d 49be
00000b0 a53e 4baf 4f9f c93c 4a9f 6e69 aa4b ce64
00000c0 ce9d 527d 4eaa a5a9 93bd 5249 2b75 25f3
00000d0 3f75 d324 3e9f 9ce7 f59c bbb9 70f2 e9a5
00000e0 9dcc ac25 9cdc d4d2 9bcf b3cf 249b e9dd
00000f0 27b9 4a3d b2f5 9b53 9c4c a5c9 76da 4e9d
0000100 dbac a72b cc27 cdfe 5657 af54 552e cd7e
0000110 75ea b3ab 3c7b 6ccf 7a99 6c79 5ab7 92ce
0000120 cd5b 2fe9 b25b d459 99ca 36ad 2f4d 52d6
0000130 934f 9524 9cdf 6cab 6ab7 fa99 72e5 a495
0000140 bf92 6b3f 9c92 cff7 9be4 cf3b 6f56 49a7
0000150 e64b eedd 6dcd cb5b c933 0051 3743 3249
0000160 7a5a a465 cbe4 a4ca acd5 4dfd b339 d29f
0000170 7299 cbe5 3ba9 a9dc 256f 4966 cffa 5ff5
0000180 e47b ad94 dd3c cf25 b337 a7d2 4c5e 6da9
0000190 2c2f 53ff bf5f 32dd 935c 6fb2 3dcd 9393
00001a0 b57c 9272 ef7e a79c 923d 33a7 c939 2939
00001b0 4d32 b4fd a9ae b93d b6ea a753 b972 cbcc
00001c0 52fb 9792 b3df 9fa9 fe2f a692 3bf9 3b25
00001d0 749b d599 ea24 d3a5 f294 3c1b 539e 5e52
00001e0 fedc 2f77 cb2d 9329 7449 f692 276b 7b36
00001f0 a53d 92f3 fa7b f277 b797 e5e9 3cbb 57a7
0000200 3f79 de97 ef74 b693 52bb 294d 25e5 9be5
0000210 944b 9eff 26d3 e664 a64c 96b3 a47e 94d5
0000220 a5a9 a472 36cf fd4a 59bf 3c7b 4d9e 2b7b
0000230 d29e b54c d5b3 4d69 bd9c 6526 e449 f5ef
0000240 e549 c9d5 9994 5b72 59c9 c934 34b7 97dc
0000250 2fe5 4ece 75b2 b292 4240 ff50 3bf8 011c
0000260 102b 3a04 5ddd 922f d959 7367 3b6d 53ee
0000270 a6f9 e55f d4c9 4995 e639 db92 dcee 9ec9
0000280 3759 36fd bb95 f63b 4b69 53ce 7d5f 7fce
0000290 de53 3965 c964 93c9 b4c9 bc96 cbd2 334f
00002a0 b295 cc6b b9f4 2f4f d9ce 6f93 9a59 3ef3
00002b0 bff4 3929 a7b6 d3cd 52ed 665a a6b7 cffe
00002c0 de33 3ec9 9995 54f2 cd93 7a92 4976 24d7
00002d0 59bf 72f2 a7b9 a439 3b9f 7bbd 58b2 3567
00002e0 d26c fe65 d65c 4e67 be69 9575 f3ba 9b3f
00002f0 caa5 9994 fe54 4973 722f 64f7 77a9 2939
0000300 e9b7 9cec b3af 2c29 24a9 7397 259b 773a
0000310 9bcb a97a eea4 f2ab 7379 e7cd e593 ce4c
0000320 2b67 b39c 93ef 7337 6bba fcea 99d2 ce99
0000330 3953 7c96 cbf7 b39b a5b4 539e d256 5d7b
0000340 725e 29cb 9cec 2dcd 9255 4b4d b225 327d
0000350 dda6 92e4 cdb4 75de 26dd 7aa5 0820 be79
0000360 b44f 6496 ffbc c966 7226 c94a 6a33 eb93
0000370 263d 9ad3 c95d ddd3 b452 27a9 d94c 53ce
0000380 dcb7 fb96 999c 7cfd 97ec ba96 ca6c a64e
0000390 f3ae 95a5 e6ed 24ef 3dcb 5b7b 975e ed2f
00003a0 f4ff fdf4 b425 a592 c933 cd72 e4d4 6b9b
00003b0 dc4d a999 b634 724e 35cb 94ad 9b94 e53c
00003c0 d575 f62d 25f5 dc9d f9ad 275f 99be 9eb2
00003d0 926e b36e 52d2 a94e 66d6 e0c9 359b a5ab
00003e0 b5e4 e626 aa65 e5e4 4b4b 6949 aa92 4952
00003f0 6ce6 a9cc 54d5 93d3 e427 2da9 f24f e54c
0000400 e597 9ad9 55ca 9d29 9fb4 523b dd52 2a29
0000410 674f 266d 675f 395d 33cb 3bd9 523a b2a6
0000420 29c9 3333 55fe 726e 6999 79f2 2653 7a4d
0000430 a97c f3b6 d2bc 4959 b479 7bf9 2655 5dd9
root@rooExtend:/home/pi/rooExtend# hexdump capture2.flac  | more
0000000 04f6 50f7 44f5 99f6 aaf4 0ef6 3ef4 b6f5
0000010 bef3 4bf5 13f3 b1f4 79f2 27f4 2bf2 eff3
0000020 19f2 00f4 faf1 18f4 b6f1 1af4 80f1 2df4
0000030 59f1 39f4 f9f0 e9f3 62f0 43f3 e3ef aaf2
0000040 d6ef 88f2 5bf0 00f3 33f1 d0f3 eff1 8af4
0000050 5ef2 02f5 c9f2 86f5 4bf3 2ff6 b8f3 c5f6
0000060 5ef4 8bf7 71f5 b1f8 81f6 c1f9 2df7 5bfa
0000070 42f7 47fa b8f6 85f9 0cf6 98f8 8cf5 d3f7
0000080 0cf5 12f7 c7f4 93f6 08f5 a8f6 b6f5 37f7
0000090 bff6 2cf8 f0f7 4cf9 01f9 48fa 30fa 60fb
00000a0 85fb a6fc 8bfc a2fd 63fd 6ffe 5efe 58ff
00000b0 58ff 3900 3200 fc00 bb00 7001 fd00 a401
00000c0 6a01 0002 0302 7902 8a02 c702 ee02 e102
00000d0 3003 da02 5103 c302 7303 c202 a903 e002
00000e0 de03 fe02 3704 3a03 9c04 7803 da04 8203
00000f0 0f05 7403 7305 8803 2506 e603 ce06 3f04
0000100 5a07 8804 e607 dc04 4108 0505 7808 0e05
0000110 8b08 f304 9e08 d404 d608 d104 0909 c904
0000120 3109 bf04 6f09 d704 f109 4005 930a cf05
0000130 1b0b 4706 5f0b 8406 500b 7506 1d0b 3a06
0000140 af0a b405 ee09 c904 0d09 ba03 5008 d302
0000150 c507 2002 5a07 8f01 0907 2101 d906 e700
0000160 d606 fe00 e706 4401 0b07 a801 2007 f501
0000170 1d07 1e02 0b07 3302 c606 0d02 8106 da01
0000180 2906 8301 d305 1c01 a705 db00 7405 9700
0000190 3805 5a00 e704 1e00 a104 ffff 4c04 d9ff
00001a0 d803 96ff 5303 3fff a602 c0fe 1502 63fe
00001b0 8001 05fe f400 a5fd 9200 56fd 6300 18fd
00001c0 9100 20fd d100 39fd 1601 68fd 6001 b1fd
00001d0 b301 0bfe ee01 45fe dd01 1ffe b601 d2fd
00001e0 7a01 67fd 6b01 2afd 7301 0ffd 5801 e2fc
00001f0 4401 d4fc 2e01 d6fc 5a01 23fd c001 a9fd
0000200 4102 3bfe d402 d1fe 4403 30ff 9003 58ff
0000210 8503 1aff 4803 aafe 1c03 60fe fe02 3efe
0000220 ea02 3efe db02 50fe f202 8cfe 2003 e3fe
0000230 5903 4dff a803 d4ff 0b04 7000 6e04 0801
0000240 b004 7f01 e404 ef01 0005 5102 fb04 9202
0000250 db04 ae02 a804 a902 7804 9c02 7404 b802
0000260 af04 0f03 ea04 5903 0905 7d03 0d05 7e03
0000270 f904 6a03 dc04 5303 a104 2003 5704 de02
0000280 2304 aa02 fc03 7502 af03 0f02 4f03 9701
0000290 1503 5c01 1203 7701 4203 d901 6e03 3b02
00002a0 8e03 8802 a703 c402 9903 d802 5803 b702
00002b0 ed02 6502 8602 0e02 2702 b401 c701 5501
00002c0 7401 0801 3601 db00 1501 d500 fd00 da00
00002d0 cf00 c400 a100 a700 9500 a200 8b00 9100
00002e0 6e00 5800 4200 ffff 0f00 97ff f7ff 57ff
00002f0 daff 30ff a1ff 14ff 6aff 1bff 46ff 44ff
0000300 1cff 61ff e5fe 58ff e4fe 64ff 10ff 82ff
0000310 41ff 9bff 64ff afff 63ff b6ff 55ff caff
0000320 31ff d8ff ecfe c1ff aafe a0ff 99fe a3ff
0000330 a1fe b6ff 9ffe afff aafe a4ff d0fe a6ff
0000340 05ff b2ff 21ff a7ff fffe 64ff b8fe 09ff
0000350 76fe c7fe 45fe a8fe 0ffe 8bfe e2fd 6bfe
0000360 defd 60fe f8fd 67fe 2efe 91fe 72fe dafe
0000370 bbfe 2eff 13ff 8bff 5cff ceff 7bff d7ff
0000380 88ff c5ff 91ff acff 8fff 8aff 87ff 6cff
0000390 7bff 5fff 73ff 6dff 5eff 7aff 48ff 80ff
00003a0 38ff 7cff 30ff 6dff 38ff 5dff 31ff 33ff
00003b0 26ff 04ff 28ff e9fe 32ff dcfe 3dff d3fe
00003c0 33ff bdfe 2fff b8fe 3dff dafe 5aff 20ff
00003d0 86ff 80ff b2ff d7ff e7ff 2100 1900 4f00
00003e0 4400 5e00 7400 6600 a100 6c00 bc00 6e00
00003f0 be00 6500 b100 5700 a100 5000 8f00 5400
0000400 7500 5e00 5100 6800 2e00 7700 1100 8800
0000410 feff 9800 edff 9e00 d8ff 9400 bbff 7700
0000420 9eff 5500 8dff 3b00 79ff 2000 64ff 0600
0000430 4fff efff 40ff daff 2bff b6ff fdfe 71ff
DrCWO commented 5 months ago

One more comment on the captures Streams. Dragging the captured files to Foobar and getting the properties

I see this for capute1.flac ...

image

... and this for capture2.flac

image

My guess with caputre2.flac there is something completely wrong in the header as the complete "General" section is missing.

Best DrCWO

dheijl commented 5 months ago

The FLAC produced by swyh-rs is generated with the official LibFlac, and there is no such thing as a "General" section in the FLAC format. But there is only minimal metadata in the swyh-rs flac stream as I do not have any metadata available to put in except for the STREAMINFO. Other metadata is optional anyway.

Anyway, a curl dump display is useless to me, but I'm prepared to have a look at the first few KB of the flac files if you can attach them as a file .

Perhaps you can ask Roon why they need extra metadata?

DrCWO commented 5 months ago

I think the issue with this FLAC is different. As I can't see a FLAC header in the stream that a grabbed with curl I suspect that you don't send it if you receive the http request. In my server I start FLAC encoding after the incoming http request and get the audio data that was ready at that time for the first package. In this case first information in the http FLAC stream is the FLAC header. Looking at your stream there is no FLAC header so you expect that the receiver can detect the beginning of the next FLAC container. Roon need the FLAC header to determin the number of channels, format and sample rate. It would be great if you might be willing to investigate that and modify the implementation in a way that after the http request a valid http header will be sent. Doing so it would be compatible with Roon and probably also other receivers that need a FLAC header at the beginning of the stream.

EDIT: Already deleted the files but I will record again and send them...

DrCWO commented 5 months ago

Sorry, I can't drop FLAC files here πŸ‘Ž Please send me an e-mail to info@definiteaudio.de and I will reply with the files. Thanks' a lot for your support πŸ‘

dheijl commented 5 months ago

The flac header is definitely there.

DrCWO commented 5 months ago

I think we're getting closer now.

I tried Roon again and saw that Roon opens the stream twice in quick succession. Please see the log output here:

Configuration { server_port: Some(5901), auto_resume: false, sound_source: Some("Voicemeeter Out B2 (VB-Audio Voicemeeter VAIO)"), sound_source_index: Some(16), log_level: Info, ssdp_interval_mins: 10.0, auto_reconnect: false, _disable_chunked: true, lpcm_stream_size: Some(U64maxNotChunked), wav_stream_size: Some(U32maxNotChunked), rf64_stream_size: Some(U64maxNotChunked), flac_stream_size: Some(U64maxChunked), use_wave_format: false, bits_per_sample: Some(24), streaming_format: Some(Flac), monitor_rms: false, capture_timeout: Some(2000), inject_silence: Some(false), buffering_delay_msec: Some(0), last_renderer: Some("foobar2000 Media Renderer foobar2000 Media Server (cwoehlri) [NB180]"), active_renderers: [], last_network: Some("192.168.0.247"), config_dir: "C:\\Users\\definiteaudio\\.swyh-rs", config_id: Some(""), read_only: false }
Setup audio sources
Now running at ABOVE_NORMAL_PRIORITY_CLASS
Capturing audio from: Voicemeeter Out B2 (VB-Audio Voicemeeter VAIO)
Default audio SupportedStreamConfig { channels: 2, sample_rate: SampleRate(48000), buffer_size: Range { min: 0, max: 4294967295 }, sample_format: F32 }
Discover networks
Starting SSDP discovery
The streaming server is listening on http://192.168.0.247:5901/stream/swyh.wav
Streaming sample rate: 48000, bits per sample: 24, format: Flac
The wave_reader is now receiving samples
OH Get Volume on Arbeitszimmer host=192.168.0.111 port=49153 = 25%
AV Get Volume on foobar2000 Media Server (cwoehlri) [NB180] host=192.168.0.168 port=1723 = 100%
Received request /stream/swyh.flac from 192.168.0.247:56184
Streaming audio/FLAC, input sample format F32, channels=2, rate=48000, to 192.168.0.247:56184
Received request /stream/swyh.flac from 192.168.0.247:56185
Streaming audio/FLAC, input sample format F32, channels=2, rate=48000, to 192.168.0.247:56185
Streaming to 192.168.0.247:56184 has ended
Streaming to 192.168.0.247:56185 has ended

I now remember that I too had this issue while writing my Linux server with node.js!

During this time I found out what Roon does:

Can it be that your server delivers wrong data if the second request is received before the first one has ended? Maybe your server not able to react to the second request because the first one is not yet finished?

DrCWO commented 5 months ago

Please forget about the screenshot I sent with the properties. In case of getting data from your server I used the URL displayed in the log info (wav) instead of changing the extension to ".flac". This gave a WAV I renamed to flac ;-) So with my latest approach getting the FLAC data with curl I corrected that and now the "general" section is filled with the correct sample rate, width and channels. Sorry for leading you to the wrong direction...

dheijl commented 5 months ago

Please don’t be sorry, it's all part if the pleasure of debugging...

dheijl commented 5 months ago

Can it be that your server delivers wrong data if the second request is received before the first one has ended? Maybe your server not able to react to the second request because the first one is not yet finished? As far as I can see each request is handled in a seperate thread completely independent from all other requests...

DrCWO commented 5 months ago

Gues this means it is reentrant so no commun variables?

I think you don't have Roon for testing. Are you able to send a second request if the first chunk of the first request got transmitted to see what happens?

You also can get a free evaluation license of Roon here: https://roonlabs.com/ If you got it I can lead you to the place where Radio stations are created. So you will be able to debug with the requests coming from Roon. As I use the same "official" FLAC encoder in my implementation there should be something else causing the issue.

Have you ever checked if your FLAC header has a file length included? This is not valid for streaming. Even "0" is illegal. The file length data should not be available at all in the FLAC header. Please check.

So enough for today, have to watch my criminal story in TV now ;-)

DrCWO commented 5 months ago

What I did now is analyzing the files with metaflac. Here the result:

Here the output of my FLAC stream (96kHz)

C:\tmp\flac-1.4.3-win\Win64>metaflac --list recording1.flac
METADATA block #0
  type: 0 (STREAMINFO)
  is last: false
  length: 34
  minimum blocksize: 1152 samples
  maximum blocksize: 1152 samples
  minimum framesize: 0 bytes
  maximum framesize: 0 bytes
  sample_rate: 96000 Hz
  channels: 2
  bits-per-sample: 24
  total samples: 0
  MD5 signature: 00000000000000000000000000000000
METADATA block #1
  type: 4 (VORBIS_COMMENT)
  is last: true
  length: 40
  vendor string: reference libFLAC 1.3.3 20190804
  comments: 0

And this is the output of yours:

C:\tmp\flac-1.4.3-win\Win64>metaflac --list recording2.flac
METADATA block #0
  type: 0 (STREAMINFO)
  is last: false
  length: 34
  minimum blocksize: 1152 samples
  maximum blocksize: 1152 samples
  minimum framesize: 0 bytes
  maximum framesize: 0 bytes
  sample_rate: 48000 Hz
  channels: 2
  bits-per-sample: 24
  total samples: 0
  MD5 signature: 00000000000000000000000000000000
METADATA block #1
  type: 4 (VORBIS_COMMENT)
  is last: true
  length: 40
  vendor string: reference libFLAC 1.3.2 20190804
  comments: 0

For me the reason that it did not work as expected with Roon seems to be the duplicate request...

DrCWO commented 5 months ago

I now tried to fire one request, stop it after 0.2s and then fire the next. Looking in the log of swyh-rs looks the same as the request order of Roon. Data for both received requests seem to be OK... Will check http headers now...

DrCWO commented 5 months ago

Here we go. http headers differ. In my stream I have the additional entries

Connection: keep-alive
Keep-Alive: timeout=5

Would be great if you might include those and get me a new release for testing with Roon. Please

image

Maybe for debug purposes it would be great to see exactly the headers I use...

dheijl commented 5 months ago

If you run swyh-rs with log level debug the response headers are in the logfile. Currently the Connection : Close header is used, because there is normally only a single request. But I can try to make a build with the Connection: keep-alive header for you, no problem.

DrCWO commented 5 months ago

What I tested now:

This worked. So were are sure now that Roon accepts the FLAC data delivered by your http server! I am happy so we now know that the encoded file content is correct and will be accepted and played by Roon πŸ‘

This means: File content is correct and we have to look for other reasons...

DrCWO commented 5 months ago

Restarted with DEBUG but no response headers. Had I got anything wrong? image

dheijl commented 5 months ago

The debug log is a file named log.txt in the .swyh-rs folder in your home directory.

DrCWO commented 5 months ago

There's a lot of UPnP talk in there but what matters is at the end I guess. But no headers found in there...

Question: Is there an option to disable the UPnP mechanics as I don't need it for Roon...


Host: 192.168.0.97:52323
Connection: close
User-Agent: swyh-rs-Rust/0.x
Accept: */*
SOAPAction: "urn:schemas-upnp-org:service:RenderingControl:1#GetVolume"
Content-Type: text/xml; charset="utf-8"
accept-encoding: gzip
Content-Length: 345
10:38:42 [DEBUG] (1) ureq::response: Body of unknown size - read until socket close
10:38:42 [DEBUG] (1) ureq::unit: response 403 to POST http://192.168.0.97:52323/upnp/control/RenderingControl
10:38:42 [ERROR] <= SOAP POST error: http://192.168.0.97:52323/upnp/control/RenderingControl: status code 403

10:38:42 [DEBUG] (1) ureq::stream: dropping stream: Stream(TcpStream { addr: 192.168.0.247:55865, peer: 192.168.0.97:52323, socket: 1220 })
10:38:42 [DEBUG] (1) swyh_rs::openhome::rendercontrol: oh_get_volume response: <Error/>
10:38:42 [INFO] tb_log: AV Get Volume on KD-43X8305C host=192.168.0.97 port=52323 = -1%
10:38:42 [DEBUG] (1) swyh_rs: Renderer KD-43X8305C Volume: -1
10:39:14 [INFO] tb_log: Received request /stream/swyh.flac from 192.168.0.247:55867
10:39:14 [DEBUG] (13) swyh_rs::server::streaming_server: Now have 1 streaming clients
10:39:14 [INFO] tb_log: Streaming audio/FLAC, input sample format F32, channels=2, rate=48000, to 192.168.0.247:55867
10:39:15 [INFO] tb_log: Received request /stream/swyh.flac from 192.168.0.247:55868
10:39:15 [DEBUG] (15) swyh_rs::server::streaming_server: Now have 2 streaming clients
10:39:15 [INFO] tb_log: Streaming audio/FLAC, input sample format F32, channels=2, rate=48000, to 192.168.0.247:55868
10:39:15 [DEBUG] (13) swyh_rs::server::streaming_server: Now have 1 streaming clients left
10:39:15 [INFO] tb_log: Streaming to 192.168.0.247:55867 has ended
10:39:15 [DEBUG] (15) swyh_rs::server::streaming_server: Now have 0 streaming clients left
10:39:15 [INFO] tb_log: Streaming to 192.168.0.247:55868 has ended
dheijl commented 5 months ago

The ssdp can be disabled in the CLI version swyh-rs-cli.exe, included in the setup. I'll have a look why the headers don't show up.

EDIT: they only show up in the debug builds, you can download these builds from releases as a seperate zip file that contains just the exe, no setup.

DrCWO commented 5 months ago

And here is what i got and I think I see the issue :-) There is a "Content-Length" in the header! This has to be omitted as the Content-Length is unknown for a stream.

I would appreciate if you are willing to build a debug-release without the Content-Length in the header.

EDIT: Other clients seem to discard this but Roon is a bit more picky on that...

12:12:00 [DEBUG] (13) swyh_rs::server::streaming_server: <== Incoming Request(GET /stream/swyh.flac from Some(192.168.0.247:59893))
12:12:00 [DEBUG] (13) swyh_rs::server::streaming_server:  <== Incoming Request Header { field: HeaderField("Host"), value: "192.168.0.247" } from 192.168.0.247:59893
12:12:00 [DEBUG] (13) swyh_rs::server::streaming_server:  <== Incoming Request Header { field: HeaderField("Connection"), value: "close" } from 192.168.0.247:59893
12:12:00 [DEBUG] (13) swyh_rs::server::streaming_server:  <== Incoming Request Header { field: HeaderField("User-Agent"), value: "Roon/200001407 (RoonServer; windows)" } from 192.168.0.247:59893
12:12:00 [INFO] tb_log: Received request /stream/swyh.flac from 192.168.0.247:59893
12:12:00 [DEBUG] (13) swyh_rs::server::streaming_server: Now have 1 streaming clients
12:12:00 [INFO] tb_log: Streaming audio/FLAC, input sample format F32, channels=2, rate=48000, to 192.168.0.247:59893
12:12:00 [DEBUG] (13) swyh_rs::server::streaming_server: ==> Response:
12:12:00 [DEBUG] (13) swyh_rs::server::streaming_server:  ==> Content-Length: 18446744073709551615
12:12:00 [DEBUG] (13) swyh_rs::server::streaming_server:  ==> Response Header { field: HeaderField("Content-Type"), value: "audio/flac" } to 192.168.0.247:59893
12:12:00 [DEBUG] (13) swyh_rs::server::streaming_server:  ==> Response Header { field: HeaderField("TransferMode.dlna.org"), value: "Streaming" } to 192.168.0.247:59893
12:12:00 [DEBUG] (13) swyh_rs::server::streaming_server:  ==> Response Header { field: HeaderField("Server"), value: "swyh-rs tiny-http" } to 192.168.0.247:59893
12:12:00 [DEBUG] (13) swyh_rs::server::streaming_server:  ==> Response Header { field: HeaderField("Accept-Ranges"), value: "none" } to 192.168.0.247:59893
12:12:00 [DEBUG] (13) swyh_rs::server::streaming_server:  ==> Response Header { field: HeaderField("icy-name"), value: "swyh-rs" } to 192.168.0.247:59893
12:12:00 [DEBUG] (15) swyh_rs::server::streaming_server: <== Incoming Request(GET /stream/swyh.flac from Some(192.168.0.247:59894))
12:12:00 [DEBUG] (15) swyh_rs::server::streaming_server:  <== Incoming Request Header { field: HeaderField("Host"), value: "192.168.0.247" } from 192.168.0.247:59894
12:12:00 [DEBUG] (15) swyh_rs::server::streaming_server:  <== Incoming Request Header { field: HeaderField("Connection"), value: "close" } from 192.168.0.247:59894
12:12:00 [DEBUG] (15) swyh_rs::server::streaming_server:  <== Incoming Request Header { field: HeaderField("User-Agent"), value: "Roon/200001407 (RoonServer; windows)" } from 192.168.0.247:59894
12:12:00 [DEBUG] (15) swyh_rs::server::streaming_server:  <== Incoming Request Header { field: HeaderField("Icy-Metadata"), value: "1" } from 192.168.0.247:59894
12:12:00 [INFO] tb_log: Received request /stream/swyh.flac from 192.168.0.247:59894
12:12:00 [DEBUG] (15) swyh_rs::server::streaming_server: Now have 2 streaming clients
12:12:00 [INFO] tb_log: Streaming audio/FLAC, input sample format F32, channels=2, rate=48000, to 192.168.0.247:59894
12:12:00 [DEBUG] (15) swyh_rs::server::streaming_server: ==> Response:
12:12:00 [DEBUG] (15) swyh_rs::server::streaming_server:  ==> Content-Length: 18446744073709551615
12:12:00 [DEBUG] (15) swyh_rs::server::streaming_server:  ==> Response Header { field: HeaderField("Content-Type"), value: "audio/flac" } to 192.168.0.247:59894
12:12:00 [DEBUG] (15) swyh_rs::server::streaming_server:  ==> Response Header { field: HeaderField("TransferMode.dlna.org"), value: "Streaming" } to 192.168.0.247:59894
12:12:00 [DEBUG] (15) swyh_rs::server::streaming_server:  ==> Response Header { field: HeaderField("Server"), value: "swyh-rs tiny-http" } to 192.168.0.247:59894
12:12:00 [DEBUG] (15) swyh_rs::server::streaming_server:  ==> Response Header { field: HeaderField("Accept-Ranges"), value: "none" } to 192.168.0.247:59894
12:12:00 [DEBUG] (15) swyh_rs::server::streaming_server:  ==> Response Header { field: HeaderField("icy-name"), value: "swyh-rs" } to 192.168.0.247:59894
12:12:00 [DEBUG] (13) swyh_rs::server::streaming_server: Now have 1 streaming clients left
12:12:00 [INFO] tb_log: Streaming to 192.168.0.247:59893 has ended
12:12:00 [DEBUG] (15) swyh_rs::server::streaming_server: Now have 0 streaming clients left
12:12:00 [INFO] tb_log: Streaming to 192.168.0.247:59894 has ended
dheijl commented 5 months ago

Yes, from the screenshot you posted I see that you selected U64maxChunked.

It's configurable because WAV and RF64 need a content-length header, and some streamers flip on some values.

You should change it NoneChunked if you don't want a Content-Length header.

EDIT: I should make that default for FLAC.

My Tiny-Http server won't let me insert a Connection header, it accepts a Keep-Alive header, but I suppose that it is not relevant.

DrCWO commented 5 months ago

Not the solution yet πŸ‘Ž I still see "Content-Length: 0" which also is wrong. This header field has to be removed completely. With this the behavior of Roon also changed as it onls sends the first request and after a while it says: image

With my webserver I had to explicitly delete the Content-Length to make this happen.

12:50:42 [DEBUG] (13) swyh_rs::server::streaming_server: <== Incoming Request(GET /stream/swyh.flac from Some(192.168.0.247:61506))
12:50:42 [DEBUG] (13) swyh_rs::server::streaming_server:  <== Incoming Request Header { field: HeaderField("Host"), value: "192.168.0.247" } from 192.168.0.247:61506
12:50:42 [DEBUG] (13) swyh_rs::server::streaming_server:  <== Incoming Request Header { field: HeaderField("Connection"), value: "close" } from 192.168.0.247:61506
12:50:42 [DEBUG] (13) swyh_rs::server::streaming_server:  <== Incoming Request Header { field: HeaderField("User-Agent"), value: "Roon/200001407 (RoonServer; windows)" } from 192.168.0.247:61506
12:50:42 [INFO] tb_log: Received request /stream/swyh.flac from 192.168.0.247:61506
12:50:42 [DEBUG] (13) swyh_rs::server::streaming_server: Now have 1 streaming clients
12:50:42 [INFO] tb_log: Streaming audio/FLAC, input sample format F32, channels=2, rate=48000, to 192.168.0.247:61506
12:50:42 [DEBUG] (13) swyh_rs::server::streaming_server: ==> Response:
12:50:42 [DEBUG] (13) swyh_rs::server::streaming_server:  ==> Content-Length: 0
12:50:42 [DEBUG] (13) swyh_rs::server::streaming_server:  ==> Response Header { field: HeaderField("Content-Type"), value: "audio/flac" } to 192.168.0.247:61506
12:50:42 [DEBUG] (13) swyh_rs::server::streaming_server:  ==> Response Header { field: HeaderField("TransferMode.dlna.org"), value: "Streaming" } to 192.168.0.247:61506
12:50:42 [DEBUG] (13) swyh_rs::server::streaming_server:  ==> Response Header { field: HeaderField("Server"), value: "swyh-rs tiny-http" } to 192.168.0.247:61506
12:50:42 [DEBUG] (13) swyh_rs::server::streaming_server:  ==> Response Header { field: HeaderField("Accept-Ranges"), value: "none" } to 192.168.0.247:61506
12:50:42 [DEBUG] (13) swyh_rs::server::streaming_server:  ==> Response Header { field: HeaderField("icy-name"), value: "swyh-rs" } to 192.168.0.247:61506

EDIT: In HTTP/1.1 - server response without content-length is when the response is [chunked encoded](https://en.wikipedia.org/wiki/Chunked_transfer_encoding)

DrCWO commented 5 months ago

Did you read this? https://tiny-http.github.io/tiny-http/tiny_http/struct.Response.html

DrCWO commented 5 months ago

Here one more reference: https://gist.github.com/CMCDragonkai/6bfade6431e9ffb7fe88

I remember I also had this issue at the beginning with my server. This is what I remember.

This means: if the http server works correctly it omits Content-Length if Transfer-Encoding was set to chunked.

dheijl commented 5 months ago

Yes, and in the case of NoneChunked I do not pass in a data length to tiny-http, but an explicit None. I can not control the contect-length directly.

DrCWO commented 5 months ago

I wonder that I don't see a Transfer-Encoding: chunked in the header if I set the GUI to chunked?

DrCWO commented 5 months ago

SUCCESS πŸ‘ πŸ‘ πŸ‘ SUCCESS πŸ‘ πŸ‘ πŸ‘ SUCCESS πŸ‘ πŸ‘ πŸ‘ SUCCESS πŸ‘ πŸ‘ πŸ‘

Set the server to U32maxChunked and this stream is accepted by Roon.

dheijl commented 5 months ago

tiny-http is hiding it.

This is from a Wireshark sniffer trace:

0000   dc a6 32 39 e5 bf f4 6d 04 71 a9 6f 08 00 45 00   ..29...m.q.o..E.
0010   00 fb a8 db 40 00 80 06 00 00 c0 a8 00 87 c0 a8   ....@...........
0020   00 fe 17 0d 96 26 56 3a 00 e6 e8 d4 54 e5 50 18   .....&V:....T.P.
0030   02 00 83 c3 00 00 48 54 54 50 2f 31 2e 31 20 32   ......HTTP/1.1 2
0040   30 30 20 4f 4b 0d 0a 44 61 74 65 3a 20 4d 6f 6e   00 OK..Date: Mon
0050   2c 20 31 33 20 4d 61 79 20 32 30 32 34 20 31 33   , 13 May 2024 13
0060   3a 31 38 3a 32 34 20 47 4d 54 0d 0a 43 6f 6e 74   :18:24 GMT..Cont
0070   65 6e 74 2d 54 79 70 65 3a 20 61 75 64 69 6f 2f   ent-Type: audio/
0080   66 6c 61 63 0d 0a 54 72 61 6e 73 66 65 72 4d 6f   flac..TransferMo
0090   64 65 2e 64 6c 6e 61 2e 6f 72 67 3a 20 53 74 72   de.dlna.org: Str
00a0   65 61 6d 69 6e 67 0d 0a 53 65 72 76 65 72 3a 20   eaming..Server: 
00b0   73 77 79 68 2d 72 73 20 74 69 6e 79 2d 68 74 74   swyh-rs tiny-htt
00c0   70 0d 0a 41 63 63 65 70 74 2d 52 61 6e 67 65 73   p..Accept-Ranges
00d0   3a 20 6e 6f 6e 65 0d 0a 69 63 79 2d 6e 61 6d 65   : none..icy-name
00e0   3a 20 73 77 79 68 2d 72 73 0d 0a 54 72 61 6e 73   : swyh-rs..Trans
00f0   66 65 72 2d 45 6e 63 6f 64 69 6e 67 3a 20 63 68   fer-Encoding: ch
0100   75 6e 6b 65 64 0d 0a 0d 0a                        unked....
dheijl commented 5 months ago

Nice! Thanks for digging into this and solving it.

dheijl commented 5 months ago

I will add a note about Roon to the Readme, thanks again!