NixOS / nixpkgs

Nix Packages collection & NixOS
MIT License
18.09k stars 14.14k forks source link

System-wide GStreamer installation lacks access to basic plugins #187765

Open moritzschaefer opened 2 years ago

moritzschaefer commented 2 years ago

Describe the bug

Gstreamer (via gst-launch) runs fine, with the exception that the capsfilter is missing:

For example: gst-launch-1.0 alsasrc device=merged_mono ! audioconvert ! audioresample ! alsasink device=hw:1 runs just fine, while gst-launch-1.0 alsasrc device=merged_mono ! audioconvert ! audioresample ! capsfilter caps=audio/x-raw, rate=16000, channels=1, format=S16LE ! alsasink device=hw:1 says, WARNING: erroneous pipeline: no element "capsfilter"

Also gst-inspect does not list the filter

[moritz@monix:~]$ gst-inspect-1.0  | grep caps
autoconvert:  autoconvert: Select converter based on caps
autoconvert:  autovideoconvert: Select color space converter based on caps
debug:  capssetter: CapsSetter

Steps To Reproduce

Steps to reproduce the behavior:

  1. Install gstreamer via environment.systemPackages (gst_all_1.gstreamer gst_all_1.gst-plugins-base gst_all_1.gst-plugins-good gst_all_1.gst-plugins-ugly gst_all_1.gst-plugins-bad)
  2. Run gstreamer (gst-launch and gst-inspect) as indicated above

Expected behavior

The plugin should be available and functional

Additional context

Tested this on aarch64 platform (Raspberry Pi 4) and on ordinary x86_64

Notify maintainers

@ttuegel @matthewbauer

Metadata

[user@system:~]$ nix-shell -p nix-info --run "nix-info -m"
 - system: `"aarch64-linux"`
 - host os: `Linux 5.15.32, NixOS, 22.05 (Quokka), 22.05pre372961.e10da1c7f54`
 - multi-user?: `yes`
 - sandbox: `yes`
 - version: `nix-env (Nix) 2.8.0`
 - channels(moritz): `""`
 - channels(root): `"nixos, nixos-hardware, nixos-unstable"`
 - nixpkgs: `/nix/var/nix/profiles/per-user/root/channels/nixos`
moritzschaefer commented 2 years ago

I have some more details on the case now. When installing gstreamer via configuration.nix, it somehow lacks an important plugin file:

gst-launch-1.0 (it's a wrapper script in nixos) successfully 'loads' most plugins automatically by adding '/run/current-system/sw/lib/gstreamer-1.0' to the GST_PLUGIN_SYSTEM_PATH_1_0 environment variable.

However /run/current-system/sw/lib/gstreamer-1.0 lacks two important plugin files: libgstcoreelements.so and libgstcoretracers.so

When I install gstreamer (in addition to the system-installed gstreamer+plugins) with nix-shell -p, the environment variable GST_PLUGIN_SYSTEM_PATH_1_0 is preset in the normal bash environment and includes the path to the otherwise missing plugins.

I have no clue why these two files are not in /run/current-system/sw/lib/gstreamer-1.0 where all the other plugin files reside in. Another way to fix the issue, would be ot propagate the variable GST_PLUGIN_SYSTEM_PATH_1_0 in the user environment (again, I have no clue, why this variable is set correctly in the nix-shell environment, but not in my normal system).

Please, let me know if you have any suggestions on how to best workaround this issue.

To 'illustrate' the issue more concretely, I add a CLI session below that shows the issue pretty clearly:


[I] moritz@mopad ~> GST_DEBUG=2 gst-launch-1.0 autoaudiosrc !     audioconvert !   audioresample  !  audio/x-raw, rate=16000, channels=1, format=S16LE !         udpsink host=127.0.0.1 port=11111
0:00:00.004420933 905045      0x16540f0 WARN     GST_ELEMENT_FACTORY gstelementfactory.c:701:gst_element_factory_make_with_properties: no such element factory "capsfilter"!
0:00:00.004429972 905045      0x16540f0 ERROR                default gstutils.c:2161:gst_element_link_pads_filtered: Could not make a capsfilter
0:00:00.004441782 905045      0x16540f0 ERROR           GST_PIPELINE gst/parse/grammar.y:767:gst_parse_perform_link: could not link audioresample0 to udpsink0 with caps audio/x-raw, rate=(int)16000, channels=(int)1, format=(string)S16LE
WARNING: erroneous pipeline: could not link audioresample0 to udpsink0 with caps audio/x-raw, rate=(int)16000, channels=(int)1, format=(string)S16LE
[I] moritz@mopad ~ [1]> nix-shell -p gst_all_1.gstreamer

[nix-shell:~]$ echo $GST_PLUGIN_SYSTEM_PATH_1_0
/nix/store/frafzrcldrfsxkawjbxdm7hrpszx7qp9-gstreamer-1.20.1/lib/gstreamer-1.0:/nix/store/frafzrcldrfsxkawjbxdm7hrpszx7qp9-gstreamer-1.20.1/lib/gstreamer-1.0

[nix-shell:~]$ ls /nix/store/frafzrcldrfsxkawjbxdm7hrpszx7qp9-gstreamer-1.20.1/lib/gstreamer-1.0
libgstcoreelements.so  libgstcoretracers.so

[nix-shell:~]$ GST_DEBUG=2 gst-launch-1.0 autoaudiosrc !     audioconvert !   audioresample  !  audio/x-raw, rate=16000, channels=1, format=S16LE !         udpsink host=127.0.0.1 port=11111
Setting pipeline to PAUSED ...
Pipeline is live and does not need PREROLL ...
Pipeline is PREROLLED ...
Setting pipeline to PLAYING ...
New clock: GstPulseSrcClock
Redistribute latency...
0:00:00.030307234 906508      0x1de2120 WARN         audio-resampler audio-resampler.c:274:convert_taps_gint16_c: can't find exact taps
Redistribute latency...
^Chandling interrupt.
Interrupt: Stopping pipeline ...
Execution ended after 0:00:02.555674144
Setting pipeline to NULL ...
0:00:02.584285230 906508      0x1de2580 WARN                audiosrc gstaudiosrc.c:227:audioringbuffer_thread_func:<autoaudiosrc0-actual-src-puls> error reading data -1 (reason: Success), skipping segment
Freeing pipeline ...
jmcdo29 commented 1 year ago

Somehow I had this working at one point, but it seems that installing obs-studio over the weekend caused something to clear out a variable, I guess. Any insights on moving forward would be great, right now get-launch-1.0 can't find the tee element

GST_DEBUG=2 gst-launch-1.0 audiotestsrc ! audioconvert ! audioresample ! tee name=t t. ! queue ! pulsesink server=127.0.0.1 t. ! queue ! audio/x-raw,rate=44100,channels=2,format=S16LE ! udpsink host=localhost port=5555 -v 
0:00:00.012183268 66221       0xc91160 WARN     GST_ELEMENT_FACTORY gstelementfactory.c:701:gst_element_factory_make_with_properties: no such element factory "tee"!
0:00:00.012199637 66221       0xc91160 ERROR           GST_PIPELINE gst/parse/grammar.y:851:priv_gst_parse_yyparse: no element "tee"
0:00:00.012208418 66221       0xc91160 ERROR           GST_PIPELINE gst/parse/grammar.y:939:priv_gst_parse_yyparse: link has no sink [source=@0xe71510]
0:00:00.012214441 66221       0xc91160 WARN     GST_ELEMENT_FACTORY gstelementfactory.c:701:gst_element_factory_make_with_properties: no such element factory "queue"!
0:00:00.012218766 66221       0xc91160 ERROR           GST_PIPELINE gst/parse/grammar.y:851:priv_gst_parse_yyparse: no element "queue"
0:00:00.012223739 66221       0xc91160 ERROR           GST_PIPELINE gst/parse/grammar.y:939:priv_gst_parse_yyparse: link has no sink [source=t@(nil)]
0:00:00.014877098 66221       0xc91160 ERROR           GST_PIPELINE gst/parse/grammar.y:939:priv_gst_parse_yyparse: link has no source [sink=@0xe7e450]
0:00:00.014892880 66221       0xc91160 WARN     GST_ELEMENT_FACTORY gstelementfactory.c:701:gst_element_factory_make_with_properties: no such element factory "queue"!
0:00:00.014901386 66221       0xc91160 ERROR           GST_PIPELINE gst/parse/grammar.y:851:priv_gst_parse_yyparse: no element "queue"
0:00:00.014914855 66221       0xc91160 ERROR           GST_PIPELINE gst/parse/grammar.y:939:priv_gst_parse_yyparse: link has no sink [source=t@(nil)]
0:00:00.016256677 66221       0xc91160 ERROR           GST_PIPELINE gst/parse/grammar.y:939:priv_gst_parse_yyparse: link has no source [sink=@0xe86290]
WARNING: erroneous pipeline: no element "tee"
gst-launch-1.0 --version                                              
gst-launch-1.0 version 1.20.3
GStreamer 1.20.3
Unknown package origin
{ pkgs, ... }:

{
    services.mopidy = let mopidyConfig = {
    serverHost = "127.0.0.1";
    ytAuthFile = "/etc/mopidy/auth.json";
    mpdPort = 6600;
    visualisationHost = "localhost";
    visualisationPort = 5555;
    withVisualisation = true;
  }; in with mopidyConfig; {
    enable = true;
    configuration = ''
      [core]
      restore_state=true
      [audio]
      output = ${if withVisualisation then
        "tee name=t ! queue ! pulsesink server=${serverHost} t. ! queue ! audio/x-raw,rate=44100,channels=2,format=S16LE ! udpsink host=${visualisationHost} port=${toString visualisationPort}"
      else 
        "autoaudiosink"
      }
      [ytmusic]
      enabled = true
      auth_json = ${ytAuthFile}
      [mpd]
      enabled = true
      hostname = ${serverHost}
      port = ${toString mpdPort}
    '';
    extensionPackages = with pkgs; [
      mopidy-ytmusic
      mopidy-mpd
      mopidy-iris
      mopidy-mpris
    ];
    };
    hardware.pulseaudio = {
    enable = true;
    tcp = {
      anonymousClients.allowedIpRanges = ["127.0.0.1"];
      enable = true;       
    };
    };
    nixpkgs.config.pulseaudio = true;
    environment.systemPackages = with pkgs; [
    pulseaudio
    gst_all_1.gstreamer
    gst_all_1.gst-plugins-base
    gst_all_1.gst-plugins-good
    gst_all_1.gst-plugins-ugly
    gst_all_1.gst-plugins-bad
    gst_all_1.gst-libav
    mopidy
    mopidy-iris
    mopidy-ytmusic
    mopidy-mpd
    mopidy-mpris
    (ncmpcpp.override {
      visualizerSupport = true;
      clockSupport = true;
    })
  ];
}
jmcdo29 commented 1 year ago

For now, as a temporary fix, I've added a location of libgstcoreelemets.so and libgstcoretracers.so found via fd libgstcoreelements.st /nix/store | grep gstreamer-1.20.3 to the GST_PLUGIN_SYSTEM_PATH_1_0 env variable in my shell configuration (.zshrc in my case) and it's now working as expected. Feels very hacky, but it's doing the trick for anyone else who comes across this.

jtojnar commented 1 year ago

Another way to fix the issue, would be ot propagate the variable GST_PLUGIN_SYSTEM_PATH_1_0 in the user environment (again, I have no clue, why this variable is set correctly in the nix-shell environment, but not in my normal system).

Installing libraries system-wide is not supported: https://nixos.wiki/wiki/FAQ#I_installed_a_library_but_my_compiler_is_not_finding_it._Why.3F

While GStreamer has stable ABI, the plug-ins may depend on various libraries and if those are not compatible with a program loading the plug-in, it may cause issues.

I am not even sure why does gst-inspect-1.0 see plug-ins in NIX_PROFILES. Those should not be picked up by apps so there is no reason to have them picked up by the tool either.

However /run/current-system/sw/lib/gstreamer-1.0 lacks two important plugin files: libgstcoreelements.so and libgstcoretracers.so

gst_all_1.gstreamer has a bin output so unless you explicitly use gst_all_1.gstreamer.out in environment.systemPackages, the bin output is what will end up in the environment.

But seriously, I would recommend using nix-shell for testing and wrapping whatever programs you use so that they are always in sync with the libraries used by GStreamer.