mirror of
https://git.shipoclu.com/moon/plspace.git
synced 2026-08-13 02:42:30 +00:00
preload a little of video to make the video show
This commit is contained in:
@@ -24,6 +24,17 @@
|
|||||||
function toggle(id: string): void {
|
function toggle(id: string): void {
|
||||||
revealed = { ...revealed, [id]: !revealed[id] }
|
revealed = { ...revealed, [id]: !revealed[id] }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ask the browser to decode the first real frame while it loads metadata.
|
||||||
|
* The tiny media-fragment seek also makes the video's intrinsic dimensions
|
||||||
|
* available before playback on browsers that otherwise leave it at 300×150.
|
||||||
|
*/
|
||||||
|
function videoPreviewUrl(url: string): string {
|
||||||
|
const fragment = url.indexOf('#')
|
||||||
|
const base = fragment >= 0 ? url.slice(0, fragment) : url
|
||||||
|
return `${base}#t=0.001`
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
{#if attachments.length > 0}
|
{#if attachments.length > 0}
|
||||||
@@ -39,12 +50,12 @@
|
|||||||
{#if media.type === 'video' || media.type === 'gifv'}
|
{#if media.type === 'video' || media.type === 'gifv'}
|
||||||
<video
|
<video
|
||||||
class="attachment-media"
|
class="attachment-media"
|
||||||
src={media.url}
|
src={videoPreviewUrl(media.url)}
|
||||||
poster={media.preview_url ?? undefined}
|
poster={media.preview_url ?? undefined}
|
||||||
controls
|
controls
|
||||||
playsinline
|
playsinline
|
||||||
loop={media.type === 'gifv'}
|
loop={media.type === 'gifv'}
|
||||||
preload="none"
|
preload="metadata"
|
||||||
>
|
>
|
||||||
<!-- Remote media carries no caption track; declared so the
|
<!-- Remote media carries no caption track; declared so the
|
||||||
requirement is explicit rather than merely unmet. -->
|
requirement is explicit rather than merely unmet. -->
|
||||||
|
|||||||
@@ -0,0 +1,42 @@
|
|||||||
|
import { render } from '@testing-library/svelte'
|
||||||
|
import { describe, expect, it } from 'vitest'
|
||||||
|
import type { MediaAttachment } from '$lib/api/types'
|
||||||
|
import Attachments from './Attachments.svelte'
|
||||||
|
|
||||||
|
function video(overrides: Partial<MediaAttachment> = {}): MediaAttachment {
|
||||||
|
return {
|
||||||
|
id: 'video-1',
|
||||||
|
type: 'video',
|
||||||
|
url: 'https://media.example.test/movie.mp4?download=1',
|
||||||
|
preview_url: 'https://media.example.test/movie-preview.jpg',
|
||||||
|
description: 'A raw video',
|
||||||
|
...overrides,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
describe('Attachments raw-video previews', () => {
|
||||||
|
it('loads metadata and seeks just past zero to expose dimensions and a first frame', () => {
|
||||||
|
const view = render(Attachments, { attachments: [video()] })
|
||||||
|
const element = view.container.querySelector('video')
|
||||||
|
|
||||||
|
expect(element).not.toBeNull()
|
||||||
|
expect(element).toHaveAttribute(
|
||||||
|
'src',
|
||||||
|
'https://media.example.test/movie.mp4?download=1#t=0.001',
|
||||||
|
)
|
||||||
|
expect(element).toHaveAttribute('preload', 'metadata')
|
||||||
|
expect(element).toHaveAttribute('poster', 'https://media.example.test/movie-preview.jpg')
|
||||||
|
expect(element).toHaveAttribute('controls')
|
||||||
|
expect(element).toHaveAttribute('playsinline')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('replaces an existing fragment instead of producing an invalid double fragment', () => {
|
||||||
|
const view = render(Attachments, {
|
||||||
|
attachments: [video({ type: 'gifv', url: 'https://media.example.test/loop.mp4#old' })],
|
||||||
|
})
|
||||||
|
const element = view.container.querySelector('video')
|
||||||
|
|
||||||
|
expect(element).toHaveAttribute('src', 'https://media.example.test/loop.mp4#t=0.001')
|
||||||
|
expect(element).toHaveAttribute('loop')
|
||||||
|
})
|
||||||
|
})
|
||||||
Reference in New Issue
Block a user