refactor(server): move video interface fetch to storage core (#28248)

This commit is contained in:
Mert
2026-05-06 09:32:03 -04:00
committed by GitHub
parent 576b1eb999
commit c5c59ed040
2 changed files with 31 additions and 25 deletions
+28
View File
@@ -18,6 +18,7 @@ import { MoveRepository } from 'src/repositories/move.repository';
import { PersonRepository } from 'src/repositories/person.repository';
import { StorageRepository } from 'src/repositories/storage.repository';
import { SystemMetadataRepository } from 'src/repositories/system-metadata.repository';
import { VideoInterfaces } from 'src/types';
import { getAssetFile } from 'src/utils/asset.util';
import { getConfig } from 'src/utils/config';
@@ -299,6 +300,11 @@ export class StorageCore {
return this.storageRepository.removeEmptyDirs(StorageCore.getBaseFolder(folder));
}
async getVideoInterfaces(): Promise<VideoInterfaces> {
const [dri, mali] = await Promise.all([this.getDevices(), this.hasMaliOpenCL()]);
return { dri, mali };
}
private savePath(pathType: PathType, id: string, newPath: string) {
switch (pathType) {
case AssetPathType.Original: {
@@ -330,4 +336,26 @@ export class StorageCore {
static getTempPathInDir(dir: string): string {
return join(dir, `${randomUUID()}.tmp`);
}
private async getDevices() {
try {
return await this.storageRepository.readdir('/dev/dri');
} catch {
this.logger.debug('No devices found in /dev/dri.');
return [];
}
}
private async hasMaliOpenCL() {
try {
const [maliIcdStat, maliDeviceStat] = await Promise.all([
this.storageRepository.stat('/etc/OpenCL/vendors/mali.icd'),
this.storageRepository.stat('/dev/mali0'),
]);
return maliIcdStat.isFile() && maliDeviceStat.isCharacterDevice();
} catch {
this.logger.debug('OpenCL not available for transcoding, so RKMPP acceleration will use CPU tonemapping');
return false;
}
}
}
+3 -25
View File
@@ -13,6 +13,7 @@ import {
AudioCodec,
Colorspace,
ImageFormat,
ImmichWorker,
JobName,
JobStatus,
QueueName,
@@ -60,10 +61,9 @@ type ThumbnailAsset = NonNullable<Awaited<ReturnType<AssetJobRepository['getForG
export class MediaService extends BaseService {
videoInterfaces: VideoInterfaces = { dri: [], mali: false };
@OnEvent({ name: 'AppBootstrap' })
@OnEvent({ name: 'AppBootstrap', workers: [ImmichWorker.Microservices] })
async onBootstrap() {
const [dri, mali] = await Promise.all([this.getDevices(), this.hasMaliOpenCL()]);
this.videoInterfaces = { dri, mali };
this.videoInterfaces = await this.storageCore.getVideoInterfaces();
}
@OnJob({ name: JobName.AssetGenerateThumbnailsQueueAll, queue: QueueName.ThumbnailGeneration })
@@ -789,28 +789,6 @@ export class MediaService extends BaseService {
return extractedSize >= targetSize;
}
private async getDevices() {
try {
return await this.storageRepository.readdir('/dev/dri');
} catch {
this.logger.debug('No devices found in /dev/dri.');
return [];
}
}
private async hasMaliOpenCL() {
try {
const [maliIcdStat, maliDeviceStat] = await Promise.all([
this.storageRepository.stat('/etc/OpenCL/vendors/mali.icd'),
this.storageRepository.stat('/dev/mali0'),
]);
return maliIcdStat.isFile() && maliDeviceStat.isCharacterDevice();
} catch {
this.logger.debug('OpenCL not available for transcoding, so RKMPP acceleration will use CPU tonemapping');
return false;
}
}
private async syncFiles(
oldFiles: (AssetFile & { isProgressive: boolean; isTransparent: boolean })[],
newFiles: UpsertFileOptions[],