working dyn video duration
This commit is contained in:
parent
e2a3eeaf43
commit
69620d806d
@ -162,5 +162,12 @@ jQuery(document).ready(function ($) {
|
|||||||
|
|
||||||
showToast(l.js_common_copied);
|
showToast(l.js_common_copied);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Weird fix for toggle in modals
|
||||||
|
$(document).on('click', '.modal .toggle label', function (e) {
|
||||||
|
const $toggle = $(this).parents('.toggle:eq(0)');
|
||||||
|
const $checkbox = $toggle.find('input[type=checkbox]');
|
||||||
|
$checkbox.prop('checked', !$checkbox.prop('checked'));
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@ -98,7 +98,7 @@ jQuery(document).ready(function ($) {
|
|||||||
$datetimepickerStart.toggleClass('hidden', !isDatetimeStart);
|
$datetimepickerStart.toggleClass('hidden', !isDatetimeStart);
|
||||||
$datetimepickerEnd.toggleClass('hidden', !isDatetimeEnd);
|
$datetimepickerEnd.toggleClass('hidden', !isDatetimeEnd);
|
||||||
|
|
||||||
$durationGroup.toggleClass('hidden', isNotification && isDatetimeEnd);
|
$durationGroup.toggleClass('hidden', (isNotification && isDatetimeEnd) || parseInt($targetDuration.val()) === auto_duration_cheatcode);
|
||||||
$scheduleEndGroup.toggleClass('hidden', isLoopStart);
|
$scheduleEndGroup.toggleClass('hidden', isLoopStart);
|
||||||
|
|
||||||
$durationGroup.find('.widget input').prop('required', $durationGroup.is(':visible'));
|
$durationGroup.find('.widget input').prop('required', $durationGroup.is(':visible'));
|
||||||
@ -125,6 +125,18 @@ jQuery(document).ready(function ($) {
|
|||||||
flushValues();
|
flushValues();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const inputAutoDurationUpdate = function (enableAutoDuration) {
|
||||||
|
const $modal = $('.modal-slide:visible');
|
||||||
|
const $input = $modal.find('.slide-auto-duration');
|
||||||
|
const $durationGroup = $modal.find('.slide-duration-group');
|
||||||
|
const $durationInput = $durationGroup.find('input');
|
||||||
|
const $autoDurationGroup = $modal.find('.slide-auto-duration-group');
|
||||||
|
const activeAutoDuration = $input.prop('checked');
|
||||||
|
|
||||||
|
$durationGroup.toggleClass('hidden', enableAutoDuration && activeAutoDuration);
|
||||||
|
$autoDurationGroup.toggleClass('hidden', !enableAutoDuration);
|
||||||
|
$durationInput.val(enableAutoDuration && activeAutoDuration ? auto_duration_cheatcode : 3);
|
||||||
|
};
|
||||||
|
|
||||||
const main = function () {
|
const main = function () {
|
||||||
$("ul.slides").sortable({
|
$("ul.slides").sortable({
|
||||||
@ -147,7 +159,7 @@ jQuery(document).ready(function ($) {
|
|||||||
|
|
||||||
$(document).on('click', '.content-explr-picker', function () {
|
$(document).on('click', '.content-explr-picker', function () {
|
||||||
showPickers('modal-content-explr-picker', function (content) {
|
showPickers('modal-content-explr-picker', function (content) {
|
||||||
inputContentUpdate(content)
|
inputContentUpdate(content);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -157,8 +169,11 @@ jQuery(document).ready(function ($) {
|
|||||||
const $inputLabel = $group.find('.target-label');
|
const $inputLabel = $group.find('.target-label');
|
||||||
const $inputId = $group.find('.target');
|
const $inputId = $group.find('.target');
|
||||||
const $actionShow = $group.find('.slide-content-show');
|
const $actionShow = $group.find('.slide-content-show');
|
||||||
|
const invalidContent = content === undefined || !content.id;
|
||||||
|
|
||||||
if (content === undefined || !content.id) {
|
inputAutoDurationUpdate(!invalidContent && content.type === 'video');
|
||||||
|
|
||||||
|
if (invalidContent) {
|
||||||
$inputLabel.val('');
|
$inputLabel.val('');
|
||||||
$inputId.val('');
|
$inputId.val('');
|
||||||
$actionShow.addClass('hidden');
|
$actionShow.addClass('hidden');
|
||||||
@ -170,6 +185,10 @@ jQuery(document).ready(function ($) {
|
|||||||
$actionShow.removeClass('hidden');
|
$actionShow.removeClass('hidden');
|
||||||
};
|
};
|
||||||
|
|
||||||
|
$(document).on('change', '.slide-auto-duration', function () {
|
||||||
|
inputAutoDurationUpdate(true);
|
||||||
|
});
|
||||||
|
|
||||||
$(document).on('click', '.slide-content-show', function () {
|
$(document).on('click', '.slide-content-show', function () {
|
||||||
window.open($(this).attr('data-route').replace('__id__', $(this).parents('.widget:eq(0)').find('.target').val()));
|
window.open($(this).attr('data-route').replace('__id__', $(this).parents('.widget:eq(0)').find('.target').val()));
|
||||||
});
|
});
|
||||||
@ -186,6 +205,9 @@ jQuery(document).ready(function ($) {
|
|||||||
const hasDateTimeEnd = hasCronEnd && validateCronDateTime(slide.cron_schedule_end);
|
const hasDateTimeEnd = hasCronEnd && validateCronDateTime(slide.cron_schedule_end);
|
||||||
const isNotification = slide.is_notification;
|
const isNotification = slide.is_notification;
|
||||||
|
|
||||||
|
|
||||||
|
$modal.find('#slide-edit-auto-duration').prop('checked', slide.duration === auto_duration_cheatcode);
|
||||||
|
|
||||||
inputContentUpdate(slide.content);
|
inputContentUpdate(slide.content);
|
||||||
|
|
||||||
$modal.find('input[type=text]:visible:eq(0)').focus().select();
|
$modal.find('input[type=text]:visible:eq(0)').focus().select();
|
||||||
|
|||||||
@ -33,6 +33,7 @@
|
|||||||
"slideshow_slide_form_section_scheduling": "Scheduling",
|
"slideshow_slide_form_section_scheduling": "Scheduling",
|
||||||
"slideshow_slide_form_label_name": "Name",
|
"slideshow_slide_form_label_name": "Name",
|
||||||
"slideshow_slide_form_label_enabled": "Enable/Disable",
|
"slideshow_slide_form_label_enabled": "Enable/Disable",
|
||||||
|
"slideshow_slide_form_label_auto_duration": "Use video's duration as timer",
|
||||||
"slideshow_slide_form_label_add_content": "Upload to library",
|
"slideshow_slide_form_label_add_content": "Upload to library",
|
||||||
"slideshow_slide_form_label_from_library": "From library",
|
"slideshow_slide_form_label_from_library": "From library",
|
||||||
"slideshow_slide_form_label_content_id": "Content",
|
"slideshow_slide_form_label_content_id": "Content",
|
||||||
|
|||||||
@ -34,6 +34,7 @@
|
|||||||
"slideshow_slide_form_label_name": "Nombre",
|
"slideshow_slide_form_label_name": "Nombre",
|
||||||
"slideshow_slide_form_label_add_content": "Upload a la biblioteca",
|
"slideshow_slide_form_label_add_content": "Upload a la biblioteca",
|
||||||
"slideshow_slide_form_label_enabled": "Activar/Desactivar",
|
"slideshow_slide_form_label_enabled": "Activar/Desactivar",
|
||||||
|
"slideshow_slide_form_label_auto_duration": "Utilizar la duración del vídeo",
|
||||||
"slideshow_slide_form_label_from_library": "Dalla biblioteca",
|
"slideshow_slide_form_label_from_library": "Dalla biblioteca",
|
||||||
"slideshow_slide_form_label_content_id": "Contenido",
|
"slideshow_slide_form_label_content_id": "Contenido",
|
||||||
"slideshow_slide_form_label_location": "Ubicación",
|
"slideshow_slide_form_label_location": "Ubicación",
|
||||||
|
|||||||
@ -33,6 +33,7 @@
|
|||||||
"slideshow_slide_form_section_scheduling": "Programmation",
|
"slideshow_slide_form_section_scheduling": "Programmation",
|
||||||
"slideshow_slide_form_label_name": "Nom",
|
"slideshow_slide_form_label_name": "Nom",
|
||||||
"slideshow_slide_form_label_enabled": "Activer/Désactiver",
|
"slideshow_slide_form_label_enabled": "Activer/Désactiver",
|
||||||
|
"slideshow_slide_form_label_auto_duration": "Utiliser la durée de la vidéo",
|
||||||
"slideshow_slide_form_label_add_content": "Upload à la bibliothèque",
|
"slideshow_slide_form_label_add_content": "Upload à la bibliothèque",
|
||||||
"slideshow_slide_form_label_from_library": "Depuis la bibliothèque",
|
"slideshow_slide_form_label_from_library": "Depuis la bibliothèque",
|
||||||
"slideshow_slide_form_label_content_id": "Contenu",
|
"slideshow_slide_form_label_content_id": "Contenu",
|
||||||
|
|||||||
@ -33,6 +33,7 @@
|
|||||||
"slideshow_slide_form_section_scheduling": "Programmazione",
|
"slideshow_slide_form_section_scheduling": "Programmazione",
|
||||||
"slideshow_slide_form_label_name": "Nome",
|
"slideshow_slide_form_label_name": "Nome",
|
||||||
"slideshow_slide_form_label_enabled": "Abilita/Disabilita",
|
"slideshow_slide_form_label_enabled": "Abilita/Disabilita",
|
||||||
|
"slideshow_slide_form_label_auto_duration": "Utilizza la durata del video",
|
||||||
"slideshow_slide_form_label_add_content": "Upload alla biblioteca",
|
"slideshow_slide_form_label_add_content": "Upload alla biblioteca",
|
||||||
"slideshow_slide_form_label_from_library": "Dalla biblioteca",
|
"slideshow_slide_form_label_from_library": "Dalla biblioteca",
|
||||||
"slideshow_slide_form_label_content_id": "Contenuti",
|
"slideshow_slide_form_label_content_id": "Contenuti",
|
||||||
|
|||||||
@ -8,7 +8,7 @@ from flask import Flask, render_template, redirect, request, url_for, send_from_
|
|||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
from src.model.entity.Slide import Slide
|
from src.model.entity.Slide import Slide
|
||||||
from src.model.enum.ContentType import ContentType
|
from src.model.enum.ContentType import ContentType, AUTO_DURATION_CHEATCODE
|
||||||
from src.exceptions.NoFallbackPlaylistException import NoFallbackPlaylistException
|
from src.exceptions.NoFallbackPlaylistException import NoFallbackPlaylistException
|
||||||
from src.service.ModelStore import ModelStore
|
from src.service.ModelStore import ModelStore
|
||||||
from src.interface.ObController import ObController
|
from src.interface.ObController import ObController
|
||||||
@ -60,7 +60,8 @@ class PlayerController(ObController):
|
|||||||
slide_animation_enabled=animation_enabled,
|
slide_animation_enabled=animation_enabled,
|
||||||
slide_animation_entrance_effect=slide_animation_entrance_effect,
|
slide_animation_entrance_effect=slide_animation_entrance_effect,
|
||||||
slide_animation_speed=slide_animation_speed,
|
slide_animation_speed=slide_animation_speed,
|
||||||
animation_speed_duration=animation_speed_duration
|
animation_speed_duration=animation_speed_duration,
|
||||||
|
auto_duration_cheatcode=AUTO_DURATION_CHEATCODE
|
||||||
)
|
)
|
||||||
|
|
||||||
def player_default(self):
|
def player_default(self):
|
||||||
@ -167,8 +168,6 @@ class PlayerController(ObController):
|
|||||||
'hard_refresh_request': self._model_store.variable().get_one_by_name("refresh_player_request").as_int()
|
'hard_refresh_request': self._model_store.variable().get_one_by_name("refresh_player_request").as_int()
|
||||||
}
|
}
|
||||||
|
|
||||||
logging.info(playlists['loop'])
|
|
||||||
|
|
||||||
return playlists
|
return playlists
|
||||||
|
|
||||||
def _check_slide_enablement(self, loop: List, notifications: List, slide: Dict) -> None:
|
def _check_slide_enablement(self, loop: List, notifications: List, slide: Dict) -> None:
|
||||||
|
|||||||
@ -4,7 +4,7 @@ from flask import Flask, render_template, redirect, request, url_for, jsonify, a
|
|||||||
from src.service.ModelStore import ModelStore
|
from src.service.ModelStore import ModelStore
|
||||||
from src.model.entity.Playlist import Playlist
|
from src.model.entity.Playlist import Playlist
|
||||||
from src.model.enum.FolderEntity import FolderEntity
|
from src.model.enum.FolderEntity import FolderEntity
|
||||||
from src.model.enum.ContentType import ContentType
|
from src.model.enum.ContentType import ContentType, AUTO_DURATION_CHEATCODE
|
||||||
from src.interface.ObController import ObController
|
from src.interface.ObController import ObController
|
||||||
|
|
||||||
|
|
||||||
@ -49,6 +49,7 @@ class PlaylistController(ObController):
|
|||||||
folders_tree=self._model_store.folder().get_folder_tree(FolderEntity.CONTENT),
|
folders_tree=self._model_store.folder().get_folder_tree(FolderEntity.CONTENT),
|
||||||
enum_content_type=ContentType,
|
enum_content_type=ContentType,
|
||||||
enum_folder_entity=FolderEntity,
|
enum_folder_entity=FolderEntity,
|
||||||
|
auto_duration_cheatcode=AUTO_DURATION_CHEATCODE,
|
||||||
)
|
)
|
||||||
|
|
||||||
def playlist_add(self):
|
def playlist_add(self):
|
||||||
|
|||||||
@ -5,6 +5,8 @@ from typing import Union, List, Optional
|
|||||||
|
|
||||||
from src.util.utils import str_to_enum
|
from src.util.utils import str_to_enum
|
||||||
|
|
||||||
|
AUTO_DURATION_CHEATCODE = 98769876
|
||||||
|
|
||||||
|
|
||||||
class ContentInputType(Enum):
|
class ContentInputType(Enum):
|
||||||
|
|
||||||
|
|||||||
@ -75,6 +75,7 @@
|
|||||||
let clockValue = 0;
|
let clockValue = 0;
|
||||||
let curItemIndex = -1;
|
let curItemIndex = -1;
|
||||||
let secondsBeforeNext = 0;
|
let secondsBeforeNext = 0;
|
||||||
|
const durationsOverride = {};
|
||||||
const introSlide = document.getElementById('IntroSlide');
|
const introSlide = document.getElementById('IntroSlide');
|
||||||
const notificationSlide = document.getElementById('NotificationSlide');
|
const notificationSlide = document.getElementById('NotificationSlide');
|
||||||
const firstSlide = document.getElementById('FirstSlide');
|
const firstSlide = document.getElementById('FirstSlide');
|
||||||
@ -157,6 +158,10 @@
|
|||||||
pause();
|
pause();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const isDurationAuto = function(duration) {
|
||||||
|
return duration === {{ auto_duration_cheatcode }};
|
||||||
|
} ;
|
||||||
|
|
||||||
const lookupPreviousItem = function() {
|
const lookupPreviousItem = function() {
|
||||||
return (curItemIndex - 1 < 0) ? items.loop[items.loop.length - 1] : items.loop[curItemIndex - 1];
|
return (curItemIndex - 1 < 0) ? items.loop[items.loop.length - 1] : items.loop[curItemIndex - 1];
|
||||||
};
|
};
|
||||||
@ -191,7 +196,14 @@
|
|||||||
if (!item) {
|
if (!item) {
|
||||||
return tickRefreshResolutionMs/1000;
|
return tickRefreshResolutionMs/1000;
|
||||||
}
|
}
|
||||||
return item.duration + Math.ceil(animation_speed_duration/1000);
|
|
||||||
|
let duration = item.duration;
|
||||||
|
|
||||||
|
if (durationsOverride[item.id]) {
|
||||||
|
duration = durationsOverride[item.id];
|
||||||
|
}
|
||||||
|
|
||||||
|
return duration + Math.ceil(animation_speed_duration/1000);
|
||||||
};
|
};
|
||||||
|
|
||||||
const main = function() {
|
const main = function() {
|
||||||
@ -363,7 +375,8 @@
|
|||||||
delayNoisyContentJIT = lookupCurrentItem().id !== item.id ? delayNoisyContentJIT : 0;
|
delayNoisyContentJIT = lookupCurrentItem().id !== item.id ? delayNoisyContentJIT : 0;
|
||||||
|
|
||||||
video.addEventListener('loadedmetadata', function() {
|
video.addEventListener('loadedmetadata', function() {
|
||||||
if (item.duration !== video.duration) {
|
if (item.duration !== video.duration && isDurationAuto(item.duration)) {
|
||||||
|
durationsOverride[item.id] = video.duration;
|
||||||
console.warn('Given duration ' + item.duration + 's is different from video file ' + Math.ceil(video.duration) + 's');
|
console.warn('Given duration ' + item.duration + 's is different from video file ' + Math.ceil(video.duration) + 's');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@ -13,6 +13,7 @@
|
|||||||
{% block add_js %}
|
{% block add_js %}
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
|
|
||||||
|
var auto_duration_cheatcode = {{ auto_duration_cheatcode }};
|
||||||
var route_slide_position = '{{ url_for('slideshow_slide_position') }}';
|
var route_slide_position = '{{ url_for('slideshow_slide_position') }}';
|
||||||
|
|
||||||
var choices_translations = {
|
var choices_translations = {
|
||||||
|
|||||||
@ -81,6 +81,24 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group form-group-horizontal slide-auto-duration-group">
|
||||||
|
<label for="">{{ l.slideshow_slide_form_label_auto_duration }}</label>
|
||||||
|
<div class="widget">
|
||||||
|
<div class="toggle">
|
||||||
|
<input type="checkbox" class="slide-auto-duration" id="slide-add-auto-duration" />
|
||||||
|
<label for="slide-add-auto-duration"></label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group slide-duration-group">
|
||||||
|
<label for="slide-add-duration">{{ l.slideshow_slide_form_label_duration }}</label>
|
||||||
|
<div class="widget widget-unit">
|
||||||
|
<input type="number" name="duration" id="slide-add-duration" required="required" value="3" />
|
||||||
|
<span class="unit">{{ l.slideshow_slide_form_label_duration_unit }}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="actions">
|
<div class="actions">
|
||||||
<button type="button" class="btn btn-naked modal-close">
|
<button type="button" class="btn btn-naked modal-close">
|
||||||
{{ l.common_close }}
|
{{ l.common_close }}
|
||||||
|
|||||||
@ -72,6 +72,16 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group form-group-horizontal slide-auto-duration-group">
|
||||||
|
<label for="">{{ l.slideshow_slide_form_label_auto_duration }}</label>
|
||||||
|
<div class="widget">
|
||||||
|
<div class="toggle">
|
||||||
|
<input type="checkbox" class="slide-auto-duration" id="slide-edit-auto-duration" />
|
||||||
|
<label for="slide-edit-auto-duration"></label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="form-group slide-duration-group">
|
<div class="form-group slide-duration-group">
|
||||||
<label for="slide-edit-duration">{{ l.slideshow_slide_form_label_duration }}</label>
|
<label for="slide-edit-duration">{{ l.slideshow_slide_form_label_duration }}</label>
|
||||||
<div class="widget widget-unit">
|
<div class="widget widget-unit">
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user