Merge pull request #159865 from midchildan/update/epgstation
epgstation: 1.7.5 -> 2.6.20
This commit is contained in:
commit
3222d8665d
|
@ -826,6 +826,58 @@
|
||||||
include serif fonts.
|
include serif fonts.
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
<literal>pkgs.epgstation</literal> has been upgraded from v1
|
||||||
|
to v2, resulting in incompatible changes in the database
|
||||||
|
scheme and configuration format.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
Some top-level settings under
|
||||||
|
<link linkend="opt-services.epgstation.enable">services.epgstation</link>
|
||||||
|
is now deprecated because it was redudant due to the same
|
||||||
|
options being present in
|
||||||
|
<link linkend="opt-services.epgstation.settings">services.epgstation.settings</link>.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
The option <literal>services.epgstation.basicAuth</literal>
|
||||||
|
was removed because basic authentication support was dropped
|
||||||
|
by upstream.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
The option
|
||||||
|
<link linkend="opt-services.epgstation.database.passwordFile">services.epgstation.database.passwordFile</link>
|
||||||
|
no longer has a default value. Make sure to set this option
|
||||||
|
explicitly before upgrading. Change the database password if
|
||||||
|
necessary.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
The
|
||||||
|
<link linkend="opt-services.epgstation.settings">services.epgstation.settings</link>
|
||||||
|
option now expects options for <literal>config.yml</literal>
|
||||||
|
in EPGStation v2.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
Existing data for the
|
||||||
|
<link linkend="opt-services.epgstation.enable">services.epgstation</link>
|
||||||
|
module would have to be backed up prior to the upgrade. To
|
||||||
|
back up exising data to
|
||||||
|
<literal>/tmp/epgstation.bak</literal>, run
|
||||||
|
<literal>sudo -u epgstation epgstation run backup /tmp/epgstation.bak</literal>.
|
||||||
|
To import that data after to the upgrade, run
|
||||||
|
<literal>sudo -u epgstation epgstation run v1migrate /tmp/epgstation.bak</literal>
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para>
|
||||||
<literal>switch-to-configuration</literal> (the script that is
|
<literal>switch-to-configuration</literal> (the script that is
|
||||||
|
|
|
@ -321,6 +321,30 @@ In addition to numerous new and upgraded packages, this release has the followin
|
||||||
`pkgs.noto-fonts-cjk` is currently an alias of `pkgs.noto-fonts-cjk-sans` and
|
`pkgs.noto-fonts-cjk` is currently an alias of `pkgs.noto-fonts-cjk-sans` and
|
||||||
doesn't include serif fonts.
|
doesn't include serif fonts.
|
||||||
|
|
||||||
|
- `pkgs.epgstation` has been upgraded from v1 to v2, resulting in incompatible
|
||||||
|
changes in the database scheme and configuration format.
|
||||||
|
|
||||||
|
- Some top-level settings under [services.epgstation](#opt-services.epgstation.enable)
|
||||||
|
is now deprecated because it was redudant due to the same options being
|
||||||
|
present in [services.epgstation.settings](#opt-services.epgstation.settings).
|
||||||
|
|
||||||
|
- The option `services.epgstation.basicAuth` was removed because basic
|
||||||
|
authentication support was dropped by upstream.
|
||||||
|
|
||||||
|
- The option [services.epgstation.database.passwordFile](#opt-services.epgstation.database.passwordFile)
|
||||||
|
no longer has a default value. Make sure to set this option explicitly before
|
||||||
|
upgrading. Change the database password if necessary.
|
||||||
|
|
||||||
|
- The [services.epgstation.settings](#opt-services.epgstation.settings)
|
||||||
|
option now expects options for `config.yml` in EPGStation v2.
|
||||||
|
|
||||||
|
- Existing data for the [services.epgstation](#opt-services.epgstation.enable)
|
||||||
|
module would have to be backed up prior to the upgrade. To back up exising
|
||||||
|
data to `/tmp/epgstation.bak`, run
|
||||||
|
`sudo -u epgstation epgstation run backup /tmp/epgstation.bak`.
|
||||||
|
To import that data after to the upgrade, run
|
||||||
|
`sudo -u epgstation epgstation run v1migrate /tmp/epgstation.bak`
|
||||||
|
|
||||||
- `switch-to-configuration` (the script that is run when running `nixos-rebuild switch` for example) has been reworked
|
- `switch-to-configuration` (the script that is run when running `nixos-rebuild switch` for example) has been reworked
|
||||||
* The interface that allows activation scripts to restart units has been streamlined. Restarting and reloading is now done by a single file `/run/nixos/activation-restart-list` that honors `restartIfChanged` and `reloadIfChanged` of the units.
|
* The interface that allows activation scripts to restart units has been streamlined. Restarting and reloading is now done by a single file `/run/nixos/activation-restart-list` that honors `restartIfChanged` and `reloadIfChanged` of the units.
|
||||||
* Preferring to reload instead of restarting can still be achieved using `/run/nixos/activation-reload-list`.
|
* Preferring to reload instead of restarting can still be achieved using `/run/nixos/activation-reload-list`.
|
||||||
|
|
|
@ -1,30 +1,40 @@
|
||||||
{ config, lib, options, pkgs, ... }:
|
{ config, lib, options, pkgs, ... }:
|
||||||
|
|
||||||
with lib;
|
|
||||||
|
|
||||||
let
|
let
|
||||||
cfg = config.services.epgstation;
|
cfg = config.services.epgstation;
|
||||||
opt = options.services.epgstation;
|
opt = options.services.epgstation;
|
||||||
|
|
||||||
|
description = "EPGStation: DVR system for Mirakurun-managed TV tuners";
|
||||||
|
|
||||||
username = config.users.users.epgstation.name;
|
username = config.users.users.epgstation.name;
|
||||||
groupname = config.users.users.epgstation.group;
|
groupname = config.users.users.epgstation.group;
|
||||||
|
mirakurun = {
|
||||||
|
sock = config.services.mirakurun.unixSocket;
|
||||||
|
option = options.services.mirakurun.unixSocket;
|
||||||
|
};
|
||||||
|
|
||||||
settingsFmt = pkgs.formats.json {};
|
yaml = pkgs.formats.yaml { };
|
||||||
settingsTemplate = settingsFmt.generate "config.json" cfg.settings;
|
settingsTemplate = yaml.generate "config.yml" cfg.settings;
|
||||||
preStartScript = pkgs.writeScript "epgstation-prestart" ''
|
preStartScript = pkgs.writeScript "epgstation-prestart" ''
|
||||||
#!${pkgs.runtimeShell}
|
#!${pkgs.runtimeShell}
|
||||||
|
|
||||||
PASSWORD="$(head -n1 "${cfg.basicAuth.passwordFile}")"
|
DB_PASSWORD_FILE=${lib.escapeShellArg cfg.database.passwordFile}
|
||||||
DB_PASSWORD="$(head -n1 "${cfg.database.passwordFile}")"
|
|
||||||
|
if [[ ! -f "$DB_PASSWORD_FILE" ]]; then
|
||||||
|
printf "[FATAL] File containing the DB password was not found in '%s'. Double check the NixOS option '%s'." \
|
||||||
|
"$DB_PASSWORD_FILE" ${lib.escapeShellArg opt.database.passwordFile} >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
DB_PASSWORD="$(head -n1 ${lib.escapeShellArg cfg.database.passwordFile})"
|
||||||
|
|
||||||
# setup configuration
|
# setup configuration
|
||||||
touch /etc/epgstation/config.json
|
touch /etc/epgstation/config.yml
|
||||||
chmod 640 /etc/epgstation/config.json
|
chmod 640 /etc/epgstation/config.yml
|
||||||
sed \
|
sed \
|
||||||
-e "s,@password@,$PASSWORD,g" \
|
|
||||||
-e "s,@dbPassword@,$DB_PASSWORD,g" \
|
-e "s,@dbPassword@,$DB_PASSWORD,g" \
|
||||||
${settingsTemplate} > /etc/epgstation/config.json
|
${settingsTemplate} > /etc/epgstation/config.yml
|
||||||
chown "${username}:${groupname}" /etc/epgstation/config.json
|
chown "${username}:${groupname}" /etc/epgstation/config.yml
|
||||||
|
|
||||||
# NOTE: Use password authentication, since mysqljs does not yet support auth_socket
|
# NOTE: Use password authentication, since mysqljs does not yet support auth_socket
|
||||||
if [ ! -e /var/lib/epgstation/db-created ]; then
|
if [ ! -e /var/lib/epgstation/db-created ]; then
|
||||||
|
@ -35,7 +45,7 @@ let
|
||||||
'';
|
'';
|
||||||
|
|
||||||
streamingConfig = lib.importJSON ./streaming.json;
|
streamingConfig = lib.importJSON ./streaming.json;
|
||||||
logConfig = {
|
logConfig = yaml.generate "logConfig.yml" {
|
||||||
appenders.stdout.type = "stdout";
|
appenders.stdout.type = "stdout";
|
||||||
categories = {
|
categories = {
|
||||||
default = { appenders = [ "stdout" ]; level = "info"; };
|
default = { appenders = [ "stdout" ]; level = "info"; };
|
||||||
|
@ -45,53 +55,51 @@ let
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
defaultPassword = "INSECURE_GO_CHECK_CONFIGURATION_NIX\n";
|
# Deprecate top level options that are redundant.
|
||||||
|
deprecateTopLevelOption = config:
|
||||||
|
lib.mkRenamedOptionModule
|
||||||
|
([ "services" "epgstation" ] ++ config)
|
||||||
|
([ "services" "epgstation" "settings" ] ++ config);
|
||||||
|
|
||||||
|
removeOption = config: instruction:
|
||||||
|
lib.mkRemovedOptionModule
|
||||||
|
([ "services" "epgstation" ] ++ config)
|
||||||
|
instruction;
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
options.services.epgstation = {
|
meta.maintainers = with lib.maintainers; [ midchildan ];
|
||||||
enable = mkEnableOption "EPGStation: DTV Software in Japan";
|
|
||||||
|
|
||||||
usePreconfiguredStreaming = mkOption {
|
imports = [
|
||||||
type = types.bool;
|
(deprecateTopLevelOption [ "port" ])
|
||||||
|
(deprecateTopLevelOption [ "socketioPort" ])
|
||||||
|
(deprecateTopLevelOption [ "clientSocketioPort" ])
|
||||||
|
(removeOption [ "basicAuth" ]
|
||||||
|
"Use a TLS-terminated reverse proxy with authentication instead.")
|
||||||
|
];
|
||||||
|
|
||||||
|
options.services.epgstation = {
|
||||||
|
enable = lib.mkEnableOption description;
|
||||||
|
|
||||||
|
package = lib.mkOption {
|
||||||
|
default = pkgs.epgstation;
|
||||||
|
type = lib.types.package;
|
||||||
|
defaultText = lib.literalExpression "pkgs.epgstation";
|
||||||
|
description = "epgstation package to use";
|
||||||
|
};
|
||||||
|
|
||||||
|
usePreconfiguredStreaming = lib.mkOption {
|
||||||
|
type = lib.types.bool;
|
||||||
default = true;
|
default = true;
|
||||||
description = ''
|
description = ''
|
||||||
Use preconfigured default streaming options.
|
Use preconfigured default streaming options.
|
||||||
|
|
||||||
Upstream defaults:
|
Upstream defaults:
|
||||||
<link xlink:href="https://github.com/l3tnun/EPGStation/blob/master/config/config.sample.json"/>
|
<link xlink:href="https://github.com/l3tnun/EPGStation/blob/master/config/config.yml.template"/>
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
port = mkOption {
|
openFirewall = lib.mkOption {
|
||||||
type = types.port;
|
type = lib.types.bool;
|
||||||
default = 20772;
|
|
||||||
description = ''
|
|
||||||
HTTP port for EPGStation to listen on.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
socketioPort = mkOption {
|
|
||||||
type = types.port;
|
|
||||||
default = cfg.port + 1;
|
|
||||||
defaultText = literalExpression "config.${opt.port} + 1";
|
|
||||||
description = ''
|
|
||||||
Socket.io port for EPGStation to listen on.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
clientSocketioPort = mkOption {
|
|
||||||
type = types.port;
|
|
||||||
default = cfg.socketioPort;
|
|
||||||
defaultText = literalExpression "config.${opt.socketioPort}";
|
|
||||||
description = ''
|
|
||||||
Socket.io port that the web client is going to connect to. This may be
|
|
||||||
different from <option>socketioPort</option> if EPGStation is hidden
|
|
||||||
behind a reverse proxy.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
openFirewall = mkOption {
|
|
||||||
type = types.bool;
|
|
||||||
default = false;
|
default = false;
|
||||||
description = ''
|
description = ''
|
||||||
Open ports in the firewall for the EPGStation web interface.
|
Open ports in the firewall for the EPGStation web interface.
|
||||||
|
@ -106,50 +114,17 @@ in
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
basicAuth = {
|
database = {
|
||||||
user = mkOption {
|
name = lib.mkOption {
|
||||||
type = with types; nullOr str;
|
type = lib.types.str;
|
||||||
default = null;
|
|
||||||
example = "epgstation";
|
|
||||||
description = ''
|
|
||||||
Basic auth username for EPGStation. If <literal>null</literal>, basic
|
|
||||||
auth will be disabled.
|
|
||||||
|
|
||||||
<warning>
|
|
||||||
<para>
|
|
||||||
Basic authentication has known weaknesses, the most critical being
|
|
||||||
that it sends passwords over the network in clear text. Use this
|
|
||||||
feature to control access to EPGStation within your family and
|
|
||||||
friends, but don't rely on it for security.
|
|
||||||
</para>
|
|
||||||
</warning>
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
passwordFile = mkOption {
|
|
||||||
type = types.path;
|
|
||||||
default = pkgs.writeText "epgstation-password" defaultPassword;
|
|
||||||
defaultText = literalDocBook ''a file containing <literal>${defaultPassword}</literal>'';
|
|
||||||
example = "/run/keys/epgstation-password";
|
|
||||||
description = ''
|
|
||||||
A file containing the password for <option>basicAuth.user</option>.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
database = {
|
|
||||||
name = mkOption {
|
|
||||||
type = types.str;
|
|
||||||
default = "epgstation";
|
default = "epgstation";
|
||||||
description = ''
|
description = ''
|
||||||
Name of the MySQL database that holds EPGStation's data.
|
Name of the MySQL database that holds EPGStation's data.
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
passwordFile = mkOption {
|
passwordFile = lib.mkOption {
|
||||||
type = types.path;
|
type = lib.types.path;
|
||||||
default = pkgs.writeText "epgstation-db-password" defaultPassword;
|
|
||||||
defaultText = literalDocBook ''a file containing <literal>${defaultPassword}</literal>'';
|
|
||||||
example = "/run/keys/epgstation-db-password";
|
example = "/run/keys/epgstation-db-password";
|
||||||
description = ''
|
description = ''
|
||||||
A file containing the password for the database named
|
A file containing the password for the database named
|
||||||
|
@ -158,69 +133,106 @@ in
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
settings = mkOption {
|
# The defaults for some options come from the upstream template
|
||||||
|
# configuration, which is the one that users would get if they follow the
|
||||||
|
# upstream instructions. This is, in some cases, different from the
|
||||||
|
# application defaults. Some options like encodeProcessNum and
|
||||||
|
# concurrentEncodeNum doesn't have an optimal default value that works for
|
||||||
|
# all hardware setups and/or performance requirements. For those kind of
|
||||||
|
# options, the application default wouldn't always result in the expected
|
||||||
|
# out-of-the-box behavior because it's the responsibility of the user to
|
||||||
|
# configure them according to their needs. In these cases, the value in the
|
||||||
|
# upstream template configuration should serve as a "good enough" default.
|
||||||
|
settings = lib.mkOption {
|
||||||
description = ''
|
description = ''
|
||||||
Options to add to config.json.
|
Options to add to config.yml.
|
||||||
|
|
||||||
Documentation:
|
Documentation:
|
||||||
<link xlink:href="https://github.com/l3tnun/EPGStation/blob/master/doc/conf-manual.md"/>
|
<link xlink:href="https://github.com/l3tnun/EPGStation/blob/master/doc/conf-manual.md"/>
|
||||||
'';
|
'';
|
||||||
|
|
||||||
default = {};
|
default = { };
|
||||||
example = {
|
example = {
|
||||||
recPriority = 20;
|
recPriority = 20;
|
||||||
conflictPriority = 10;
|
conflictPriority = 10;
|
||||||
};
|
};
|
||||||
|
|
||||||
type = types.submodule {
|
type = lib.types.submodule {
|
||||||
freeformType = settingsFmt.type;
|
freeformType = yaml.type;
|
||||||
|
|
||||||
options.readOnlyOnce = mkOption {
|
options.port = lib.mkOption {
|
||||||
type = types.bool;
|
type = lib.types.port;
|
||||||
default = false;
|
default = 20772;
|
||||||
description = "Don't reload configuration files at runtime.";
|
description = ''
|
||||||
|
HTTP port for EPGStation to listen on.
|
||||||
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
options.mirakurunPath = mkOption (let
|
options.socketioPort = lib.mkOption {
|
||||||
sockPath = config.services.mirakurun.unixSocket;
|
type = lib.types.port;
|
||||||
in {
|
default = cfg.settings.port + 1;
|
||||||
type = types.str;
|
defaultText = lib.literalExpression "config.${opt.settings}.port + 1";
|
||||||
default = "http+unix://${replaceStrings ["/"] ["%2F"] sockPath}";
|
description = ''
|
||||||
defaultText = literalExpression ''
|
Socket.io port for EPGStation to listen on. It is valid to share
|
||||||
"http+unix://''${replaceStrings ["/"] ["%2F"] config.${options.services.mirakurun.unixSocket}}"
|
ports with <option>${opt.settings}.port</option>.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
options.clientSocketioPort = lib.mkOption {
|
||||||
|
type = lib.types.port;
|
||||||
|
default = cfg.settings.socketioPort;
|
||||||
|
defaultText = lib.literalExpression "config.${opt.settings}.socketioPort";
|
||||||
|
description = ''
|
||||||
|
Socket.io port that the web client is going to connect to. This may
|
||||||
|
be different from <option>${opt.settings}.socketioPort</option> if
|
||||||
|
EPGStation is hidden behind a reverse proxy.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
options.mirakurunPath = with mirakurun; lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
default = "http+unix://${lib.replaceStrings ["/"] ["%2F"] sock}";
|
||||||
|
defaultText = lib.literalExpression ''
|
||||||
|
"http+unix://''${lib.replaceStrings ["/"] ["%2F"] config.${option}}"
|
||||||
'';
|
'';
|
||||||
example = "http://localhost:40772";
|
example = "http://localhost:40772";
|
||||||
description = "URL to connect to Mirakurun.";
|
description = "URL to connect to Mirakurun.";
|
||||||
});
|
};
|
||||||
|
|
||||||
options.encode = mkOption {
|
options.encodeProcessNum = lib.mkOption {
|
||||||
type = with types; listOf attrs;
|
type = lib.types.ints.positive;
|
||||||
|
default = 4;
|
||||||
|
description = ''
|
||||||
|
The maximum number of processes that EPGStation would allow to run
|
||||||
|
at the same time for encoding or streaming videos.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
options.concurrentEncodeNum = lib.mkOption {
|
||||||
|
type = lib.types.ints.positive;
|
||||||
|
default = 1;
|
||||||
|
description = ''
|
||||||
|
The maximum number of encoding jobs that EPGStation would run at the
|
||||||
|
same time.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
options.encode = lib.mkOption {
|
||||||
|
type = with lib.types; listOf attrs;
|
||||||
description = "Encoding presets for recorded videos.";
|
description = "Encoding presets for recorded videos.";
|
||||||
default = [
|
default = [
|
||||||
{
|
{
|
||||||
name = "H264";
|
name = "H.264";
|
||||||
cmd = "${pkgs.epgstation}/libexec/enc.sh main";
|
cmd = "%NODE% ${cfg.package}/libexec/enc.js";
|
||||||
suffix = ".mp4";
|
suffix = ".mp4";
|
||||||
default = true;
|
|
||||||
}
|
|
||||||
{
|
|
||||||
name = "H264-sub";
|
|
||||||
cmd = "${pkgs.epgstation}/libexec/enc.sh sub";
|
|
||||||
suffix = "-sub.mp4";
|
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
defaultText = literalExpression ''
|
defaultText = lib.literalExpression ''
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
name = "H264";
|
name = "H.264";
|
||||||
cmd = "''${pkgs.epgstation}/libexec/enc.sh main";
|
cmd = "%NODE% config.${opt.package}/libexec/enc.js";
|
||||||
suffix = ".mp4";
|
suffix = ".mp4";
|
||||||
default = true;
|
|
||||||
}
|
|
||||||
{
|
|
||||||
name = "H264-sub";
|
|
||||||
cmd = "''${pkgs.epgstation}/libexec/enc.sh sub";
|
|
||||||
suffix = "-sub.mp4";
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
'';
|
'';
|
||||||
|
@ -229,14 +241,25 @@ in
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
config = mkIf cfg.enable {
|
config = lib.mkIf cfg.enable {
|
||||||
|
assertions = [
|
||||||
|
{
|
||||||
|
assertion = !(lib.hasAttr "readOnlyOnce" cfg.settings);
|
||||||
|
message = ''
|
||||||
|
The option config.${opt.settings}.readOnlyOnce can no longer be used
|
||||||
|
since it's been removed. No replacements are available.
|
||||||
|
'';
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
environment.etc = {
|
environment.etc = {
|
||||||
"epgstation/operatorLogConfig.json".text = builtins.toJSON logConfig;
|
"epgstation/epgUpdaterLogConfig.yml".source = logConfig;
|
||||||
"epgstation/serviceLogConfig.json".text = builtins.toJSON logConfig;
|
"epgstation/operatorLogConfig.yml".source = logConfig;
|
||||||
|
"epgstation/serviceLogConfig.yml".source = logConfig;
|
||||||
};
|
};
|
||||||
|
|
||||||
networking.firewall = mkIf cfg.openFirewall {
|
networking.firewall = lib.mkIf cfg.openFirewall {
|
||||||
allowedTCPPorts = with cfg; [ port socketioPort ];
|
allowedTCPPorts = with cfg.settings; [ port socketioPort ];
|
||||||
};
|
};
|
||||||
|
|
||||||
users.users.epgstation = {
|
users.users.epgstation = {
|
||||||
|
@ -245,13 +268,13 @@ in
|
||||||
isSystemUser = true;
|
isSystemUser = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
users.groups.epgstation = {};
|
users.groups.epgstation = { };
|
||||||
|
|
||||||
services.mirakurun.enable = mkDefault true;
|
services.mirakurun.enable = lib.mkDefault true;
|
||||||
|
|
||||||
services.mysql = {
|
services.mysql = {
|
||||||
enable = mkDefault true;
|
enable = lib.mkDefault true;
|
||||||
package = mkDefault pkgs.mariadb;
|
package = lib.mkDefault pkgs.mariadb;
|
||||||
ensureDatabases = [ cfg.database.name ];
|
ensureDatabases = [ cfg.database.name ];
|
||||||
# FIXME: enable once mysqljs supports auth_socket
|
# FIXME: enable once mysqljs supports auth_socket
|
||||||
# ensureUsers = [ {
|
# ensureUsers = [ {
|
||||||
|
@ -260,39 +283,28 @@ in
|
||||||
# } ];
|
# } ];
|
||||||
};
|
};
|
||||||
|
|
||||||
services.epgstation.settings = let
|
services.epgstation.settings =
|
||||||
defaultSettings = {
|
let
|
||||||
serverPort = cfg.port;
|
defaultSettings = {
|
||||||
socketioPort = cfg.socketioPort;
|
dbtype = lib.mkDefault "mysql";
|
||||||
clientSocketioPort = cfg.clientSocketioPort;
|
mysql = {
|
||||||
|
socketPath = lib.mkDefault "/run/mysqld/mysqld.sock";
|
||||||
|
user = username;
|
||||||
|
password = lib.mkDefault "@dbPassword@";
|
||||||
|
database = cfg.database.name;
|
||||||
|
};
|
||||||
|
|
||||||
dbType = mkDefault "mysql";
|
ffmpeg = lib.mkDefault "${pkgs.ffmpeg-full}/bin/ffmpeg";
|
||||||
mysql = {
|
ffprobe = lib.mkDefault "${pkgs.ffmpeg-full}/bin/ffprobe";
|
||||||
user = username;
|
|
||||||
database = cfg.database.name;
|
# for disambiguation with TypeScript files
|
||||||
socketPath = mkDefault "/run/mysqld/mysqld.sock";
|
recordedFileExtension = lib.mkDefault ".m2ts";
|
||||||
password = mkDefault "@dbPassword@";
|
|
||||||
connectTimeout = mkDefault 1000;
|
|
||||||
connectionLimit = mkDefault 10;
|
|
||||||
};
|
};
|
||||||
|
in
|
||||||
basicAuth = mkIf (cfg.basicAuth.user != null) {
|
lib.mkMerge [
|
||||||
user = mkDefault cfg.basicAuth.user;
|
defaultSettings
|
||||||
password = mkDefault "@password@";
|
(lib.mkIf cfg.usePreconfiguredStreaming streamingConfig)
|
||||||
};
|
];
|
||||||
|
|
||||||
ffmpeg = mkDefault "${pkgs.ffmpeg-full}/bin/ffmpeg";
|
|
||||||
ffprobe = mkDefault "${pkgs.ffmpeg-full}/bin/ffprobe";
|
|
||||||
|
|
||||||
fileExtension = mkDefault ".m2ts";
|
|
||||||
maxEncode = mkDefault 2;
|
|
||||||
maxStreaming = mkDefault 2;
|
|
||||||
};
|
|
||||||
in
|
|
||||||
mkMerge [
|
|
||||||
defaultSettings
|
|
||||||
(mkIf cfg.usePreconfiguredStreaming streamingConfig)
|
|
||||||
];
|
|
||||||
|
|
||||||
systemd.tmpfiles.rules = [
|
systemd.tmpfiles.rules = [
|
||||||
"d '/var/lib/epgstation/streamfiles' - ${username} ${groupname} - -"
|
"d '/var/lib/epgstation/streamfiles' - ${username} ${groupname} - -"
|
||||||
|
@ -301,15 +313,15 @@ in
|
||||||
];
|
];
|
||||||
|
|
||||||
systemd.services.epgstation = {
|
systemd.services.epgstation = {
|
||||||
description = pkgs.epgstation.meta.description;
|
inherit description;
|
||||||
|
|
||||||
wantedBy = [ "multi-user.target" ];
|
wantedBy = [ "multi-user.target" ];
|
||||||
after = [
|
after = [ "network.target" ]
|
||||||
"network.target"
|
++ lib.optional config.services.mirakurun.enable "mirakurun.service"
|
||||||
] ++ optional config.services.mirakurun.enable "mirakurun.service"
|
++ lib.optional config.services.mysql.enable "mysql.service";
|
||||||
++ optional config.services.mysql.enable "mysql.service";
|
|
||||||
|
|
||||||
serviceConfig = {
|
serviceConfig = {
|
||||||
ExecStart = "${pkgs.epgstation}/bin/epgstation start";
|
ExecStart = "${cfg.package}/bin/epgstation start";
|
||||||
ExecStartPre = "+${preStartScript}";
|
ExecStartPre = "+${preStartScript}";
|
||||||
User = username;
|
User = username;
|
||||||
Group = groupname;
|
Group = groupname;
|
||||||
|
|
|
@ -1,119 +1,140 @@
|
||||||
{
|
{
|
||||||
"liveHLS": [
|
"urlscheme": {
|
||||||
{
|
"m2ts": {
|
||||||
"name": "720p",
|
"ios": "vlc-x-callback://x-callback-url/stream?url=PROTOCOL://ADDRESS",
|
||||||
"cmd": "%FFMPEG% -re -dual_mono_mode main -i pipe:0 -sn -threads 0 -map 0 -ignore_unknown -max_muxing_queue_size 1024 -f hls -hls_time 3 -hls_list_size 17 -hls_allow_cache 1 -hls_segment_filename %streamFileDir%/stream%streamNum%-%09d.ts -c:a aac -ar 48000 -b:a 192k -ac 2 -c:v libx264 -vf yadif,scale=-2:720 -b:v 3000k -preset veryfast -flags +loop-global_header %OUTPUT%"
|
"android": "intent://ADDRESS#Intent;package=org.videolan.vlc;type=video;scheme=PROTOCOL;end"
|
||||||
},
|
},
|
||||||
{
|
"video": {
|
||||||
"name": "480p",
|
"ios": "infuse://x-callback-url/play?url=PROTOCOL://ADDRESS",
|
||||||
"cmd": "%FFMPEG% -re -dual_mono_mode main -i pipe:0 -sn -threads 0 -map 0 -ignore_unknown -max_muxing_queue_size 1024 -f hls -hls_time 3 -hls_list_size 17 -hls_allow_cache 1 -hls_segment_filename %streamFileDir%/stream%streamNum%-%09d.ts -c:a aac -ar 48000 -b:a 128k -ac 2 -c:v libx264 -vf yadif,scale=-2:480 -b:v 1500k -preset veryfast -flags +loop-global_header %OUTPUT%"
|
"android": "intent://ADDRESS#Intent;package=com.mxtech.videoplayer.ad;type=video;scheme=PROTOCOL;end"
|
||||||
},
|
},
|
||||||
{
|
"download": {
|
||||||
"name": "180p",
|
"ios": "vlc-x-callback://x-callback-url/download?url=PROTOCOL://ADDRESS&filename=FILENAME"
|
||||||
"cmd": "%FFMPEG% -re -dual_mono_mode main -i pipe:0 -sn -threads 0 -map 0 -ignore_unknown -max_muxing_queue_size 1024 -f hls -hls_time 3 -hls_list_size 17 -hls_allow_cache 1 -hls_segment_filename %streamFileDir%/stream%streamNum%-%09d.ts -c:a aac -ar 48000 -b:a 48k -ac 2 -c:v libx264 -vf yadif,scale=-2:180 -b:v 100k -preset veryfast -maxrate 110k -bufsize 1000k -flags +loop-global_header %OUTPUT%"
|
|
||||||
}
|
}
|
||||||
],
|
|
||||||
"liveMP4": [
|
|
||||||
{
|
|
||||||
"name": "720p",
|
|
||||||
"cmd": "%FFMPEG% -re -dual_mono_mode main -i pipe:0 -sn -threads 0 -c:a aac -ar 48000 -b:a 192k -ac 2 -c:v libx264 -vf yadif,scale=-2:720 -b:v 3000k -profile:v baseline -preset veryfast -tune fastdecode,zerolatency -movflags frag_keyframe+empty_moov+faststart+default_base_moof -y -f mp4 pipe:1"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "480p",
|
|
||||||
"cmd": "%FFMPEG% -re -dual_mono_mode main -i pipe:0 -sn -threads 0 -c:a aac -ar 48000 -b:a 128k -ac 2 -c:v libx264 -vf yadif,scale=-2:480 -b:v 1500k -profile:v baseline -preset veryfast -tune fastdecode,zerolatency -movflags frag_keyframe+empty_moov+faststart+default_base_moof -y -f mp4 pipe:1"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"liveWebM": [
|
|
||||||
{
|
|
||||||
"name": "720p",
|
|
||||||
"cmd": "%FFMPEG% -re -dual_mono_mode main -i pipe:0 -sn -threads 3 -c:a libvorbis -ar 48000 -b:a 192k -ac 2 -c:v libvpx-vp9 -vf yadif,scale=-2:720 -b:v 3000k -deadline realtime -speed 4 -cpu-used -8 -y -f webm pipe:1"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "480p",
|
|
||||||
"cmd": "%FFMPEG% -re -dual_mono_mode main -i pipe:0 -sn -threads 2 -c:a libvorbis -ar 48000 -b:a 128k -ac 2 -c:v libvpx-vp9 -vf yadif,scale=-2:480 -b:v 1500k -deadline realtime -speed 4 -cpu-used -8 -y -f webm pipe:1"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"mpegTsStreaming": [
|
|
||||||
{
|
|
||||||
"name": "720p",
|
|
||||||
"cmd": "%FFMPEG% -re -dual_mono_mode main -i pipe:0 -sn -threads 0 -c:a aac -ar 48000 -b:a 192k -ac 2 -c:v libx264 -vf yadif,scale=-2:720 -b:v 3000k -preset veryfast -y -f mpegts pipe:1"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "480p",
|
|
||||||
"cmd": "%FFMPEG% -re -dual_mono_mode main -i pipe:0 -sn -threads 0 -c:a aac -ar 48000 -b:a 128k -ac 2 -c:v libx264 -vf yadif,scale=-2:480 -b:v 1500k -preset veryfast -y -f mpegts pipe:1"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Original"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"mpegTsViewer": {
|
|
||||||
"ios": "vlc-x-callback://x-callback-url/stream?url=http://ADDRESS",
|
|
||||||
"android": "intent://ADDRESS#Intent;package=com.mxtech.videoplayer.ad;type=video;scheme=http;end"
|
|
||||||
},
|
},
|
||||||
"recordedDownloader": {
|
"stream": {
|
||||||
"ios": "vlc-x-callback://x-callback-url/download?url=http://ADDRESS&filename=FILENAME",
|
"live": {
|
||||||
"android": "intent://ADDRESS#Intent;package=com.dv.adm;type=video;scheme=http;end"
|
"ts": {
|
||||||
},
|
"m2ts": [
|
||||||
"recordedStreaming": {
|
{
|
||||||
"webm": [
|
"name": "720p",
|
||||||
{
|
"cmd": "%FFMPEG% -re -dual_mono_mode main -i pipe:0 -sn -threads 0 -c:a aac -ar 48000 -b:a 192k -ac 2 -c:v libx264 -vf yadif,scale=-2:720 -b:v 3000k -preset veryfast -y -f mpegts pipe:1"
|
||||||
"name": "720p",
|
},
|
||||||
"cmd": "%FFMPEG% -dual_mono_mode main %RE% -i pipe:0 -sn -threads 3 -c:a libvorbis -ar 48000 -ac 2 -c:v libvpx-vp9 -vf yadif,scale=-2:720 %VB% %VBUFFER% %AB% %ABUFFER% -deadline realtime -speed 4 -cpu-used -8 -y -f webm pipe:1",
|
{
|
||||||
"vb": "3000k",
|
"name": "480p",
|
||||||
"ab": "192k"
|
"cmd": "%FFMPEG% -re -dual_mono_mode main -i pipe:0 -sn -threads 0 -c:a aac -ar 48000 -b:a 128k -ac 2 -c:v libx264 -vf yadif,scale=-2:480 -b:v 1500k -preset veryfast -y -f mpegts pipe:1"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "360p",
|
"name": "無変換"
|
||||||
"cmd": "%FFMPEG% -dual_mono_mode main %RE% -i pipe:0 -sn -threads 2 -c:a libvorbis -ar 48000 -ac 2 -c:v libvpx-vp9 -vf yadif,scale=-2:360 %VB% %VBUFFER% %AB% %ABUFFER% -deadline realtime -speed 4 -cpu-used -8 -y -f webm pipe:1",
|
}
|
||||||
"vb": "1500k",
|
],
|
||||||
"ab": "128k"
|
"m2tsll": [
|
||||||
|
{
|
||||||
|
"name": "720p",
|
||||||
|
"cmd": "%FFMPEG% -dual_mono_mode main -f mpegts -analyzeduration 500000 -i pipe:0 -map 0 -c:s copy -c:d copy -ignore_unknown -fflags nobuffer -flags low_delay -max_delay 250000 -max_interleave_delta 1 -threads 0 -c:a aac -ar 48000 -b:a 192k -ac 2 -c:v libx264 -flags +cgop -vf yadif,scale=-2:720 -b:v 3000k -preset veryfast -y -f mpegts pipe:1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "480p",
|
||||||
|
"cmd": "%FFMPEG% -dual_mono_mode main -f mpegts -analyzeduration 500000 -i pipe:0 -map 0 -c:s copy -c:d copy -ignore_unknown -fflags nobuffer -flags low_delay -max_delay 250000 -max_interleave_delta 1 -threads 0 -c:a aac -ar 48000 -b:a 128k -ac 2 -c:v libx264 -flags +cgop -vf yadif,scale=-2:480 -b:v 1500k -preset veryfast -y -f mpegts pipe:1"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"webm": [
|
||||||
|
{
|
||||||
|
"name": "720p",
|
||||||
|
"cmd": "%FFMPEG% -re -dual_mono_mode main -i pipe:0 -sn -threads 3 -c:a libvorbis -ar 48000 -b:a 192k -ac 2 -c:v libvpx-vp9 -vf yadif,scale=-2:720 -b:v 3000k -deadline realtime -speed 4 -cpu-used -8 -y -f webm pipe:1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "480p",
|
||||||
|
"cmd": "%FFMPEG% -re -dual_mono_mode main -i pipe:0 -sn -threads 2 -c:a libvorbis -ar 48000 -b:a 128k -ac 2 -c:v libvpx-vp9 -vf yadif,scale=-2:480 -b:v 1500k -deadline realtime -speed 4 -cpu-used -8 -y -f webm pipe:1"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"mp4": [
|
||||||
|
{
|
||||||
|
"name": "720p",
|
||||||
|
"cmd": "%FFMPEG% -re -dual_mono_mode main -i pipe:0 -sn -threads 0 -c:a aac -ar 48000 -b:a 192k -ac 2 -c:v libx264 -vf yadif,scale=-2:720 -b:v 3000k -profile:v baseline -preset veryfast -tune fastdecode,zerolatency -movflags frag_keyframe+empty_moov+faststart+default_base_moof -y -f mp4 pipe:1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "480p",
|
||||||
|
"cmd": "%FFMPEG% -re -dual_mono_mode main -i pipe:0 -sn -threads 0 -c:a aac -ar 48000 -b:a 128k -ac 2 -c:v libx264 -vf yadif,scale=-2:480 -b:v 1500k -profile:v baseline -preset veryfast -tune fastdecode,zerolatency -movflags frag_keyframe+empty_moov+faststart+default_base_moof -y -f mp4 pipe:1"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"hls": [
|
||||||
|
{
|
||||||
|
"name": "720p",
|
||||||
|
"cmd": "%FFMPEG% -re -dual_mono_mode main -i pipe:0 -sn -map 0 -threads 0 -ignore_unknown -max_muxing_queue_size 1024 -f hls -hls_time 3 -hls_list_size 17 -hls_allow_cache 1 -hls_segment_filename %streamFileDir%/stream%streamNum%-%09d.ts -hls_flags delete_segments -c:a aac -ar 48000 -b:a 192k -ac 2 -c:v libx264 -vf yadif,scale=-2:720 -b:v 3000k -preset veryfast -flags +loop-global_header %OUTPUT%"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "480p",
|
||||||
|
"cmd": "%FFMPEG% -re -dual_mono_mode main -i pipe:0 -sn -map 0 -threads 0 -ignore_unknown -max_muxing_queue_size 1024 -f hls -hls_time 3 -hls_list_size 17 -hls_allow_cache 1 -hls_segment_filename %streamFileDir%/stream%streamNum%-%09d.ts -hls_flags delete_segments -c:a aac -ar 48000 -b:a 128k -ac 2 -c:v libx264 -vf yadif,scale=-2:480 -b:v 1500k -preset veryfast -flags +loop-global_header %OUTPUT%"
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
],
|
|
||||||
"mp4": [
|
|
||||||
{
|
|
||||||
"name": "720p",
|
|
||||||
"cmd": "%FFMPEG% -dual_mono_mode main %RE% -i pipe:0 -sn -threads 0 -c:a aac -ar 48000 -ac 2 -c:v libx264 -vf yadif,scale=-2:720 %VB% %VBUFFER% %AB% %ABUFFER% -profile:v baseline -preset veryfast -tune fastdecode,zerolatency -movflags frag_keyframe+empty_moov+faststart+default_base_moof -y -f mp4 pipe:1",
|
|
||||||
"vb": "3000k",
|
|
||||||
"ab": "192k"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "360p",
|
|
||||||
"cmd": "%FFMPEG% -dual_mono_mode main %RE% -i pipe:0 -sn -threads 0 -c:a aac -ar 48000 -ac 2 -c:v libx264 -vf yadif,scale=-2:360 %VB% %VBUFFER% %AB% %ABUFFER% -profile:v baseline -preset veryfast -tune fastdecode,zerolatency -movflags frag_keyframe+empty_moov+faststart+default_base_moof -y -f mp4 pipe:1",
|
|
||||||
"vb": "1500k",
|
|
||||||
"ab": "128k"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"mpegTs": [
|
|
||||||
{
|
|
||||||
"name": "720p (H.264)",
|
|
||||||
"cmd": "%FFMPEG% -dual_mono_mode main %RE% -i pipe:0 -sn -threads 0 -c:a aac -ar 48000 -ac 2 -c:v libx264 -vf yadif,scale=-2:720 %VB% %VBUFFER% %AB% %ABUFFER% -profile:v baseline -preset veryfast -tune fastdecode,zerolatency -y -f mpegts pipe:1",
|
|
||||||
"vb": "3000k",
|
|
||||||
"ab": "192k"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "360p (H.264)",
|
|
||||||
"cmd": "%FFMPEG% -dual_mono_mode main %RE% -i pipe:0 -sn -threads 0 -c:a aac -ar 48000 -ac 2 -c:v libx264 -vf yadif,scale=-2:360 %VB% %VBUFFER% %AB% %ABUFFER% -profile:v baseline -preset veryfast -tune fastdecode,zerolatency -y -f mpegts pipe:1",
|
|
||||||
"vb": "1500k",
|
|
||||||
"ab": "128k"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"recordedHLS": [
|
|
||||||
{
|
|
||||||
"name": "720p",
|
|
||||||
"cmd": "%FFMPEG% -dual_mono_mode main -i %INPUT% -sn -threads 0 -map 0 -ignore_unknown -max_muxing_queue_size 1024 -f hls -hls_time 3 -hls_list_size 0 -hls_allow_cache 1 -hls_segment_filename %streamFileDir%/stream%streamNum%-%09d.ts -c:a aac -ar 48000 -b:a 192k -ac 2 -c:v libx264 -vf yadif,scale=-2:720 -b:v 3000k -preset veryfast -flags +loop-global_header %OUTPUT%"
|
|
||||||
},
|
},
|
||||||
{
|
"recorded": {
|
||||||
"name": "480p",
|
"ts": {
|
||||||
"cmd": "%FFMPEG% -dual_mono_mode main -i %INPUT% -sn -threads 0 -map 0 -ignore_unknown -max_muxing_queue_size 1024 -f hls -hls_time 3 -hls_list_size 0 -hls_allow_cache 1 -hls_segment_filename %streamFileDir%/stream%streamNum%-%09d.ts -c:a aac -ar 48000 -b:a 128k -ac 2 -c:v libx264 -vf yadif,scale=-2:480 -b:v 1500k -preset veryfast -flags +loop-global_header %OUTPUT%"
|
"webm": [
|
||||||
},
|
{
|
||||||
{
|
"name": "720p",
|
||||||
"name": "480p(h265)",
|
"cmd": "%FFMPEG% -dual_mono_mode main -i pipe:0 -sn -threads 3 -c:a libvorbis -ar 48000 -b:a 192k -ac 2 -c:v libvpx-vp9 -vf yadif,scale=-2:720 -b:v 3000k -deadline realtime -speed 4 -cpu-used -8 -y -f webm pipe:1"
|
||||||
"cmd": "%FFMPEG% -dual_mono_mode main -i %INPUT% -sn -map 0 -ignore_unknown -max_muxing_queue_size 1024 -f hls -hls_time 3 -hls_list_size 0 -hls_allow_cache 1 -hls_segment_type fmp4 -hls_fmp4_init_filename stream%streamNum%-init.mp4 -hls_segment_filename stream%streamNum%-%09d.m4s -c:a aac -ar 48000 -b:a 128k -ac 2 -c:v libx265 -vf yadif,scale=-2:480 -b:v 350k -preset veryfast -tag:v hvc1 %OUTPUT%"
|
},
|
||||||
|
{
|
||||||
|
"name": "480p",
|
||||||
|
"cmd": "%FFMPEG% -dual_mono_mode main -i pipe:0 -sn -threads 3 -c:a libvorbis -ar 48000 -b:a 128k -ac 2 -c:v libvpx-vp9 -vf yadif,scale=-2:480 -b:v 1500k -deadline realtime -speed 4 -cpu-used -8 -y -f webm pipe:1"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"mp4": [
|
||||||
|
{
|
||||||
|
"name": "720p",
|
||||||
|
"cmd": "%FFMPEG% -dual_mono_mode main -i pipe:0 -sn -threads 0 -c:a aac -ar 48000 -b:a 192k -ac 2 -c:v libx264 -vf yadif,scale=-2:720 -b:v 3000k -profile:v baseline -preset veryfast -tune fastdecode,zerolatency -movflags frag_keyframe+empty_moov+faststart+default_base_moof -y -f mp4 pipe:1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "480p",
|
||||||
|
"cmd": "%FFMPEG% -dual_mono_mode main -i pipe:0 -sn -threads 0 -c:a aac -ar 48000 -b:a 128k -ac 2 -c:v libx264 -vf yadif,scale=-2:480 -b:v 1500k -profile:v baseline -preset veryfast -tune fastdecode,zerolatency -movflags frag_keyframe+empty_moov+faststart+default_base_moof -y -f mp4 pipe:1"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"hls": [
|
||||||
|
{
|
||||||
|
"name": "720p",
|
||||||
|
"cmd": "%FFMPEG% -dual_mono_mode main -i pipe:0 -sn -map 0 -threads 0 -ignore_unknown -max_muxing_queue_size 1024 -f hls -hls_time 3 -hls_list_size 0 -hls_allow_cache 1 -hls_segment_filename %streamFileDir%/stream%streamNum%-%09d.ts -hls_flags delete_segments -c:a aac -ar 48000 -b:a 192k -ac 2 -c:v libx264 -vf yadif,scale=-2:720 -b:v 3000k -preset veryfast -flags +loop-global_header %OUTPUT%"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "480p",
|
||||||
|
"cmd": "%FFMPEG% -dual_mono_mode main -i pipe:0 -sn -map 0 -threads 0 -ignore_unknown -max_muxing_queue_size 1024 -f hls -hls_time 3 -hls_list_size 0 -hls_allow_cache 1 -hls_segment_filename %streamFileDir%/stream%streamNum%-%09d.ts -hls_flags delete_segments -c:a aac -ar 48000 -b:a 128k -ac 2 -c:v libx264 -vf yadif,scale=-2:480 -b:v 1500k -preset veryfast -flags +loop-global_header %OUTPUT%"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"encoded": {
|
||||||
|
"webm": [
|
||||||
|
{
|
||||||
|
"name": "720p",
|
||||||
|
"cmd": "%FFMPEG% -dual_mono_mode main -ss %SS% -i %INPUT% -sn -threads 3 -c:a libvorbis -ar 48000 -b:a 192k -ac 2 -c:v libvpx-vp9 -vf scale=-2:720 -b:v 3000k -deadline realtime -speed 4 -cpu-used -8 -y -f webm pipe:1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "480p",
|
||||||
|
"cmd": "%FFMPEG% -dual_mono_mode main -ss %SS% -i %INPUT% -sn -threads 3 -c:a libvorbis -ar 48000 -b:a 128k -ac 2 -c:v libvpx-vp9 -vf scale=-2:480 -b:v 1500k -deadline realtime -speed 4 -cpu-used -8 -y -f webm pipe:1"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"mp4": [
|
||||||
|
{
|
||||||
|
"name": "720p",
|
||||||
|
"cmd": "%FFMPEG% -dual_mono_mode main -ss %SS% -i %INPUT% -sn -threads 0 -c:a aac -ar 48000 -b:a 192k -ac 2 -c:v libx264 -vf scale=-2:720 -b:v 3000k -profile:v baseline -preset veryfast -tune fastdecode,zerolatency -movflags frag_keyframe+empty_moov+faststart+default_base_moof -y -f mp4 pipe:1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "480p",
|
||||||
|
"cmd": "%FFMPEG% -dual_mono_mode main -ss %SS% -i %INPUT% -sn -threads 0 -c:a aac -ar 48000 -b:a 128k -ac 2 -c:v libx264 -vf scale=-2:480 -b:v 1500k -profile:v baseline -preset veryfast -tune fastdecode,zerolatency -movflags frag_keyframe+empty_moov+faststart+default_base_moof -y -f mp4 pipe:1"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"hls": [
|
||||||
|
{
|
||||||
|
"name": "720p",
|
||||||
|
"cmd": "%FFMPEG% -dual_mono_mode main -ss %SS% -i %INPUT% -sn -threads 0 -ignore_unknown -max_muxing_queue_size 1024 -f hls -hls_time 3 -hls_list_size 0 -hls_allow_cache 1 -hls_segment_filename %streamFileDir%/stream%streamNum%-%09d.ts -hls_flags delete_segments -c:a aac -ar 48000 -b:a 192k -ac 2 -c:v libx264 -vf scale=-2:720 -b:v 3000k -preset veryfast -flags +loop-global_header %OUTPUT%"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "480p",
|
||||||
|
"cmd": "%FFMPEG% -dual_mono_mode main -ss %SS% -i %INPUT% -sn -threads 0 -ignore_unknown -max_muxing_queue_size 1024 -f hls -hls_time 3 -hls_list_size 0 -hls_allow_cache 1 -hls_segment_filename %streamFileDir%/stream%streamNum%-%09d.ts -hls_flags delete_segments -c:a aac -ar 48000 -b:a 128k -ac 2 -c:v libx264 -vf scale=-2:480 -b:v 3000k -preset veryfast -flags +loop-global_header %OUTPUT%"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
],
|
|
||||||
"recordedViewer": {
|
|
||||||
"ios": "infuse://x-callback-url/play?url=http://ADDRESS",
|
|
||||||
"android": "intent://ADDRESS#Intent;package=com.mxtech.videoplayer.ad;type=video;scheme=http;end"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
57
pkgs/applications/video/epgstation/client/package.json
Normal file
57
pkgs/applications/video/epgstation/client/package.json
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
{
|
||||||
|
"name": "epgstation-client",
|
||||||
|
"version": "2.6.20",
|
||||||
|
"private": true,
|
||||||
|
"scripts": {
|
||||||
|
"build": "vue-cli-service build",
|
||||||
|
"lint": "vue-cli-service lint",
|
||||||
|
"watch": "vue-cli-service build --watch --mode development"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@mdi/font": "6.5.95",
|
||||||
|
"aribb24.js": "1.8.8",
|
||||||
|
"axios": "0.24.0",
|
||||||
|
"eventemitter2": "6.4.5",
|
||||||
|
"hls.js": "1.1.2",
|
||||||
|
"inversify": "6.0.1",
|
||||||
|
"json-stable-stringify": "1.0.1",
|
||||||
|
"lodash": "4.17.21",
|
||||||
|
"material-design-icons-iconfont": "6.1.1",
|
||||||
|
"mpegts.js": "1.6.10",
|
||||||
|
"reflect-metadata": "0.1.13",
|
||||||
|
"resize-observer-polyfill": "1.5.1",
|
||||||
|
"roboto-fontface": "*",
|
||||||
|
"smoothscroll-polyfill": "0.4.4",
|
||||||
|
"socket.io-client": "4.3.2",
|
||||||
|
"typeface-roboto": "1.1.13",
|
||||||
|
"vue": "2.6.14",
|
||||||
|
"vue-class-component": "7.2.6",
|
||||||
|
"vue-property-decorator": "9.1.2",
|
||||||
|
"vue-router": "3.5.3",
|
||||||
|
"vuetify": "2.5.10",
|
||||||
|
"vuetify-datetime-picker": "2.1.1",
|
||||||
|
"@types/hls.js": "0.13.3",
|
||||||
|
"@types/json-stable-stringify": "1.0.33",
|
||||||
|
"@types/lodash": "4.14.178",
|
||||||
|
"@types/smoothscroll-polyfill": "0.3.1",
|
||||||
|
"@types/socket.io-client": "1.4.36",
|
||||||
|
"@typescript-eslint/eslint-plugin": "4.33.0",
|
||||||
|
"@typescript-eslint/parser": "4.33.0",
|
||||||
|
"@vue/cli-plugin-eslint": "4.5.12",
|
||||||
|
"@vue/cli-plugin-typescript": "4.5.13",
|
||||||
|
"@vue/cli-plugin-vuex": "4.5.13",
|
||||||
|
"@vue/cli-service": "4.5.13",
|
||||||
|
"@vue/eslint-config-prettier": "6.0.0",
|
||||||
|
"@vue/eslint-config-typescript": "7.0.0",
|
||||||
|
"eslint": "7.32.0",
|
||||||
|
"eslint-plugin-prettier": "3.4.1",
|
||||||
|
"eslint-plugin-vue": "7.20.0",
|
||||||
|
"prettier": "2.4.1",
|
||||||
|
"sass": "1.32.12",
|
||||||
|
"sass-loader": "10.2.0",
|
||||||
|
"typescript": "4.4.4",
|
||||||
|
"vue-cli-plugin-vuetify": "2.4.3",
|
||||||
|
"vue-template-compiler": "2.6.14",
|
||||||
|
"vuetify-loader": "1.7.3"
|
||||||
|
}
|
||||||
|
}
|
|
@ -10,17 +10,18 @@
|
||||||
, nodePackages
|
, nodePackages
|
||||||
, gzip
|
, gzip
|
||||||
, jq
|
, jq
|
||||||
|
, yq
|
||||||
}:
|
}:
|
||||||
|
|
||||||
let
|
let
|
||||||
# NOTE: use updateScript to bump the package version
|
# NOTE: use updateScript to bump the package version
|
||||||
pname = "EPGStation";
|
pname = "EPGStation";
|
||||||
version = "1.7.5";
|
version = "2.6.20";
|
||||||
src = fetchFromGitHub {
|
src = fetchFromGitHub {
|
||||||
owner = "l3tnun";
|
owner = "l3tnun";
|
||||||
repo = "EPGStation";
|
repo = "EPGStation";
|
||||||
rev = "v${version}";
|
rev = "v${version}";
|
||||||
sha256 = "06yaf5yb5rp3q0kdhw33df7px7vyfby885ckb6bdzw3wnams5d8m";
|
sha256 = "K1cAvmqWEfS6EY4MKAtjXb388XLYHtouxNM70PWgFig=";
|
||||||
};
|
};
|
||||||
|
|
||||||
workaround-opencollective-buildfailures = stdenv.mkDerivation {
|
workaround-opencollective-buildfailures = stdenv.mkDerivation {
|
||||||
|
@ -35,19 +36,44 @@ let
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
pkg = nodePackages.epgstation.override (drv: {
|
client = nodePackages.epgstation-client.override (drv: {
|
||||||
|
# FIXME: remove this option if possible
|
||||||
|
#
|
||||||
|
# Unsetting this option resulted NPM attempting to re-download packages.
|
||||||
|
dontNpmInstall = true;
|
||||||
|
|
||||||
|
meta = drv.meta // {
|
||||||
|
inherit (nodejs.meta) platforms;
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
server = nodePackages.epgstation.override (drv: {
|
||||||
inherit src;
|
inherit src;
|
||||||
|
|
||||||
|
bypassCache = false;
|
||||||
|
|
||||||
|
# This is set to false to keep devDependencies at build time. Build time
|
||||||
|
# dependencies are pruned afterwards.
|
||||||
|
production = false;
|
||||||
|
|
||||||
buildInputs = [ bash ];
|
buildInputs = [ bash ];
|
||||||
nativeBuildInputs = [
|
nativeBuildInputs = [
|
||||||
|
nodejs
|
||||||
workaround-opencollective-buildfailures
|
workaround-opencollective-buildfailures
|
||||||
makeWrapper
|
makeWrapper
|
||||||
nodePackages.node-pre-gyp
|
] ++ (with nodePackages; [
|
||||||
];
|
node-pre-gyp
|
||||||
|
node-gyp-build
|
||||||
|
]);
|
||||||
|
|
||||||
preRebuild = ''
|
preRebuild = ''
|
||||||
# Fix for not being able to connect to mysql using domain sockets.
|
# Fix for not being able to connect to mysql using domain sockets.
|
||||||
patch -p1 ${./use-mysql-over-domain-socket.patch}
|
patch -p1 < ${./use-mysql-over-domain-socket.patch}
|
||||||
|
|
||||||
|
# Workaround for https://github.com/svanderburg/node2nix/issues/275
|
||||||
|
sed -i -e "s|#!/usr/bin/env node|#! ${nodejs}/bin/node|" node_modules/node-gyp-build/bin.js
|
||||||
|
|
||||||
|
find . -name package-lock.json -delete
|
||||||
'';
|
'';
|
||||||
|
|
||||||
postInstall = let
|
postInstall = let
|
||||||
|
@ -56,12 +82,19 @@ let
|
||||||
''
|
''
|
||||||
mkdir -p $out/{bin,libexec,share/doc/epgstation,share/man/man1}
|
mkdir -p $out/{bin,libexec,share/doc/epgstation,share/man/man1}
|
||||||
|
|
||||||
pushd $out/lib/node_modules/EPGStation
|
pushd $out/lib/node_modules/epgstation
|
||||||
|
|
||||||
|
cp -r ${client}/lib/node_modules/epgstation-client/node_modules client/node_modules
|
||||||
|
chmod -R u+w client/node_modules
|
||||||
|
|
||||||
npm run build
|
npm run build
|
||||||
npm prune --production
|
|
||||||
|
|
||||||
mv config/{enc.sh,enc.js} $out/libexec
|
npm prune --production
|
||||||
|
pushd client
|
||||||
|
npm prune --production
|
||||||
|
popd
|
||||||
|
|
||||||
|
mv config/enc.js.template $out/libexec/enc.js
|
||||||
mv LICENSE Readme.md $out/share/doc/epgstation
|
mv LICENSE Readme.md $out/share/doc/epgstation
|
||||||
mv doc/* $out/share/doc/epgstation
|
mv doc/* $out/share/doc/epgstation
|
||||||
sed 's/@DESCRIPTION@/${drv.meta.description}/g' ${./epgstation.1} \
|
sed 's/@DESCRIPTION@/${drv.meta.description}/g' ${./epgstation.1} \
|
||||||
|
@ -82,8 +115,9 @@ let
|
||||||
ln -sfT /var/lib/epgstation/thumbnail thumbnail
|
ln -sfT /var/lib/epgstation/thumbnail thumbnail
|
||||||
|
|
||||||
makeWrapper ${nodejs}/bin/npm $out/bin/epgstation \
|
makeWrapper ${nodejs}/bin/npm $out/bin/epgstation \
|
||||||
--run "cd $out/lib/node_modules/EPGStation" \
|
--run "cd $out/lib/node_modules/epgstation" \
|
||||||
--prefix PATH : ${lib.makeBinPath runtimeDeps}
|
--prefix PATH : ${lib.makeBinPath runtimeDeps} \
|
||||||
|
--set APP_ROOT_PATH "$out/lib/node_modules/epgstation"
|
||||||
|
|
||||||
popd
|
popd
|
||||||
'';
|
'';
|
||||||
|
@ -99,22 +133,25 @@ let
|
||||||
common-updater-scripts
|
common-updater-scripts
|
||||||
genericUpdater
|
genericUpdater
|
||||||
writers
|
writers
|
||||||
jq;
|
jq
|
||||||
|
yq;
|
||||||
};
|
};
|
||||||
|
|
||||||
# nodePackages.epgstation is a stub package to fetch npm dependencies and
|
# nodePackages.epgstation is a stub package to fetch npm dependencies and
|
||||||
# is marked as broken to prevent users from installing it directly. This
|
# its meta.platforms is made empty to prevent users from installing it
|
||||||
# technique ensures epgstation can share npm packages with the rest of
|
# directly. This technique ensures epgstation can share npm packages with
|
||||||
# nixpkgs while still allowing us to heavily customize the build. It also
|
# the rest of nixpkgs while still allowing us to heavily customize the
|
||||||
# allows us to provide devDependencies for the epgstation build process
|
# build. It also allows us to provide devDependencies for the epgstation
|
||||||
# without doing the same for all the other node packages.
|
# build process without doing the same for all the other node packages.
|
||||||
meta = drv.meta // { broken = false; };
|
meta = drv.meta // {
|
||||||
|
inherit (nodejs.meta) platforms;
|
||||||
|
};
|
||||||
});
|
});
|
||||||
in
|
in
|
||||||
pkg // {
|
server // {
|
||||||
name = "${pname}-${version}";
|
name = "${pname}-${version}";
|
||||||
|
|
||||||
meta = with lib; pkg.meta // {
|
meta = with lib; server.meta // {
|
||||||
maintainers = with maintainers; [ midchildan ];
|
maintainers = with maintainers; [ midchildan ];
|
||||||
|
|
||||||
# NOTE: updateScript relies on this being correct
|
# NOTE: updateScript relies on this being correct
|
||||||
|
|
|
@ -27,7 +27,7 @@ platforms, run
|
||||||
to start EPGStation.
|
to start EPGStation.
|
||||||
.Sh FILES
|
.Sh FILES
|
||||||
.Bl -tag -width Ds -compact
|
.Bl -tag -width Ds -compact
|
||||||
.It Pa /etc/epgstation/config.json
|
.It Pa /etc/epgstation/config.yml
|
||||||
.Nm
|
.Nm
|
||||||
configuration file.
|
configuration file.
|
||||||
.El
|
.El
|
||||||
|
@ -48,5 +48,9 @@ Restore the EPGstation database.
|
||||||
.Pp
|
.Pp
|
||||||
.Dl $ epgstation run restore /path/to/src
|
.Dl $ epgstation run restore /path/to/src
|
||||||
.Pp
|
.Pp
|
||||||
|
Restore the EPGstation database from the prior v1 release.
|
||||||
|
.Pp
|
||||||
|
.Dl $ epgstation run v1migrate /path/to/src
|
||||||
|
.Pp
|
||||||
.Sh SEE ALSO
|
.Sh SEE ALSO
|
||||||
.Xr npm 1
|
.Xr npm 1
|
||||||
|
|
|
@ -1,85 +1,72 @@
|
||||||
{
|
{
|
||||||
"name": "EPGStation",
|
"name": "epgstation",
|
||||||
"version": "1.7.5",
|
"version": "2.6.20",
|
||||||
"description": "DTV Software in Japan.",
|
"description": "DTV Software in Japan.",
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/l3tnun/EPGStation.git"
|
"url": "git+https://github.com/l3tnun/EPGStation-V2.git"
|
||||||
},
|
},
|
||||||
"author": "l3tnun",
|
"author": "l3tnun",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"bugs": {
|
"bugs": {
|
||||||
"url": "https://github.com/l3tnun/EPGStation/issues"
|
"url": "https://github.com/l3tnun/EPGStation-V2/issues"
|
||||||
},
|
|
||||||
"homepage": "https://github.com/l3tnun/EPGStation#readme",
|
|
||||||
"engines": {
|
|
||||||
"node": "^10.x.x < 11 || ^12.14.0 < 13 || ^14.5.0 < 15"
|
|
||||||
},
|
},
|
||||||
|
"homepage": "https://github.com/l3tnun/EPGStation-V2#readme",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"aribts": "^2.1.12",
|
"arib-subtitle-timedmetadater": "4.0.9",
|
||||||
"b24.js": "1.0.3",
|
"aribts": "2.1.12",
|
||||||
"basic-auth": "2.0.1",
|
"axios": "0.24.0",
|
||||||
"body-parser": "1.19.0",
|
"body-parser": "1.19.0",
|
||||||
"chart.js": "2.9.3",
|
"cors": "2.8.5",
|
||||||
"css-ripple-effect": "1.0.5",
|
"diskusage-ng": "1.0.2",
|
||||||
"diskusage": "1.1.3",
|
|
||||||
"express": "4.17.1",
|
"express": "4.17.1",
|
||||||
"express-openapi": "7.0.1",
|
"express-openapi": "9.3.0",
|
||||||
"fs-extra": "9.0.1",
|
"file-type": "16.5.3",
|
||||||
"hls-b24.js": "0.12.3",
|
"inversify": "5.1.1",
|
||||||
"js-yaml": "3.14.0",
|
"js-yaml": "4.1.0",
|
||||||
"lodash": "4.17.20",
|
"lodash": "4.17.21",
|
||||||
"log4js": "6.3.0",
|
"log4js": "6.3.0",
|
||||||
"material-design-icons": "3.0.1",
|
|
||||||
"material-design-lite": "1.3.0",
|
|
||||||
"minimist": "1.2.5",
|
"minimist": "1.2.5",
|
||||||
"mirakurun": "3.3.1",
|
"mirakurun": "3.9.0-beta.26",
|
||||||
"mithril": "2.0.4",
|
|
||||||
"mkdirp": "1.0.4",
|
"mkdirp": "1.0.4",
|
||||||
"multer": "1.4.2",
|
"multer": "1.4.3",
|
||||||
"mysql": "2.18.1",
|
"mysql": "2.18.1",
|
||||||
"openapi-types": "7.0.1",
|
"openapi-types": "9.3.0",
|
||||||
"pg": "8.3.3",
|
"reflect-metadata": "0.1.13",
|
||||||
"request": "2.88.2",
|
"socket.io": "4.3.1",
|
||||||
"socket.io": "2.3.0",
|
"source-map-support": "0.5.20",
|
||||||
"socket.io-client": "2.3.0",
|
"sqlite3": "5.0.2",
|
||||||
"sqlite3": "5.0.0",
|
"swagger-ui-dist": "3.52.5",
|
||||||
"swagger-ui-dist": "3.34.0",
|
"typeorm": "0.2.38",
|
||||||
"url-join": "4.0.1",
|
"url-join": "4.0.1",
|
||||||
"@types/basic-auth": "1.1.3",
|
"@types/body-parser": "1.19.1",
|
||||||
"@types/body-parser": "1.19.0",
|
"@types/express": "4.17.13",
|
||||||
"@types/chart.js": "2.9.24",
|
"@types/file-type": "10.9.1",
|
||||||
"@types/express": "4.17.8",
|
"@types/js-yaml": "4.0.4",
|
||||||
"@types/hls.js": "0.13.1",
|
"@types/lodash": "4.14.176",
|
||||||
"@types/js-yaml": "3.12.5",
|
"@types/minimist": "1.2.2",
|
||||||
"@types/lodash": "4.14.161",
|
"@types/mkdirp": "1.0.2",
|
||||||
"@types/material-design-lite": "1.1.16",
|
"@types/mongodb": "4.0.6",
|
||||||
"@types/minimist": "1.2.0",
|
"@types/multer": "1.4.7",
|
||||||
"@types/mithril": "2.0.3",
|
"@types/node": "16.11.6",
|
||||||
"@types/mkdirp": "1.0.1",
|
"@types/socket.io": "3.0.1",
|
||||||
"@types/multer": "1.4.4",
|
"@types/source-map-support": "0.5.4",
|
||||||
"@types/mysql": "2.15.15",
|
"@types/sqlite3": "3.1.7",
|
||||||
"@types/node": "14.11.1",
|
"@types/url-join": "4.0.1",
|
||||||
"@types/pg": "7.14.5",
|
"@typescript-eslint/eslint-plugin": "4.33.0",
|
||||||
"@types/request": "2.48.5",
|
"@typescript-eslint/parser": "4.33.0",
|
||||||
"@types/socket.io": "2.1.11",
|
"del": "6.0.0",
|
||||||
"@types/socket.io-client": "1.4.33",
|
"eslint": "7.32.0",
|
||||||
"@types/sqlite3": "3.1.6",
|
"eslint-config-prettier": "8.3.0",
|
||||||
"@types/url-join": "4.0.0",
|
"eslint-plugin-prettier": "3.4.1",
|
||||||
"del": "5.1.0",
|
|
||||||
"gulp": "4.0.2",
|
"gulp": "4.0.2",
|
||||||
"gulp-clean-css": "4.3.0",
|
"gulp-eslint": "6.0.0",
|
||||||
"gulp-concat": "2.6.1",
|
|
||||||
"gulp-dart-sass": "1.0.2",
|
|
||||||
"gulp-plumber": "1.2.1",
|
"gulp-plumber": "1.2.1",
|
||||||
"gulp-sourcemaps": "2.6.5",
|
"gulp-sourcemaps": "3.0.0",
|
||||||
"gulp-tslint": "8.1.4",
|
|
||||||
"gulp-typescript": "5.0.1",
|
"gulp-typescript": "5.0.1",
|
||||||
"terser-webpack-plugin": "4.2.2",
|
"prettier": "2.4.1",
|
||||||
"ts-loader": "8.0.4",
|
"ts-loader": "9.2.6",
|
||||||
"tslint": "6.1.3",
|
"ts-node": "10.4.0",
|
||||||
"typescript": "4.0.3",
|
"typescript": "4.4.4"
|
||||||
"webpack": "4.44.2",
|
|
||||||
"webpack-stream": "6.1.0"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
, genericUpdater
|
, genericUpdater
|
||||||
, writers
|
, writers
|
||||||
, jq
|
, jq
|
||||||
|
, yq
|
||||||
}:
|
}:
|
||||||
|
|
||||||
let
|
let
|
||||||
|
@ -40,6 +41,11 @@ in writers.writeBash "update-epgstation" ''
|
||||||
} | del(.devDependencies, .main, .scripts)' \
|
} | del(.devDependencies, .main, .scripts)' \
|
||||||
"$SRC/package.json" \
|
"$SRC/package.json" \
|
||||||
> package.json
|
> package.json
|
||||||
|
${jq}/bin/jq '. + {
|
||||||
|
dependencies: (.dependencies + .devDependencies),
|
||||||
|
} | del(.devDependencies, .main, .scripts)' \
|
||||||
|
"$SRC/client/package.json" \
|
||||||
|
> client/package.json
|
||||||
|
|
||||||
# Regenerate node packages to update the pre-overriden epgstation derivation.
|
# Regenerate node packages to update the pre-overriden epgstation derivation.
|
||||||
# This must come *after* package.json has been regenerated.
|
# This must come *after* package.json has been regenerated.
|
||||||
|
@ -49,18 +55,11 @@ in writers.writeBash "update-epgstation" ''
|
||||||
|
|
||||||
# Generate default streaming settings for the nixos module.
|
# Generate default streaming settings for the nixos module.
|
||||||
pushd ../../../../nixos/modules/services/video/epgstation
|
pushd ../../../../nixos/modules/services/video/epgstation
|
||||||
${jq}/bin/jq '
|
${yq}/bin/yq -j '{ urlscheme , stream }' \
|
||||||
{ liveHLS
|
"$SRC/config/config.yml.template" \
|
||||||
, liveMP4
|
|
||||||
, liveWebM
|
|
||||||
, mpegTsStreaming
|
|
||||||
, mpegTsViewer
|
|
||||||
, recordedDownloader
|
|
||||||
, recordedStreaming
|
|
||||||
, recordedHLS
|
|
||||||
, recordedViewer
|
|
||||||
}' \
|
|
||||||
"$SRC/config/config.sample.json" \
|
|
||||||
> streaming.json
|
> streaming.json
|
||||||
|
|
||||||
|
# Fix generated output for EditorConfig compliance
|
||||||
|
printf '\n' >> streaming.json # rule: insert_final_newline
|
||||||
popd
|
popd
|
||||||
''
|
''
|
||||||
|
|
|
@ -1,17 +1,46 @@
|
||||||
diff --git a/src/server/ConfigInterface.ts b/src/server/ConfigInterface.ts
|
diff --git a/ormconfig.js b/ormconfig.js
|
||||||
index d23badd..1dd2b98 100644
|
index 5591853b..838c06cb 100644
|
||||||
--- a/src/server/ConfigInterface.ts
|
--- a/ormconfig.js
|
||||||
+++ b/src/server/ConfigInterface.ts
|
+++ b/ormconfig.js
|
||||||
@@ -11,9 +11,10 @@ interface ConfigInterface {
|
@@ -38,8 +38,6 @@ switch (config.dbtype) {
|
||||||
dbPath: string;
|
|
||||||
dbInfoPath: string;
|
case 'mysql':
|
||||||
mysql: {
|
ormConfig.type = 'mysql';
|
||||||
|
- ormConfig.host = config.mysql.host;
|
||||||
|
- ormConfig.port = config.mysql.port;
|
||||||
|
ormConfig.username = config.mysql.user;
|
||||||
|
ormConfig.password = config.mysql.password;
|
||||||
|
ormConfig.database = config.mysql.database;
|
||||||
|
@@ -49,6 +47,12 @@ switch (config.dbtype) {
|
||||||
|
} else {
|
||||||
|
ormConfig.charset = config.mysql.charset;
|
||||||
|
}
|
||||||
|
+ if (config.mysql.socketPath) {
|
||||||
|
+ ormConfig.socketPath = config.mysql.socketPath;
|
||||||
|
+ } else {
|
||||||
|
+ ormConfig.host = config.mysql.host;
|
||||||
|
+ ormConfig.port = config.mysql.port;
|
||||||
|
+ }
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'postgres':
|
||||||
|
diff --git a/src/model/IConfigFile.ts b/src/model/IConfigFile.ts
|
||||||
|
index 6a502e83..ba84a423 100644
|
||||||
|
--- a/src/model/IConfigFile.ts
|
||||||
|
+++ b/src/model/IConfigFile.ts
|
||||||
|
@@ -61,12 +61,13 @@ export default interface IConfigFile {
|
||||||
|
regexp?: boolean;
|
||||||
|
};
|
||||||
|
mysql?: {
|
||||||
- host: string;
|
- host: string;
|
||||||
+ host?: string;
|
+ host?: string;
|
||||||
+ socketPath?: string;
|
|
||||||
user: string;
|
user: string;
|
||||||
- password: string;
|
- port: number;
|
||||||
+ password?: string;
|
+ port?: number;
|
||||||
|
password: string;
|
||||||
database: string;
|
database: string;
|
||||||
connectTimeout: number;
|
charset?: string;
|
||||||
connectionLimit: number;
|
+ socketPath?: string;
|
||||||
|
};
|
||||||
|
postgres?: {
|
||||||
|
host: string;
|
||||||
|
|
|
@ -127,7 +127,15 @@ let
|
||||||
# ../../applications/video/epgstation
|
# ../../applications/video/epgstation
|
||||||
epgstation = super."epgstation-../../applications/video/epgstation".override (drv: {
|
epgstation = super."epgstation-../../applications/video/epgstation".override (drv: {
|
||||||
meta = drv.meta // {
|
meta = drv.meta // {
|
||||||
broken = true; # not really broken, see the comment above
|
platforms = pkgs.lib.platforms.none;
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
# NOTE: this is a stub package to fetch npm dependencies for
|
||||||
|
# ../../applications/video/epgstation/client
|
||||||
|
epgstation-client = super."epgstation-client-../../applications/video/epgstation/client".override (drv: {
|
||||||
|
meta = drv.meta // {
|
||||||
|
platforms = pkgs.lib.platforms.none;
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -270,6 +278,14 @@ let
|
||||||
url = "https://github.com/svanderburg/node2nix/commit/e4c951971df6c9f9584c7252971c13b55c369916.patch";
|
url = "https://github.com/svanderburg/node2nix/commit/e4c951971df6c9f9584c7252971c13b55c369916.patch";
|
||||||
sha256 = "0w8fcyr12g2340rn06isv40jkmz2khmak81c95zpkjgipzx7hp7w";
|
sha256 = "0w8fcyr12g2340rn06isv40jkmz2khmak81c95zpkjgipzx7hp7w";
|
||||||
})
|
})
|
||||||
|
# handle package alias in dependencies
|
||||||
|
# https://github.com/svanderburg/node2nix/pull/240
|
||||||
|
#
|
||||||
|
# TODO: remove after node2nix 1.10.0
|
||||||
|
(fetchpatch {
|
||||||
|
url = "https://github.com/svanderburg/node2nix/commit/644e90c0304038a446ed53efc97e9eb1e2831e71.patch";
|
||||||
|
sha256 = "sha256-sQgVf80H1ouUjzHq+2d9RO4a+o++kh+l+FOTNXfPBH0=";
|
||||||
|
})
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
postInstall = ''
|
postInstall = ''
|
||||||
|
|
|
@ -114,6 +114,7 @@
|
||||||
, "emoj"
|
, "emoj"
|
||||||
, "emojione"
|
, "emojione"
|
||||||
, {"epgstation": "../../applications/video/epgstation"}
|
, {"epgstation": "../../applications/video/epgstation"}
|
||||||
|
, {"epgstation-client": "../../applications/video/epgstation/client"}
|
||||||
, "escape-string-regexp"
|
, "escape-string-regexp"
|
||||||
, "eslint"
|
, "eslint"
|
||||||
, "eslint_d"
|
, "eslint_d"
|
||||||
|
|
7530
pkgs/development/node-packages/node-packages.nix
generated
7530
pkgs/development/node-packages/node-packages.nix
generated
File diff suppressed because it is too large
Load diff
Loading…
Reference in a new issue