eratic / packages / core / src / components / Video.astro
258 words
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
---
/**
 * A short video.
 *
 * The file itself is not in git — it lives on the server under
 * /opt/eratic/media and is referenced by path:
 *
 *   <Video src="video/2026/harbour.mp4" poster="video/2026/harbour.jpg"
 *          alt="Boats moving in a harbour at dusk" />
 *
 * Both `src` and `poster` go through mediaUrl(), so the day ird ships IPFS you
 * can change this one reference to "ipfs://bafy…", set MEDIA.ipfsGateway in
 * config.ts, and nothing else in the codebase moves.
 *
 * `preload="metadata"` means a page with five clips on it downloads five
 * headers, not five videos.
 */
import { mediaUrl } from '../config.js';

interface Props {
	src: string;
	/** Still frame shown before playback. Strongly recommended. */
	poster?: string;
	/** Describes the video for anyone who cannot see it. */
	alt?: string;
	caption?: string;
	width?: 'content' | 'wide' | 'full';
	/** Silent looping clip with no controls — treat it as a moving photograph. */
	ambient?: boolean;
}

const { src, poster, alt, caption, width = 'wide', ambient = false } = Astro.props;

const source = mediaUrl(src);
const posterUrl = poster ? mediaUrl(poster) : undefined;
const type = source.endsWith('.webm') ? 'video/webm' : 'video/mp4';
---

<figure class:list={[width === 'wide' && 'u-wide', width === 'full' && 'u-full']}>
	{/* eslint-disable-next-line jsx-a11y/media-has-caption -- short silent clips */}
	<video
		poster={posterUrl}
		controls={!ambient}
		autoplay={ambient}
		loop={ambient}
		muted={ambient}
		playsinline
		preload="metadata"
		aria-label={alt}
	>
		<source src={source} type={type} />
		<p>
			Your browser cannot play this video. <a href={source}>Download it instead</a>.
		</p>
	</video>

	{caption && <figcaption>{caption}</figcaption>}
</figure>

<style>
	video {
		inline-size: 100%;
		block-size: auto;
		background: var(--surface-sunk);
		border-radius: var(--radius);
	}
</style>

static mirror of HEAD · about · clone: git clone https://git.makefuture.ro/eratic.git