Files
immich/web/src/lib/components/admin-page/settings/ffmpeg/ffmpeg-settings.svelte
Zack Pollard 4e0fe27de3 feat(server): transcoding improvements (#1370)
* feat: support isEdited flag for SettingSwitch

* feat: add transcodeAll ffmpeg settings for extra transcoding control

* refactor: tidy up and rename current video transcoding code + transcode everything

* feat: better video transcoding with ffprobe

analyses video files to see if they are already in the desired format
allows admin to choose to transcode all videos regardless of the current format

* fix: always serve encoded video if it exists

* feat: change video codec option to a select box, limit options

removed previous video codec config option as it's incompatible with new options
removed mapping for encoder to codec as we now store the codec in the config

* feat: add video conversion job for transcoding previously missed videos

* chore: fix spelling of job messages to pluralise assets

* chore: fix prettier/eslint warnings

* feat: force switch targetAudioCodec default to aac to avoid iOS incompatibility

* chore: lint issues after rebase
2023-01-21 20:09:02 -06:00

140 lines
4.0 KiB
Svelte

<script lang="ts">
import {
notificationController,
NotificationType
} from '$lib/components/shared-components/notification/notification';
import { api, SystemConfigFFmpegDto } from '@api';
import SettingButtonsRow from '../setting-buttons-row.svelte';
import SettingInputField, { SettingInputFieldType } from '../setting-input-field.svelte';
import SettingSelect from '../setting-select.svelte';
import SettingSwitch from '../setting-switch.svelte';
import _ from 'lodash';
import { fade } from 'svelte/transition';
export let ffmpegConfig: SystemConfigFFmpegDto; // this is the config that is being edited
let savedConfig: SystemConfigFFmpegDto;
let defaultConfig: SystemConfigFFmpegDto;
async function getConfigs() {
[savedConfig, defaultConfig] = await Promise.all([
api.systemConfigApi.getConfig().then((res) => res.data.ffmpeg),
api.systemConfigApi.getDefaults().then((res) => res.data.ffmpeg)
]);
}
async function saveSetting() {
try {
const { data: configs } = await api.systemConfigApi.getConfig();
const result = await api.systemConfigApi.updateConfig({
...configs,
ffmpeg: ffmpegConfig
});
ffmpegConfig = { ...result.data.ffmpeg };
savedConfig = { ...result.data.ffmpeg };
notificationController.show({
message: 'FFmpeg settings saved',
type: NotificationType.Info
});
} catch (e) {
console.error('Error [ffmpeg-settings] [saveSetting]', e);
notificationController.show({
message: 'Unable to save settings',
type: NotificationType.Error
});
}
}
async function reset() {
const { data: resetConfig } = await api.systemConfigApi.getConfig();
ffmpegConfig = { ...resetConfig.ffmpeg };
savedConfig = { ...resetConfig.ffmpeg };
notificationController.show({
message: 'Reset FFmpeg settings to the recent saved settings',
type: NotificationType.Info
});
}
async function resetToDefault() {
const { data: configs } = await api.systemConfigApi.getDefaults();
ffmpegConfig = { ...configs.ffmpeg };
defaultConfig = { ...configs.ffmpeg };
notificationController.show({
message: 'Reset FFmpeg settings to default',
type: NotificationType.Info
});
}
</script>
<div>
{#await getConfigs() then}
<div in:fade={{ duration: 500 }}>
<form autocomplete="off" on:submit|preventDefault>
<div class="flex flex-col gap-4 ml-4 mt-4">
<SettingInputField
inputType={SettingInputFieldType.NUMBER}
label="CONSTANT RATE FACTOR (-crf)"
bind:value={ffmpegConfig.crf}
required={true}
isEdited={!(ffmpegConfig.crf == savedConfig.crf)}
/>
<SettingInputField
inputType={SettingInputFieldType.TEXT}
label="PRESET (-preset)"
bind:value={ffmpegConfig.preset}
required={true}
isEdited={!(ffmpegConfig.preset == savedConfig.preset)}
/>
<SettingInputField
inputType={SettingInputFieldType.TEXT}
label="AUDIO CODEC (-acodec)"
bind:value={ffmpegConfig.targetAudioCodec}
required={true}
isEdited={!(ffmpegConfig.targetAudioCodec == savedConfig.targetAudioCodec)}
/>
<SettingSelect
label="VIDEO CODEC (-vcodec)"
bind:value={ffmpegConfig.targetVideoCodec}
options={['h264', 'hevc', 'vp9']}
isEdited={!(ffmpegConfig.targetVideoCodec == savedConfig.targetVideoCodec)}
/>
<SettingInputField
inputType={SettingInputFieldType.TEXT}
label="SCALING (-vf scale=)"
bind:value={ffmpegConfig.targetScaling}
required={true}
isEdited={!(ffmpegConfig.targetScaling == savedConfig.targetScaling)}
/>
<SettingSwitch
title="TRANSCODE ALL"
subtitle="Transcode all files, even if they already match the specified format?"
bind:checked={ffmpegConfig.transcodeAll}
isEdited={!(ffmpegConfig.transcodeAll == savedConfig.transcodeAll)}
/>
</div>
<div class="ml-4">
<SettingButtonsRow
on:reset={reset}
on:save={saveSetting}
on:reset-to-default={resetToDefault}
showResetToDefault={!_.isEqual(savedConfig, defaultConfig)}
/>
</div>
</form>
</div>
{/await}
</div>