Implement video region support
This commit is contained in:
@@ -61,6 +61,86 @@ function getCanvasSignature(width, height) {
|
||||
return normalizedWidth + 'x' + normalizedHeight;
|
||||
}
|
||||
|
||||
function hasVideoRegion(contentJson) {
|
||||
if (!contentJson) {
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
const parsed = typeof contentJson === 'string' ? JSON.parse(contentJson) : contentJson;
|
||||
return Boolean(parsed && typeof parsed === 'object' && Object.keys(parsed).some((key) => {
|
||||
const region = parsed[key];
|
||||
return region && typeof region === 'object' && String(region.type || '').trim().toLowerCase() === 'video';
|
||||
}));
|
||||
} catch (_error) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function getVideoSourcePath(slide) {
|
||||
if (!slide) {
|
||||
return '';
|
||||
}
|
||||
|
||||
const directMediaPath = String(slide.media_path || '').trim();
|
||||
if (String(slide.media_type || '').trim().toLowerCase() === 'video' && directMediaPath) {
|
||||
return directMediaPath;
|
||||
}
|
||||
|
||||
const contentJson = slide.content_json;
|
||||
if (!contentJson) {
|
||||
return directMediaPath;
|
||||
}
|
||||
|
||||
try {
|
||||
const parsed = typeof contentJson === 'string' ? JSON.parse(contentJson) : contentJson;
|
||||
if (!parsed || typeof parsed !== 'object') {
|
||||
return directMediaPath;
|
||||
}
|
||||
|
||||
const videoRegion = Object.keys(parsed).map((key) => parsed[key]).find((region) => {
|
||||
return region && typeof region === 'object' && String(region.type || '').trim().toLowerCase() === 'video' && String(region.value || '').trim();
|
||||
});
|
||||
|
||||
return videoRegion ? String(videoRegion.value || '').trim() : directMediaPath;
|
||||
} catch (_error) {
|
||||
return directMediaPath;
|
||||
}
|
||||
}
|
||||
|
||||
function getVideoDurationSeconds(slide) {
|
||||
if (!slide) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const contentJson = slide.content_json;
|
||||
if (!contentJson) {
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
const parsed = typeof contentJson === 'string' ? JSON.parse(contentJson) : contentJson;
|
||||
if (!parsed || typeof parsed !== 'object') {
|
||||
return null;
|
||||
}
|
||||
|
||||
const videoRegion = Object.keys(parsed).map((key) => parsed[key]).find((region) => {
|
||||
return region && typeof region === 'object' && String(region.type || '').trim().toLowerCase() === 'video' && Number(region.duration_seconds || 0) > 0;
|
||||
});
|
||||
|
||||
const duration = Math.round(Number(videoRegion && videoRegion.duration_seconds || 0) * 1000) / 1000;
|
||||
return Number.isFinite(duration) && duration > 0 ? duration : null;
|
||||
} catch (_error) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
function getVideoDurationValue(slide) {
|
||||
const storedDuration = Number(slide && slide.duration_seconds || 0);
|
||||
const videoDuration = getVideoDurationSeconds(slide);
|
||||
return Boolean(slide && slide.use_video_duration) && videoDuration ? videoDuration : storedDuration;
|
||||
}
|
||||
|
||||
module.exports = function renderPlaylistEditPage(playlist, data, message, currentUser) {
|
||||
const playlistSlides = (data.playlistSlides || [])
|
||||
.filter((item) => item.playlist_id === playlist.id)
|
||||
@@ -75,6 +155,11 @@ module.exports = function renderPlaylistEditPage(playlist, data, message, curren
|
||||
isFirst: index === 0,
|
||||
isLast: index === items.length - 1,
|
||||
canvasSignature: getCanvasSignature(item.canvas_width, item.canvas_height) || '',
|
||||
showVideoDurationButton: String(item.media_type || '').trim().toLowerCase() === 'video' || hasVideoRegion(item.content_json),
|
||||
videoSourcePath: getVideoSourcePath(item),
|
||||
videoDurationSeconds: getVideoDurationSeconds(item),
|
||||
useVideoDuration: Boolean(item.use_video_duration),
|
||||
durationSeconds: getVideoDurationValue(item),
|
||||
scheduleSummary: scheduleSummary(item)
|
||||
}));
|
||||
const assignedSlideIds = new Set(playlistSlides.map((item) => item.slide_id));
|
||||
@@ -91,7 +176,12 @@ module.exports = function renderPlaylistEditPage(playlist, data, message, curren
|
||||
return getCanvasSignature(slide.canvas_width, slide.canvas_height) === playlistCanvasSignature;
|
||||
}).map((slide) => Object.assign({}, slide, {
|
||||
canvasSignature: getCanvasSignature(slide.canvas_width, slide.canvas_height) || '',
|
||||
isAssigned: assignedSlideIds.has(slide.id)
|
||||
isAssigned: assignedSlideIds.has(slide.id),
|
||||
showVideoDurationButton: String(slide.media_type || '').trim().toLowerCase() === 'video' || hasVideoRegion(slide.content_json),
|
||||
videoSourcePath: getVideoSourcePath(slide),
|
||||
videoDurationSeconds: getVideoDurationSeconds(slide),
|
||||
useVideoDuration: Boolean(slide.use_video_duration),
|
||||
durationSeconds: getVideoDurationValue(slide)
|
||||
}));
|
||||
const hasAddableSlides = selectableSlides.some((slide) => !slide.isAssigned);
|
||||
|
||||
@@ -111,6 +201,6 @@ module.exports = function renderPlaylistEditPage(playlist, data, message, curren
|
||||
selectableSlides: selectableSlides,
|
||||
playlistCanvasSignature: playlistCanvasSignature,
|
||||
playlistCanvasMismatch: playlistCanvasMismatch,
|
||||
scripts: ['js/lib/modal.js', 'js/vendor/sortable.min.js', 'js/playlists/playlist-schedule.js']
|
||||
scripts: ['js/lib/modal.js?v=20260726.7', 'js/vendor/sortable.min.js?v=20260726.7', 'js/playlists/playlist-schedule.js?v=20260726.7']
|
||||
});
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user