diff --git a/server/package-lock.json b/server/package-lock.json index ddadb2b5c..4dfd567c0 100644 --- a/server/package-lock.json +++ b/server/package-lock.json @@ -1,12 +1,12 @@ { "name": "@scrypted/server", - "version": "0.123.73", + "version": "0.125.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@scrypted/server", - "version": "0.123.73", + "version": "0.125.1", "hasInstallScript": true, "license": "ISC", "dependencies": { diff --git a/server/python/plugin_remote.py b/server/python/plugin_remote.py index c2c142430..c67c89391 100644 --- a/server/python/plugin_remote.py +++ b/server/python/plugin_remote.py @@ -6,6 +6,7 @@ import inspect import multiprocessing import multiprocessing.connection import os +from pathlib import Path import platform import random import sys @@ -472,11 +473,39 @@ class MediaManager: ) -> scrypted_python.scrypted_sdk.types.MediaObject: return await self.mediaManager.createMediaObjectFromUrl(data, options) - async def getFFmpegPath(self) -> str: + async def get_ffmpeg_path(self): + # try to get the ffmpeg path as a value of another variable + # ie, in docker builds: + # export SCRYPTED_FFMPEG_PATH_ENV_VARIABLE=SCRYPTED_RASPBIAN_FFMPEG_PATH + v = os.getenv('SCRYPTED_FFMPEG_PATH_ENV_VARIABLE') + if v: + f = os.getenv(v) + if f and Path(f).exists(): + return f + + # try to get the ffmpeg path from a variable + # ie: + # export SCRYPTED_FFMPEG_PATH=/usr/local/bin/ffmpeg + f = os.getenv('SCRYPTED_FFMPEG_PATH') + if f and Path(f).exists(): + return f + return await self.mediaManager.getFFmpegPath() - async def getFilesPath(self) -> str: - return await self.mediaManager.getFilesPath() + async def get_files_path(self): + # Get the value of the SCRYPTED_PLUGIN_VOLUME environment variable + files_path = os.getenv('SCRYPTED_PLUGIN_VOLUME') + if not files_path: + raise ValueError('SCRYPTED_PLUGIN_VOLUME env variable not set?') + + # Construct the path for the 'files' directory + ret = Path(files_path) / 'files' + + # Ensure the directory exists + await asyncio.to_thread(ret.mkdir, parents=True, exist_ok=True) + + # Return the constructed directory path as a string + return str(ret) class DeviceState(scrypted_python.scrypted_sdk.types.DeviceState): diff --git a/server/src/plugin/ffmpeg-path.ts b/server/src/plugin/ffmpeg-path.ts new file mode 100644 index 000000000..224e2ead9 --- /dev/null +++ b/server/src/plugin/ffmpeg-path.ts @@ -0,0 +1,25 @@ +import { getFfmpegPath } from '@scrypted/ffmpeg-static'; +import fs from 'fs'; +import os from 'os'; + +export async function getScryptedFFmpegPath(): Promise { + // try to get the ffmpeg path as a value of another variable + // ie, in docker builds: + // export SCRYPTED_FFMPEG_PATH_ENV_VARIABLE=SCRYPTED_RASPBIAN_FFMPEG_PATH + const v = process.env.SCRYPTED_FFMPEG_PATH_ENV_VARIABLE; + if (v) { + const f = process.env[v]; + if (f && fs.existsSync(f)) + return f; + } + + // try to get the ffmpeg path from a variable + // ie: + // export SCRYPTED_FFMPEG_PATH=/usr/local/bin/ffmpeg + const f = process.env.SCRYPTED_FFMPEG_PATH; + if (f && fs.existsSync(f)) + return f; + + const defaultPath = os.platform() === 'win32' ? 'ffmpeg.exe' : 'ffmpeg'; + return getFfmpegPath() || defaultPath; +} diff --git a/server/src/plugin/media.ts b/server/src/plugin/media.ts index 2ea92f800..d80bf831c 100644 --- a/server/src/plugin/media.ts +++ b/server/src/plugin/media.ts @@ -1,12 +1,11 @@ -import { getFfmpegPath } from '@scrypted/ffmpeg-static'; import { BufferConverter, DeviceManager, FFmpegInput, MediaConverter, MediaManager, MediaObjectCreateOptions, MediaObject as MediaObjectInterface, MediaStreamUrl, ScryptedDevice, ScryptedInterface, ScryptedInterfaceProperty, ScryptedMimeTypes, ScryptedNativeId, SystemDeviceState, SystemManager } from "@scrypted/types"; import fs from 'fs'; import https from 'https'; import Graph from 'node-dijkstra'; -import os from 'os'; import path from 'path'; import send from 'send'; import MimeType from 'whatwg-mimetype'; +import { getScryptedFFmpegPath } from './ffmpeg-path'; import { MediaObject } from "./mediaobject"; import { MediaObjectRemote } from "./plugin-api"; @@ -174,25 +173,7 @@ export abstract class MediaManagerBase implements MediaManager { abstract getMixinConsole(mixinId: string, nativeId: ScryptedNativeId): Console; async getFFmpegPath(): Promise { - // try to get the ffmpeg path as a value of another variable - // ie, in docker builds: - // export SCRYPTED_FFMPEG_PATH_ENV_VARIABLE=SCRYPTED_RASPBIAN_FFMPEG_PATH - const v = process.env.SCRYPTED_FFMPEG_PATH_ENV_VARIABLE; - if (v) { - const f = process.env[v]; - if (f && fs.existsSync(f)) - return f; - } - - // try to get the ffmpeg path from a variable - // ie: - // export SCRYPTED_FFMPEG_PATH=/usr/local/bin/ffmpeg - const f = process.env.SCRYPTED_FFMPEG_PATH; - if (f && fs.existsSync(f)) - return f; - - const defaultPath = os.platform() === 'win32' ? 'ffmpeg.exe' : 'ffmpeg'; - return getFfmpegPath() || defaultPath; + return getScryptedFFmpegPath(); } async getFilesPath(): Promise { diff --git a/server/src/scrypted-cluster-main.ts b/server/src/scrypted-cluster-main.ts index 3f3bdaf98..fb50c510e 100644 --- a/server/src/scrypted-cluster-main.ts +++ b/server/src/scrypted-cluster-main.ts @@ -23,6 +23,7 @@ import { EnvControl } from './services/env'; import { Info } from './services/info'; import { ServiceControl } from './services/service-control'; import { sleep } from './sleep'; +import { getScryptedFFmpegPath } from './plugin/ffmpeg-path'; installSourceMapSupport({ environment: 'node', @@ -143,6 +144,7 @@ function createClusterForkParam(mainFilename: string, clusterId: string, cluster ...runtimeWorkerOptions.env, SCRYPTED_VOLUME: volume, SCRYPTED_PLUGIN_VOLUME: pluginVolume, + SCRYPTED_FFMPEG_PATH: process.env.SCRYPTED_FFMPEG_PATH || await getScryptedFFmpegPath(), }; runtimeWorker = rt(mainFilename, runtimeWorkerOptions, undefined);