Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FLAC network streaming #1419

Open
ubik3000 opened this issue Feb 16, 2022 · 9 comments
Open

FLAC network streaming #1419

ubik3000 opened this issue Feb 16, 2022 · 9 comments

Comments

@ubik3000
Copy link

Hello, would it be possible to also add FLAC network streaming as an alternative to MP3?

If OwnTone plays an mp3-encoded song, wouldn't that means that for the MP3 network streaming transcoding takes place?
As far as I have tested some time ago, transcoding does involve audible loss of quality.
So streaming in FLAC over network would mean that transcoding does not take place.

I am willing to work on the implementation if technically possible (with some mild guidance, my own investigation-> targeted questions -> answers).

Regards,
Cristian

@ejurgensen
Copy link
Member

Yes, it would be possible, and great that you offer your help. When it comes to new features that I won't be using myself, I would like to also get some assurance that you will stick around for maintenance. So I would ask you to create a fork, maintain it for 2-3 months with the new feature, and then submit a PR with the improvement.

With regard to implementation, it would mostly be about refactoring httpd_streaming.c so that it also offers a stream.flac endpoint. So I would start by studying that.

@frankusb
Copy link

frankusb commented Mar 3, 2022

WAV streaming was prototyped in #982.

@whatdoineed2do
Copy link
Contributor

@ejurgensen - I was taking a second loop at the #982. So right now, it works for streaming both flac and mp3. You added a comment #982 (review) that i was trying to understand as i see how to cleanup the old PR (i want to get alac to send lossless to Roku Soundbridge)

The current streaming does seem to be different to the other outputs - whilst they all implement the .write(struct output_buffer obuf) method, only streaming seems to be getting data a couple of pipes rather than the obuf->data[i].buffer.

Every output seems to:

  • outputs_quality_subscribe(...)
  • transcode_decode_setup_raw(XCODE_RAW, ...)
  • transcode_encode_setup(XCODE_{ALAC, OPUS} ....)
  • encoding: transcode_frame_new() and transcode_encode()

streaming does all this except outputs_quality_subscribe() - i assume that streaming output should take the obuf and not read directly off the pipes. When you say:

basic issue, which is that the change involves having the streaming output do it's own transcoding, and output modules are not supposed to do that. They should leave this to the output via the subscription function.

Is the transcode_encoode() not performing the transcode? cast.c for OPUS and airplay for ALAC.

thanks

@frankusb
Copy link

frankusb commented Mar 6, 2022

@whatdoineed2do if there is ANYTHING I can do to help to get ALAC streaming working, please let me know. This is the ideal setup for the Soundbridge.

@ejurgensen
Copy link
Member

@whatdoineed2do yes you wouldn't be able to re-use e.g. Apple Pay alac encoding with the current framework. It's been a while since I looked at this, but I think my request to have an approach similar to the outputs, i.e. subscribing to a quality and then encoding in streaming. Contrary to the outputs, you here have to deal with two threads, so I imagine a pipe is still required. Maybe multiple pipe's, since it is better to encode in the player thread than in the httpd thread.

@whatdoineed2do
Copy link
Contributor

Day job getting in the way of quicker cycles on this.

Would you be happy with a single quality the entire streaming module to subscribe? This simplifies the handling for the different formats - the outputs.write() callback will simply pass the audio data (via the per-client/format pipes) to perform the xcode to their output formats (mp3, flac, alac or whatever)?

@whatdoineed2do
Copy link
Contributor

@frankusb

I've continued some work on this in the original branch. Its working for mp3 and flac (some oddities in PTS timestamps reported by mpv need to be looekd at but audio plays) and the setup for additional transcoding endpoints is easy to extend. right now the streaming module makes a common subscription of one quality type and then transcode to the per stream quality.

However, this where i'm stuck for the ALAC endpoint. i want to push the data into a mp4 container, containing the alac data but for some reason avformat_write_header() fails with Invalid argument. If you've got any libav dev background it'd be good to know why what is missing

#0  open_output (ctx=0x7fce40031d30, src_ctx=0x7fce4002f4a0) at transcode.c:1166
#1  0x0000000000446a14 in transcode_encode_setup
    (profile=XCODE_ALAC, quality=0x4d7f80 <streaming_ctxs+8736>, src_ctx=0x7fce4002f4a0, est_size=0x0, width=0, height=0) at transcode.c:1495
#2  0x000000000044025a in streaming_request (req=0x7fce4002aec0, uri_parsed=0x7fce4002f000) at httpd_streaming.c:686
#3  0x000000000042bdab in httpd_gen_cb (req=0x7fce4002aec0, arg=<optimized out>) at httpd.c:856

@frankusb
Copy link

Is it the same issue as identified in 1182?

@whatdoineed2do
Copy link
Contributor

Unfortuantely, it appears that way. i did get the encoding to be happy with requesting an ismv container whcih can apparently take ALAC but issues on output and the soundbridges pickiness on formats its not worth persuing. I've seen many times repeated that flac is less CPU intensive/quicker to decode than alac too.

I'll tidy this up and push this back for request for comment later

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants