rework layout

This commit is contained in:
Jonas Rabenstein 2025-09-20 13:34:01 +02:00
commit 5fdaa22732
8 changed files with 257 additions and 198 deletions

View file

@ -1,159 +0,0 @@
{
lib,
original,
callPackage,
dotnetCorePackages,
fetchFromGitHub,
buildDotnetModule,
gnused,
jprm,
unzip,
}:
let
capitalize =
upper: str:
let
length = builtins.stringLength str;
head = builtins.substring 0 1 str;
tail = builtins.substring 1 length str;
in
"${upper head}${tail}";
jellyfin = original.overrideAttrs (
final: prev:
assert !prev ? "plugin";
{
passthru.plugin =
base: args:
let
meta = from: { inherit (from) license homepage description; };
helper = {
inherit base;
name = builtins.baseNameOf info.base;
self = info;
owner = "jellyfin";
hash = "sha256-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=";
rev = "v${info.version}";
description = "${info.name} plugin for jellyfin";
homepage = original.meta.homepage;
license = original.meta.license;
override =
assert false;
null;
overrideAttrs =
assert false;
null;
overrideDerivation =
assert false;
null;
mkPlugin = info: result: buildDotnetModule result;
inherit jellyfin;
};
defaults = {
pname = "jellyfin-plugin-${info.name}";
nugetDeps =
let
options = builtins.filter builtins.pathExists [
"${info.base}/deps.json"
];
in
assert options != [ ];
builtins.head options;
pluginLibraries = lib.attrsets.foldlAttrs (
acc: name: value:
acc ++ lib.optional (value == "directory") name
) [ ] (builtins.readDir ("${info.src}/src"));
dotnet-sdk = dotnetCorePackages.sdk_8_0;
dotnet-runtime = dotnetCorePackages.aspnetcore_8_0;
dontDotnetBuild = true;
dontDotnetInstall = true;
project = "Jellyfin.Plugin.${capitalize lib.strings.toUpper info.name}";
prePatch = ''
sed --sandbox --separate \
-e 's:\(PackageReference Include="Jellyfin\..*" Version="\)[^"]\+":\1${info.jellyfin.version}":' \
-e 's:<\(enerateDocumentationFile\|TreatWarningsAsErrors\)>true</\1>:<\1>false</\1>:' \
-i ${
lib.strings.escapeShellArgs (builtins.map (lib: "src/${lib}/${lib}.csproj") info.pluginLibraries)
}
success=true
for x in ${
lib.strings.escapeShellArgs (builtins.map (lib: "src/${lib}/${lib}.csproj") info.pluginLibraries)
}
do
diff -q $src/$x $x 2>/dev/null || continue
printf >&2 'no change: %s\n' $x
success=false
done
$success || exit 1
'';
projectFile = "src/${info.project}/${info.project}.csproj";
src = fetchFromGitHub {
owner = info.owner;
repo = "jellyfin-plugin-${info.name}";
inherit (info) rev hash;
};
nativeBuildInputs = [
gnused
jprm
unzip
];
patches =
lib.optional (builtins.pathExists "${info.base}.patch") "${info.base}.patch"
++ lib.optionals (builtins.pathExists info.base) (
lib.attrsets.foldlAttrs (
acc: name: type:
acc
++ lib.optional (type == "regular" && lib.strings.hasSuffix ".patch" name) "${info.base}/${name}"
) [ ] (builtins.readDir info.base)
);
outputs = [
"out"
"zip"
];
postInstall =
let
dlls = builtins.map (name: "${name}.dll") info.pluginLibraries;
in
''
tmp_output_dir="$(mktemp -d)"
jprm plugin build . --output="''${tmp_output_dir}" --version="${info.version}" --dotnet-configuration="''${dotnetBuildType-Release}"
mv "''${tmp_output_dir}/${info.name}_${info.version}.zip" $zip
mkdir -p $out
unzip $zip -d $out
success=true
for file in $out/*;
do
case "''${file##*/}" in
meta.json)
;;
${builtins.concatStringsSep "|" (builtins.map lib.strings.escapeShellArg dlls)}) ;;
*)
printf 'unknown file: %s\n' ''${file@Q}
success=false
;;
esac
done
for file in meta.json ${lib.strings.escapeShellArgs dlls}
do
[[ -f "$out/$file" ]] && continue
printf 'missing file: %s\n' ''${file@Q}
success=false
done
$success || exit 42
'';
meta = meta original.meta // meta info;
};
info = helper // defaults // callPackage base ({ inherit info; } // args);
result = lib.attrsets.removeAttrs info (builtins.attrNames helper);
in
info.mkPlugin info result;
}
);
in
jellyfin

View file

@ -0,0 +1,19 @@
{
original,
callPackage,
}:
let
jellyfin = original.overrideAttrs (
final: prev:
assert !prev ? "plugin";
{
passthru.plugin =
base:
callPackage ./plugin.nix {
plugin = base;
jellyfin = jellyfin;
};
}
);
in
jellyfin

View file

@ -0,0 +1,26 @@
diff --git a/MediaBrowser.Model/Dlna/StreamBuilder.cs b/MediaBrowser.Model/Dlna/StreamBuilder.cs
index 1801db70d..9fe792b26 100644
--- a/MediaBrowser.Model/Dlna/StreamBuilder.cs
+++ b/MediaBrowser.Model/Dlna/StreamBuilder.cs
@@ -100,6 +100,11 @@ namespace MediaBrowser.Model.Dlna
}
MediaStream audioStream = item.GetDefaultAudioStream(null);
+ if (audioStream is null)
+ {
+ _logger.LogError("No audio stream for {0}", item.Path ?? "<unknown>");
+ return null;
+ }
var directPlayInfo = GetAudioDirectPlayProfile(item, audioStream, options);
@@ -434,6 +439,9 @@ namespace MediaBrowser.Model.Dlna
TranscodeReason transcodeReasons = 0;
if (directPlayProfile is null)
{
+ _logger.LogDebug("Profile: {0}", options.Profile.Name ?? "<unknown>");
+ _logger.LogDebug("Path: {0}", item.Path ?? "<unknwon>");
+ _logger.LogDebug("Codec: {0}", audioStream.Codec ?? "<unknown>");
_logger.LogDebug(
"Profile: {0}, No audio direct play profiles found for {1} with codec {2}",
options.Profile.Name ?? "Unknown Profile",

153
package/jellyfin/plugin.nix Normal file
View file

@ -0,0 +1,153 @@
{
lib,
jellyfin,
plugin,
fetchFromGitHub,
buildDotnetModule,
gnused,
jprm,
unzip,
dotnetCorePackages,
callPackage,
}:
let
drv =
args:
let
meta = from: { inherit (from) license homepage description; };
capitalize =
upper: str:
let
length = builtins.stringLength str;
head = builtins.substring 0 1 str;
tail = builtins.substring 1 length str;
in
"${upper head}${tail}";
helper = {
base = plugin;
name = builtins.baseNameOf info.base;
self = info;
owner = "jellyfin";
repo = "jellyfin-plugin-${info.name}";
hash = "sha256-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=";
rev = "v${info.version}";
description = "${info.name} plugin for jellyfin";
homepage = jellyfin.meta.homepage;
license = jellyfin.meta.license;
mkPlugin = info: result: buildDotnetModule result;
inherit jellyfin;
ignore = builtins.attrNames helper ++ [
"override" "overrideAttrs" "overrideDerivation"
];
};
defaults = {
pname = "jellyfin-plugin-${info.name}";
nugetDeps =
let
options = builtins.filter builtins.pathExists [
"${info.base}/deps.json"
];
in
assert options != [ ];
builtins.head options;
pluginLibraries = lib.attrsets.foldlAttrs (
acc: name: value:
acc ++ lib.optional (value == "directory") name
) [ ] (builtins.readDir ("${info.src}/src"));
dotnet-sdk = dotnetCorePackages.sdk_8_0;
dotnet-runtime = dotnetCorePackages.aspnetcore_8_0;
dontDotnetBuild = true;
dontDotnetInstall = true;
project = "Jellyfin.Plugin.${capitalize lib.strings.toUpper info.name}";
prePatch = ''
sed --sandbox --separate \
-e 's:\(PackageReference Include="Jellyfin\..*" Version="\)[^"]\+":\1${info.jellyfin.version}":' \
-e 's:<\(enerateDocumentationFile\|TreatWarningsAsErrors\)>true</\1>:<\1>false</\1>:' \
-i ${
lib.strings.escapeShellArgs (builtins.map (lib: "src/${lib}/${lib}.csproj") info.pluginLibraries)
}
success=true
for x in ${
lib.strings.escapeShellArgs (builtins.map (lib: "src/${lib}/${lib}.csproj") info.pluginLibraries)
}
do
diff -q $src/$x $x 2>/dev/null || continue
printf >&2 'no change: %s\n' $x
success=false
done
$success || exit 1
'';
projectFile = "src/${info.project}/${info.project}.csproj";
src = fetchFromGitHub {
owner = info.owner;
repo = info.repo;
inherit (info) rev hash;
};
nativeBuildInputs = [
gnused
jprm
unzip
];
patches =
lib.optional (builtins.pathExists "${info.base}.patch") "${info.base}.patch"
++ lib.optionals (builtins.pathExists info.base) (
lib.attrsets.foldlAttrs (
acc: name: type:
acc
++ lib.optional (type == "regular" && lib.strings.hasSuffix ".patch" name) "${info.base}/${name}"
) [ ] (builtins.readDir info.base)
);
outputs = [
"out"
"zip"
];
postInstall =
let
dlls = builtins.map (name: "${name}.dll") info.pluginLibraries;
in
''
tmp_output_dir="$(mktemp -d)"
jprm plugin build . --output="''${tmp_output_dir}" --version="${info.version}" --dotnet-configuration="''${dotnetBuildType-Release}"
mv "''${tmp_output_dir}/${info.name}_${info.version}.zip" $zip
mkdir -p $out
unzip $zip -d $out
success=true
for file in $out/*;
do
case "''${file##*/}" in
meta.json)
;;
${builtins.concatStringsSep "|" (builtins.map lib.strings.escapeShellArg dlls)}) ;;
*)
printf 'unknown file: %s\n' ''${file@Q}
success=false
;;
esac
done
for file in meta.json ${lib.strings.escapeShellArgs dlls}
do
[[ -f "$out/$file" ]] && continue
printf 'missing file: %s\n' ''${file@Q}
success=false
done
$success || exit 42
'';
meta = meta jellyfin.meta // meta info;
};
info = helper // defaults // callPackage plugin ({ inherit info; } // args);
in info.mkPlugin info (lib.attrsets.removeAttrs info info.ignore);
functor = args: (drv args).overrideAttrs (final: prev: {
passthru = builtins.trace "override passthru" (prev.passthru or {}) // {
in-version = { version, rev ? null, hash ? null }@args':
callPackage functor (builtins.removeAttrs args [ "version" "rev" "hash" ] // args');
};
});
in lib.trivial.mirrorFunctionArgs plugin functor