forensic-pathways/src/utils/remarkVideoPlugin.ts
overcuriousity d1c297189d cleanup
2025-08-12 22:34:11 +02:00

85 lines
3.0 KiB
TypeScript

// src/utils/remarkVideoPlugin.ts
import { visit } from 'unist-util-visit';
import type { Plugin } from 'unified';
import type { Root } from 'hast';
export const remarkVideoPlugin: Plugin<[], Root> = () => {
return (tree: Root) => {
visit(tree, 'html', (node: any, index: number | undefined, parent: any) => {
if (node.value && node.value.includes('<video') && typeof index === 'number') {
const srcMatch = node.value.match(/src=["']([^"']+)["']/);
const titleMatch = node.value.match(/title=["']([^"']+)["']/);
if (srcMatch) {
const originalSrc = srcMatch[1];
const title = titleMatch?.[1] || 'Video';
const finalSrc = processNextcloudUrl(originalSrc);
const hasControls = node.value.includes('controls');
const hasAutoplay = node.value.includes('autoplay');
const hasMuted = node.value.includes('muted');
const hasLoop = node.value.includes('loop');
const hasPreload = node.value.match(/preload=["']([^"']+)["']/);
const enhancedHTML = `
<div class="video-container aspect-16-9">
<video
src="${escapeHtml(finalSrc)}"
${hasControls ? 'controls' : ''}
${hasAutoplay ? 'autoplay' : ''}
${hasMuted ? 'muted' : ''}
${hasLoop ? 'loop' : ''}
${hasPreload ? `preload="${hasPreload[1]}"` : 'preload="metadata"'}
style="width: 100%; height: 100%;"
data-video-title="${escapeHtml(title)}"
data-original-src="${escapeHtml(originalSrc)}"
>
<p>Your browser does not support the video element.</p>
</video>
${title !== 'Video' ? `
<div class="video-metadata">
<div class="video-title">${escapeHtml(title)}</div>
</div>
` : ''}
</div>
`.trim();
parent.children[index] = { type: 'html', value: enhancedHTML };
console.log(`[VIDEO] Processed: ${title}`);
console.log(`[VIDEO] Final URL: ${finalSrc}`);
}
}
});
};
};
function processNextcloudUrl(originalUrl: string): string {
if (isNextcloudShareUrl(originalUrl) && !originalUrl.includes('/download')) {
const downloadUrl = `${originalUrl}/download`;
console.log(`[VIDEO] Auto-added /download: ${originalUrl}${downloadUrl}`);
return downloadUrl;
}
return originalUrl;
}
function isNextcloudShareUrl(url: string): boolean {
const pattern = /\/s\/[a-zA-Z0-9]+/;
return pattern.test(url) && (url.includes('nextcloud') || url.includes('cloud.'));
}
function escapeHtml(unsafe: string): string {
if (typeof unsafe !== 'string') return '';
return unsafe
.replace(/&/g, "&amp;")
.replace(/</g, "&lt;")
.replace(/>/g, "&gt;")
.replace(/"/g, "&quot;")
.replace(/'/g, "&#039;");
}