fix: Implement universal openVideoPreview and add Stash container/transcode stream path resolution

This commit is contained in:
david
2026-08-18 11:12:09 -04:00
parent 45cb902647
commit 8c723cfabc
2 changed files with 42 additions and 7 deletions
+37 -7
View File
@@ -5377,11 +5377,38 @@ Return ONLY a valid JSON object with an array named "results":
const btnPreviewNext = document.getElementById('btn-preview-next'); const btnPreviewNext = document.getElementById('btn-preview-next');
const previewState = { const previewState = {
activeType: 'smb', // 'smb' | 'qb' activeType: 'smb', // 'smb' | 'qb' | 'direct'
currentIndex: -1, currentIndex: -1,
currentList: [] currentList: []
}; };
function openVideoPreview(filePath, title = 'Video Preview', category = null) {
if (!filePath) {
showToast('No video path available for preview', 'error');
return;
}
previewState.activeType = 'direct';
previewState.currentIndex = 0;
previewState.currentList = [{ name: title, path: filePath, selectedPerformer: category }];
videoModal.classList.add('open');
if (videoCounter) videoCounter.textContent = '1 / 1';
if (btnPreviewPrev) btnPreviewPrev.disabled = true;
if (btnPreviewNext) btnPreviewNext.disabled = true;
const playlistBar = document.getElementById('video-playlist-bar');
if (playlistBar) playlistBar.style.display = 'none';
videoTitle.textContent = title || filePath.split('/').pop() || 'Video Preview';
const streamUrl = `/api/stream?path=${encodeURIComponent(filePath)}`;
videoElement.src = streamUrl;
videoElement.load();
videoElement.play().catch(e => console.log('Autoplay deferred:', e));
renderVideoModalPerformerControls({ name: title, path: filePath, selectedPerformer: category }, 'direct');
}
function openVideoPreviewForSmb(filePath) { function openVideoPreviewForSmb(filePath) {
const query = smbSearchInput.value.trim().toLowerCase(); const query = smbSearchInput.value.trim().toLowerCase();
const filtered = smbState.files.filter(f => { const filtered = smbState.files.filter(f => {
@@ -7888,11 +7915,14 @@ Return ONLY a valid JSON object with an array named "results":
</span> </span>
</td> </td>
<td style="text-align: right;"> <td style="text-align: right;">
<div style="display: inline-flex; gap: 0.4rem;"> <div style="display: inline-flex; gap: 0.35rem; align-items: center;">
<button class="btn btn-secondary btn-transcode-preview" data-path="${escapeHtml(item.orig_local_path)}" data-title="${escapeHtml(item.basename)}" style="padding: 0.2rem 0.5rem; font-size: 0.7rem;" title="Preview original video"> <button class="btn btn-secondary btn-transcode-preview" data-path="${escapeHtml(item.orig_local_path)}" data-title="Original: ${escapeHtml(item.basename)}" style="padding: 0.2rem 0.45rem; font-size: 0.68rem;" title="Preview original video">
🎬 Preview 🎬 Orig
</button> </button>
<button class="btn btn-success btn-transcode-replace-single" data-hash="${item.oshash}" style="padding: 0.2rem 0.6rem; font-size: 0.72rem; font-weight: 600;" title="Safely replace original with transcoded file"> <button class="btn btn-secondary btn-transcode-preview-trans" data-path="${escapeHtml(item.transcode_path)}" data-title="Transcode: ${escapeHtml(item.basename)}" style="padding: 0.2rem 0.45rem; font-size: 0.68rem; color: var(--accent-green); border-color: rgba(16,185,129,0.3);" title="Preview Stash transcoded video">
⚡ Transcode
</button>
<button class="btn btn-success btn-transcode-replace-single" data-hash="${item.oshash}" style="padding: 0.2rem 0.55rem; font-size: 0.7rem; font-weight: 600;" title="Safely replace original with transcoded file">
⚡ Replace ⚡ Replace
</button> </button>
</div> </div>
@@ -7931,8 +7961,8 @@ Return ONLY a valid JSON object with an array named "results":
}); });
}); });
// Preview listener // Preview listeners
container.querySelectorAll('.btn-transcode-preview').forEach(btn => { container.querySelectorAll('.btn-transcode-preview, .btn-transcode-preview-trans').forEach(btn => {
btn.addEventListener('click', () => { btn.addEventListener('click', () => {
const p = btn.getAttribute('data-path'); const p = btn.getAttribute('data-path');
const t = btn.getAttribute('data-title'); const t = btn.getAttribute('data-title');
+5
View File
@@ -664,6 +664,10 @@ def resolve_stream_video_path(requested_path):
stem = os.path.splitext(basename)[0] stem = os.path.splitext(basename)[0]
candidate_paths = [ candidate_paths = [
requested_path.replace('/data/', '/mnt/isolation/videos/'),
requested_path.replace('/data', '/mnt/isolation/videos'),
requested_path.replace('/media/stashapp/generated/', '/mnt/isolation/stashapp/generated/'),
requested_path.replace('/generated/', '/mnt/isolation/stashapp/generated/'),
requested_path.replace('/isolation/videos/', '/mnt/isolation/videos/'), requested_path.replace('/isolation/videos/', '/mnt/isolation/videos/'),
requested_path.replace('/isolation/', '/mnt/isolation/'), requested_path.replace('/isolation/', '/mnt/isolation/'),
requested_path.replace('/downloads/', '/mnt/isolation/videos/unsorted/'), requested_path.replace('/downloads/', '/mnt/isolation/videos/unsorted/'),
@@ -673,6 +677,7 @@ def resolve_stream_video_path(requested_path):
requested_path.replace('/downloads/', '/mnt/isolation/downloads/'), requested_path.replace('/downloads/', '/mnt/isolation/downloads/'),
os.path.join('/mnt/isolation/videos/unsorted', basename), os.path.join('/mnt/isolation/videos/unsorted', basename),
os.path.join('/mnt/isolation/videos/videodownloader', basename), os.path.join('/mnt/isolation/videos/videodownloader', basename),
os.path.join('/mnt/isolation/stashapp/generated/transcodes', basename),
os.path.join('/mnt/isolation/incomplete', basename), os.path.join('/mnt/isolation/incomplete', basename),
os.path.join('/mnt/isolation/downloads', basename) os.path.join('/mnt/isolation/downloads', basename)
] ]