Compare commits

..

1 Commits

Author SHA1 Message Date
mertalev
9e70f14a8a override reserved metadata 2025-09-23 20:07:51 -04:00
11 changed files with 73 additions and 15 deletions

View File

@@ -73,7 +73,7 @@ jobs:
- name: Restore Gradle Cache
id: cache-gradle-restore
uses: actions/cache/restore@0400d5f644dc74513175e3cd8d07132dd4860809 # v4.2.4
uses: actions/cache/restore@0400d5f644dc74513175e3cd8d07132dd4860809 # v4
with:
path: |
~/.gradle/caches
@@ -130,7 +130,7 @@ jobs:
- name: Save Gradle Cache
id: cache-gradle-save
uses: actions/cache/save@0400d5f644dc74513175e3cd8d07132dd4860809 # v4.2.4
uses: actions/cache/save@0400d5f644dc74513175e3cd8d07132dd4860809 # v4
if: github.ref == 'refs/heads/main'
with:
path: |

View File

@@ -1,5 +1,5 @@
allprojects {
ext.kotlin_version = '2.2.20'
ext.kotlin_version = '2.0.20'
repositories {
google()
@@ -16,8 +16,8 @@ subprojects {
if (project.plugins.hasPlugin("com.android.application") ||
project.plugins.hasPlugin("com.android.library")) {
project.android {
compileSdkVersion 36
buildToolsVersion "36.0.0"
compileSdkVersion 35
buildToolsVersion "35.0.0"
}
}
}

View File

@@ -1,6 +1,6 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.13-all.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.9-all.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME

View File

@@ -18,10 +18,10 @@ pluginManagement {
plugins {
id "dev.flutter.flutter-plugin-loader" version "1.0.0"
id "com.android.application" version '8.11.2' apply false
id "org.jetbrains.kotlin.android" version "2.2.20" apply false
id "com.android.application" version '8.7.2' apply false
id "org.jetbrains.kotlin.android" version "2.0.20" apply false
id 'org.jetbrains.kotlin.plugin.serialization' version '1.9.22' apply false
id 'com.google.devtools.ksp' version '2.2.20-2.0.3' apply false
id 'com.google.devtools.ksp' version '2.0.20-1.0.24' apply false
}
include ":app"

View File

@@ -1208,8 +1208,8 @@ packages:
dependency: "direct main"
description:
path: "."
ref: "893894b"
resolved-ref: "893894b98b832be8a995a8d5d4c2289d0ad2d246"
ref: "5459d54"
resolved-ref: "5459d54cdc1cf4d99e2193b310052f1ebb5dcf43"
url: "https://github.com/immich-app/native_video_player"
source: git
version: "1.3.1"

View File

@@ -77,7 +77,7 @@ dependencies:
native_video_player:
git:
url: https://github.com/immich-app/native_video_player
ref: '893894b'
ref: '5459d54'
openapi:
path: openapi
isar:

View File

@@ -203,6 +203,9 @@ export class MediaRepository {
isHDR: stream.color_transfer === 'smpte2084' || stream.color_transfer === 'arib-std-b67',
bitrate: this.parseInt(stream.bit_rate),
pixelFormat: stream.pix_fmt || 'yuv420p',
colorPrimaries: stream.color_primaries,
colorSpace: stream.color_space,
colorTransfer: stream.color_transfer,
})),
audioStreams: results.streams
.filter((stream) => stream.codec_type === 'audio')

View File

@@ -445,6 +445,7 @@ describe(MediaService.name, () => {
}),
);
});
it('should not skip intra frames for MTS file', async () => {
mocks.media.probe.mockResolvedValue(probeStub.videoStreamMTS);
mocks.assetJob.getForGenerateThumbnailJob.mockResolvedValue(assetStub.video);
@@ -462,6 +463,25 @@ describe(MediaService.name, () => {
);
});
it('should override reserved color metadata', async () => {
mocks.media.probe.mockResolvedValue(probeStub.videoStreamReserved);
mocks.assetJob.getForGenerateThumbnailJob.mockResolvedValue(assetStub.video);
await sut.handleGenerateThumbnails({ id: assetStub.video.id });
expect(mocks.media.transcode).toHaveBeenCalledWith(
'/original/path.ext',
expect.any(String),
expect.objectContaining({
inputOptions: expect.arrayContaining([
'-bsf:v hevc_metadata=colour_primaries=1:matrix_coefficients=1:transfer_characteristics=1',
]),
outputOptions: expect.any(Array),
progress: expect.any(Object),
twoPass: false,
}),
);
});
it('should use scaling divisible by 2 even when using quick sync', async () => {
mocks.media.probe.mockResolvedValue(probeStub.videoStream2160p);
mocks.systemMetadata.get.mockResolvedValue({ ffmpeg: { accel: TranscodeHardwareAcceleration.Qsv } });

View File

@@ -88,6 +88,9 @@ export interface VideoStreamInfo {
isHDR: boolean;
bitrate: number;
pixelFormat: string;
colorPrimaries?: string;
colorSpace?: string;
colorTransfer?: string;
}
export interface AudioStreamInfo {

View File

@@ -392,9 +392,30 @@ export class ThumbnailConfig extends BaseConfig {
getBaseInputOptions(videoStream: VideoStreamInfo, format?: VideoFormat): string[] {
// skip_frame nointra skips all frames for some MPEG-TS files. Look at ffmpeg tickets 7950 and 7895 for more details.
return format?.formatName === 'mpegts'
? ['-sws_flags accurate_rnd+full_chroma_int']
: ['-skip_frame nointra', '-sws_flags accurate_rnd+full_chroma_int'];
const options =
format?.formatName === 'mpegts'
? ['-sws_flags accurate_rnd+full_chroma_int']
: ['-skip_frame nointra', '-sws_flags accurate_rnd+full_chroma_int'];
const metadataOverrides = [];
if (videoStream.colorPrimaries === 'reserved') {
metadataOverrides.push('colour_primaries=1');
}
if (videoStream.colorSpace === 'reserved') {
metadataOverrides.push('matrix_coefficients=1');
}
if (videoStream.colorTransfer === 'reserved') {
metadataOverrides.push('transfer_characteristics=1');
}
if (metadataOverrides.length > 0) {
// workaround for https://fftrac-bg.ffmpeg.org/ticket/11020
options.push(`-bsf:v ${videoStream.codecName}_metadata=${metadataOverrides.join(':')}`);
}
return options;
}
getBaseOutputOptions() {

View File

@@ -261,4 +261,15 @@ export const probeStub = {
bitrate: 0,
},
}),
videoStreamReserved: Object.freeze<VideoInfo>({
...probeStubDefault,
videoStreams: [
{
...probeStubDefaultVideoStream[0],
colorPrimaries: 'reserved',
colorSpace: 'reserved',
colorTransfer: 'reserved',
},
],
}),
};