Closed maweki closed 6 years ago
gmrender-resurrect plays to any gstreamer backend you configure (see gstreamer documentation for that). I only suggest to use alsa, because it is usually the least trouble.
@maweki Did you manage to do this? I'm trying to do the same thing as you and it's unclear to me.
I managed to use "pulsesink" and the sinkname as parameters. This worked but didn't solve my problem. I tried getting to run a while gstreamer pipeline and that decidedly didn't work, because gmrender-resurrect does something strange with the parameters so that an arbitrary pipeline is just broken.
hzeller is right, gstreamer supports a wide array of outputs, there is a big list here : https://gstreamer.freedesktop.org/documentation/plugins.html On this list, I find something promising : filesink. It looks like it should do what I want. However, I have no idea how to tell this audio sink where to right to.
A command line example with gstreamer : gst-launch-1.0 v4l2src num-buffers=1 ! jpegenc ! filesink location=capture1.jpeg
@hzeller : how can I specify a location argument when launching gmediarender? I tried gmediarender -f patate --gstout-audiosink=filesink location=/tmp/snapfifo
but it fails with gstreamer] sink: Error: No file name specified for writing.
The filesink specs are here : https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer-plugins/html/gstreamer-plugins-filesink.html
progress - somewhat : I edited line 519 of the file /src/output_gstreamer.c so that instead of passing the audio_device parameter, it passes the "location" parameter that filesink expects.
So, it went from
g_object_set (G_OBJECT(sink), "device", audio_device, NULL);
to
g_object_set (G_OBJECT(sink), "location", audio_device, NULL);
I recompiled and tested : it does indeed send the output to the specified file that I set in this command line :
./gmediarender -f banane --gstout-audiosink=filesink --gstout-audiodevice=/tmp/snapfifo
This fifo file (/tmp/snapfifo) is the input "file" of snapcast. Snapcast does indeed receive the stream, but all I get is white noise out of the snapcast clients.
Thoughts?
Yeah, so for gstreamer there shouldn't be two parameters from the client side but one, to build the correct pipeline. Not every pipeline has a "device".
all I get is white noise out of the snapcast clients.
I am also using snapcast and I've never had that problem. Is there something else going on? You can always manually test it with something like this: gst-launch-1.0 filesrc location="/root/notify.mp3" ! decodebin ! audioresample ! audioconvert ! audio/x-raw,rate=48000,channels=2,format=S16LE ! wavenc ! filesink location=/tmp/snapfifo
And as one can see here, the full pipeline might have many parameters and no "device"
Edit: that's my pipeline going out of mopidy
and my notification-script. That should be the one out of gmrender as well, but it doesn't work because auf the added device
(at least I think that's it).
I had the same problem, because I was also looking for a dlna renderer for snapcast. I digged into the details and found, that the reason for the noise is the output format. I used an audio pipeline similar to what @maweki proposed to convert. This ended up in a fork https://github.com/jaecksch/gmrender-resurrect. The output format is currently fixed to 44100:16:2 For me it works fine, please test if it works for you too. The audiosink must be named snapcast and the device parameter contains the file to write to.
--gstout-audiosink=snapcast --gstout-audiodevice=/tmp/snapfifo
I tested it with a named pipe, as well with the "process" method via stdout.
For "process" the parameter for snapcast is as follows:
... -s \"process:///usr/local/bin/gmediarender?name=upnp¶ms=-f Snapcast --gstout-audiosink=snapcast --gstout-audiodevice=/dev/stdout&sampleformat=44100:16:2&codec=flac\" ...
That fork is a little bit heavy on builtin/compiled stuff. Can't we just make the device parameter optional and have correct gstreamer pipe parsing like every other application?
Thanks for your comment. Its really heavy change for a very specific application. Based on your comment I used a more generic approach: I added a parameter gstout-audiopipe which makes pipe parsing like gst-launch. Was this your intention? This approach is more flexible for the user and not really big:
if (audio_pipe != NULL) {
GstElement *sink = NULL;
Log_info("gstreamer", "Setting audio sink-pipeline to %s\n",audio_pipe);
sink = gst_parse_bin_from_description(audio_pipe,TRUE,NULL);
if (sink==NULL) {
Log_error("gstreamer","Could not create pipeline\n")
}
else
{
g_object_set (G_OBJECT (player_), "audio-sink", sink, NULL);
}
}
The command line would like like this:
gmediarender --gstout-audiopipe 'audioresample ! audioconvert ! audio/x-raw,rate=44100,channels=2,format=S16LE ! filesink location=/tmp/upnp'
@jaecksch I'll keep the conversation here as this branch will eventually be merged with this repository, hopefully.
With your latest build piped into Snapcast on OSMC (a dedicated Kodi distro for raspberry pi), I get the wrong music pitch (I think the driver on osmc is running at 48 khz) and silent pauses every few seconds (for the buffer to fill up again?) and I get this repeated error message on the console :
ERROR [2017-01-05 20:14:15.431336 | gstreamer] Failed to get track pos
Also, if I set the sample rate at 48 khz with this command line switch :
gmediarender --gstout-audiopipe 'audioresample ! audioconvert ! audio/x-raw,rate=48000,channels=2,format=S16LE ! filesink location=/tmp/snapfifo'
I get this repeated error message :
(gmediarender:13701): GStreamer-CRITICAL **: gst_segment_to_stream_time: assertion 'segment->format == format' failed
Is there any way to make this work on a system running the sound card at 48khz?
Never mind, the 48000 setting works as it should.
I only have the ERROR [2017-01-05 20:14:15.431336 | gstreamer] Failed to get track pos
error, I probably made a typo before.
Never mind again, the Failed to get track pos
error is only present with AirAudio (android app), not with DSub (another android app), so, it's probably the fault of the app.
I added a parameter gstout-audiopipe which makes pipe parsing like gst-launch
That's the best solution, I think. I can't try it right now but if this is available, all advanced use cases should be covered
looking this issue for help with the same problem. I am new to linux and tried to set up an multi-room system with high women-acceptance-factor....
My english isnt perfect, so my question: How to solve it; Is it solvable? I tried some things from this thread, but nothing worked..just white noise as stanelie at Dec 15 says.. Open for help in german, or light english
I'm using this code, not the fork of jaecksch!
gmediarender -f "mediarenderer" --logfile=/dev/stdout --gstout-initial-volume-db=-10 --gstout-audiosink=filesink --gstout-audiodevice=/tmp/snapfifo
is not working, I get this error Error: No file name specified for writing.
so how can I specify the file name? I one comment option --gstout-audiopipe
is mentioned, but this does not exist...
any tips?
UPDATE: I replaced src/output_gstreamer.c with the version of jaecksch/gmrender-resurrect so I get the --gstout-audiopipe option, so know it's working!
Yeah. It's sad to see that specifying a generic pipe hasn't found its way into gmrender. Any advanced pipeline is impossible and you're stuck with a few possible options.
Sending a pull request that fixes the itch it is probably more fruitful than being passive aggressive about it.
Hi
Is this merged in to the main code? I need to cast it to Snapcast as well, but the filefinsk with fifo does not workas others stated here.
this is what I have gmediarender 0.0.7-git; 0.0.7-git
Now it is :) (github makes it hard to discover pending pull requests, so they sometimes go unnoticed)
@hzeller thanks!!!!!!!!!!
ok here is initial test
/usr/local/bin/gmediarender -gstout-audiosink=filesink --gstout-audiopipe=/tmp/snapfifo
gmediarender 0.0.7-git started [ gmediarender 2018-06-18_d0f46f5 (libupnp-1.6.24; glib-2.56.1; gstreamer-1.14.1) ].
Logging switched off. Enable with --logfile=<filename> (e.g. --logfile=/dev/stdout for console)
ERROR [2018-06-18 19:30:00.807502 | gstreamer] --gstout-audosink and --gstout-audiopipe are mutually exclusive.
ERROR [2018-06-18 19:30:00.807521 | main] ERROR: Failed to initialize Output subsystem
/usr/local/bin/gmediarender --gstout-audiopipe=/tmp/snapfifo
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 >)
)
ERROR [2018-06-18 19:22:43.378267 | gstreamer] source: Error: Internal data stream error. (Debug: gstbasesrc.c(3055): gst_base_src_loop (): /GstPlayBin:play/GstURIDecodeBin:uridecodebin1/GstSoupHTTPSrc:source:
streaming stopped, reason not-linked (-1))
ERROR [2018-06-18 19:22:47.136208 | upnp] upnp_set_error: Pause failed
also tried withoiut success.
gmediarender --gstout-audiopipe 'audioresample ! audioconvert ! audio/x raw,rate=44100,channels=2,format=S16LE ! filesink location=/tmp/snapfifo'
Nevermind! I was not sure about the right option and my snapclient crashed when testing the last method. The last option seems to work.
How did it work at the end and what options does the fix give?
I am using this one
gmediarender --gstout-audiopipe 'audioresample ! audioconvert ! audio/x raw,rate=44100,channels=2,format=S16LE ! filesink location=/tmp/snapfifo'
FWIW the default sample rate of snapcast is 48000 (check snapserver --help).
You can also let snapserver start gmediarender like this: snapserver -s "process:///usr/bin/gmediarender?name=DLNA¶ms=--gstout-audiopipe 'audioresample ! audioconvert ! audio/x-raw,rate=48000,channels=2,format=S16LE ! wavenc ! filesink location=/dev/stdout' --logfile /dev/null"
When using command arguments like above, it worked well for some audio, but not others. For example, some podcasts worked but others were too fast or too slow. Now instead I use the command line
--gstout-audiosink=alsasink --gstout-audiodevice=snapcast
combined with /etc/asound.conf like below
pcm.snapcast {
type rate
slave {
pcm writeSnapFifo # Direct to the plugin which will write to a file
format S16_LE
rate 48000
}
}
pcm.writeSnapFifo {
type file
slave.pcm null
file "/tmp/snapfifo"
format "raw"
}
And it seems to adjust better to differences in the source audio format
Here's the correct audio pipeline to handle different sample rates and bit depth.
gmediarender --gstout-audiopipe 'audioresample ! audio/x-raw, rate=44100, format=S16LE ! filesink location=/tmp/fifo'
As I understand it, gmrender-resurrect plays to alsa only. Is there any way (in pulseaudio, gmrender, with an environment variable, etc) to select beforehand, which pulseaudio sink (or fifo-pipe) to play into? I have a streaming server using snapcast (https://github.com/badaix/snapcast) that uses fifo-pipes on the server (one per zone).
So to use gmrender with this setup, I would either need it to play into a pulseaudio-sink (that is attached to the fifo-pipe, already got that configured), or play into a fifo-pipe directly.
Gmrender would be the missing link in my setup, having mopidy and analog sound-cards already playing into different zones, with published sinks in the network for pulseaudio streaming.