You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

85 lines
2.4 KiB

import type { Slide } from 'yet-another-react-lightbox'
import type { TImetaInfo } from '@/types'
import { isAudio, isImage, isMedia, isVideo, preferBlossomPrimalDisplayUrl } from '@/lib/url'
function sourceTypeFromPath(url: string, kind: 'video' | 'audio'): string {
const path = url.split(/[?#]/)[0].toLowerCase()
if (kind === 'audio') {
if (path.endsWith('.mka')) return 'audio/x-matroska'
if (path.endsWith('.opus')) return 'audio/opus'
if (path.endsWith('.webm')) return 'audio/webm'
if (path.endsWith('.ogg')) return 'audio/ogg'
if (path.endsWith('.m4a') || path.endsWith('.aac')) return 'audio/mp4'
if (path.endsWith('.flac')) return 'audio/flac'
if (path.endsWith('.wav')) return 'audio/wav'
return 'audio/mpeg'
}
if (path.endsWith('.webm')) return 'video/webm'
if (path.endsWith('.mkv')) return 'video/x-matroska'
if (path.endsWith('.ogv')) return 'video/ogg'
if (path.endsWith('.3gp')) return 'video/3gpp'
if (path.endsWith('.3g2')) return 'video/3gpp2'
return 'video/mp4'
}
/**
* Build a Yet Another React Lightbox slide from imeta (or URL + optional MIME).
* Uses the Video plugin for video/audio URLs so the lightbox can play what we upload.
*/
export function lightboxSlideFromImeta(info: Pick<TImetaInfo, 'url' | 'alt' | 'm' | 'image'>): Slide {
const url = preferBlossomPrimalDisplayUrl(info.url)
const title = info.alt || info.url
const m = info.m?.toLowerCase()
if (m?.startsWith('image/')) {
return { src: url, alt: title, title }
}
if (m?.startsWith('video/')) {
return {
type: 'video',
title,
poster: info.image,
sources: [{ src: url, type: info.m as string }]
}
}
if (m?.startsWith('audio/')) {
return {
type: 'video',
width: 400,
height: 64,
title,
sources: [{ src: url, type: info.m as string }]
}
}
if (isVideo(url)) {
return {
type: 'video',
title,
poster: info.image,
sources: [{ src: url, type: sourceTypeFromPath(url, 'video') }]
}
}
if (isAudio(url)) {
return {
type: 'video',
width: 400,
height: 64,
title,
sources: [{ src: url, type: sourceTypeFromPath(url, 'audio') }]
}
}
if (isImage(url)) {
return { src: url, alt: title, title }
}
if (isMedia(url)) {
return {
type: 'video',
title,
poster: info.image,
sources: [{ src: url, type: 'video/mp4' }]
}
}
return { src: url, alt: title, title }
}