Unverified Commit fc35b306 authored by Cosima Neidahl's avatar Cosima Neidahl Committed by GitHub
Browse files

galene-stream: init at 0.2.0 (#405556)

parents e6817f33 6bfa191e
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -547,7 +547,7 @@ in
  ft2-clone = runTest ./ft2-clone.nix;
  legit = runTest ./legit.nix;
  mimir = runTest ./mimir.nix;
  galene = discoverTests (import ./galene.nix);
  galene = discoverTests (import ./galene.nix { inherit runTest; });
  gancio = runTest ./gancio.nix;
  garage_1 = import ./garage {
    inherit runTest;
+135 −11
Original line number Diff line number Diff line
{ runTest }:

let
  makeTest = import ./make-test-python.nix;
  galeneTestGroupsDir = "/var/lib/galene/groups";
  galeneTestGroupFile = "galene-test-config.json";
  galenePort = 8443;
@@ -7,7 +8,7 @@ let
  galeneTestGroupAdminPassword = "1234";
in
{
  basic = makeTest (
  basic = runTest (
    { pkgs, lib, ... }:
    {
      name = "galene-works";
@@ -56,10 +57,7 @@ in
        with subtest("galene starts"):
            # Starts?
            machine.wait_for_unit("galene")

            # Keeps running after startup?
            machine.sleep(10)
            machine.wait_for_unit("galene")
            machine.wait_for_open_port(${builtins.toString galenePort})

            # Reponds fine?
            machine.succeed("curl -s -D - -o /dev/null 'http://localhost:${builtins.toString galenePort}' >&2")
@@ -93,7 +91,7 @@ in
    }
  );

  file-transfer = makeTest (
  file-transfer = runTest (
    { pkgs, lib, ... }:
    {
      name = "galene-file-transfer-works";
@@ -143,10 +141,7 @@ in
        with subtest("galene starts"):
            # Starts?
            machine.wait_for_unit("galene")

            # Keeps running after startup?
            machine.sleep(10)
            machine.wait_for_unit("galene")
            machine.wait_for_open_port(${builtins.toString galenePort})

            # Reponds fine?
            machine.succeed("curl -s -D - -o /dev/null 'http://localhost:${builtins.toString galenePort}' >&2")
@@ -208,4 +203,133 @@ in
      '';
    }
  );

  stream = runTest (
    { pkgs, lib, ... }:
    let
      galeneTestGroupBotName = "bot";
      galeneTestGroupBotPassword = "1234";
      galeneStreamSrtPort = 9710;
      galeneStreamFeedImage = "galene-stream-feed.png";
      galeneStreamFeedLabel = "Example";
    in
    {
      name = "galene-stream-works";
      meta = {
        # inherit (pkgs.galene-stream.meta) teams;
        inherit (pkgs.galene.meta) maintainers;
        platforms = lib.platforms.linux;
      };

      nodes.machine =
        { config, pkgs, ... }:
        {
          imports = [ ./common/x11.nix ];

          services.xserver.enable = true;

          environment = {
            # https://galene.org/INSTALL.html
            etc = {
              ${galeneTestGroupFile}.source = (pkgs.formats.json { }).generate galeneTestGroupFile {
                presenter = [
                  {
                    username = galeneTestGroupBotName;
                    password = galeneTestGroupBotPassword;
                  }
                ];
                other = [ { } ];
              };

              ${galeneStreamFeedImage}.source =
                pkgs.runCommand galeneStreamFeedImage
                  {
                    nativeBuildInputs = with pkgs; [
                      (imagemagick.override { ghostscriptSupport = true; }) # Add text to image
                    ];
                  }
                  ''
                    magick -size 400x400 -background white -fill black canvas:white -pointsize 70 -annotate +100+200 '${galeneStreamFeedLabel}' $out
                  '';
            };

            systemPackages = with pkgs; [
              ffmpeg
              firefox
              galene-stream
            ];
          };

          services.galene = {
            enable = true;
            insecure = true;
            httpPort = galenePort;
            groupsDir = galeneTestGroupsDir;
          };
        };

      enableOCR = true;

      testScript = ''
        machine.wait_for_x()

        with subtest("galene starts"):
            # Starts?
            machine.wait_for_unit("galene")
            machine.wait_for_open_port(${builtins.toString galenePort})

            # Reponds fine?
            machine.succeed("curl -s -D - -o /dev/null 'http://localhost:${builtins.toString galenePort}' >&2")

        machine.succeed("cp -v /etc/${galeneTestGroupFile} ${galeneTestGroupsDir}/test.json >&2")
        machine.wait_until_succeeds("curl -s -D - -o /dev/null 'http://localhost:${builtins.toString galenePort}/group/test/' >&2")

        with subtest("galene-stream works"):
            # Start interface for stream data
            machine.succeed(
                "galene-stream "
                + "--input 'srt://localhost:${builtins.toString galeneStreamSrtPort}?mode=listener' "
                + "--insecure --output 'http://localhost:${builtins.toString galenePort}/group/test/' "
                + "--username ${galeneTestGroupBotName} --password ${galeneTestGroupBotPassword} "
                + ">&2 &"
            )
            machine.wait_for_console_text("Waiting for incoming stream...")

            # Start streaming
            machine.succeed(
                "ffmpeg "
                + "-f lavfi -i anullsrc=channel_layout=stereo:sample_rate=48000 " # need an audio track
                + "-re -loop 1 -i /etc/${galeneStreamFeedImage} " # loop of feed image
                + "-map 0:a -map 1:v " # arrange the output stream to have silent audio & looped video
                + "-c:a mp2 " # stream audio codec
                + "-c:v libx264 -pix_fmt yuv420p " # stream video codec
                + "-f mpegts " # stream format
                + "'srt://localhost:${builtins.toString galeneStreamSrtPort}' "
                + ">/dev/null 2>&1 &"
            )
            machine.wait_for_console_text("Setting remote session description")

            # Open site
            machine.succeed("firefox --new-window 'http://localhost:${builtins.toString galenePort}/group/test/' >&2 &")
            # Note: Firefox doesn't use a regular "-" in the window title, but "—" (Hex: 0xe2 0x80 0x94)
            machine.wait_for_window("Test — Mozilla Firefox")
            machine.send_key("ctrl-minus")
            machine.send_key("ctrl-minus")
            machine.send_key("alt-f10")
            machine.wait_for_text(r"(Galène|Username|Password|Connect)")
            machine.screenshot("galene-group-test-join")

            # Log in as anon
            machine.send_key("ret")
            machine.sleep(5)
            # Close "Remember credentials?" FF prompt
            machine.send_key("esc")
            machine.sleep(5)

            # Look for stream
            machine.wait_for_text("${galeneStreamFeedLabel}")
            machine.screenshot("galene-stream-group-test-streams")
      '';
    }
  );
}
+81 −0
Original line number Diff line number Diff line
{
  lib,
  python3Packages,
  fetchFromGitHub,
  gitUpdater,
  nixosTests,
  galene,
  gobject-introspection,
  gst_all_1,
  libnice,
  wrapGAppsHook3,
}:

python3Packages.buildPythonApplication rec {
  pname = "galene-stream";
  version = "0.2.0";
  pyproject = true;

  src = fetchFromGitHub {
    owner = "erdnaxe";
    repo = "galene-stream";
    tag = "${version}";
    hash = "sha256-3TdU3vBVuFle+jon2oJLa/rTLIiwYkvzscTDbMEXD1Q=";
  };

  # When insecure is enabled on both galene and galene-stream, passing the ssl_context with certificate checking disabled when trying to open a websocket connection to ws:// errors out, because no ssl_context is expected to be passed for an SSL-less websocket like that
  # When --insecure in galene-stream, don't pass ssl_context here
  # TODO: How does this interact with a galene with insecure disabled? Expecting endpoint there to be wss://. Might need more sophisticated patch.
  postPatch = ''
    substituteInPlace galene_stream/galene.py \
      --replace-fail 'await websockets.connect(status["endpoint"], ssl=ssl_context)' 'await websockets.connect(status["endpoint"], ssl=None if self.insecure else ssl_context)'
  '';

  strictDeps = true;

  nativeBuildInputs = [
    gobject-introspection
    wrapGAppsHook3
  ];

  build-system = with python3Packages; [
    setuptools
    setuptools-scm
  ];

  buildInputs =
    [
      libnice # libgstnice.so
    ]
    ++ (with gst_all_1; [
      gst-plugins-base
      gst-plugins-good
      gst-plugins-bad
      gst-plugins-ugly # libgstx264.so
    ]);

  dependencies = with python3Packages; [
    pygobject3
    websockets
  ];

  dontWrapGApps = true;

  preFixup = ''
    makeWrapperArgs+=("''${gappsWrapperArgs[@]}")
  '';

  passthru = {
    tests.vm = nixosTests.galene.stream;
    updateScript = gitUpdater { };
  };

  meta = {
    description = "Gateway to send UDP, RTMP, SRT or RIST streams to Galène videoconference server";
    homepage = "https://github.com/erdnaxe/galene-stream";
    changelog = "https://github.com/erdnaxe/galene-stream/releases/tag/${src.tag}";
    license = lib.licenses.mit;
    platforms = lib.platforms.linux;
    inherit (galene.meta) maintainers;
  };
}