your personal website on atproto - mirror
blento.app
1import { uploadBlob } from '$lib/atproto';
2import type { CardDefinition } from '../types';
3import VideoCard from './VideoCard.svelte';
4import VideoCardSettings from './VideoCardSettings.svelte';
5
6async function getAspectRatio(videoBlob: Blob): Promise<{ width: number; height: number }> {
7 return new Promise((resolve, reject) => {
8 const video = document.createElement('video');
9 video.preload = 'metadata';
10
11 video.onloadedmetadata = () => {
12 URL.revokeObjectURL(video.src);
13 resolve({
14 width: video.videoWidth,
15 height: video.videoHeight
16 });
17 };
18
19 video.onerror = () => {
20 URL.revokeObjectURL(video.src);
21 reject(new Error('Failed to load video metadata'));
22 };
23
24 video.src = URL.createObjectURL(videoBlob);
25 });
26}
27
28export const VideoCardDefinition = {
29 type: 'video',
30 contentComponent: VideoCard,
31 createNew: (card) => {
32 card.cardType = 'video';
33 card.cardData = {
34 video: null,
35 href: ''
36 };
37 },
38 upload: async (item) => {
39 if (item.cardData.blob) {
40 const blob = item.cardData.blob;
41 const aspectRatio = await getAspectRatio(blob);
42 const uploadedBlob = await uploadBlob({ blob });
43
44 item.cardData.video = {
45 $type: 'app.bsky.embed.video',
46 video: uploadedBlob,
47 aspectRatio
48 };
49
50 delete item.cardData.blob;
51 }
52
53 if (item.cardData.objectUrl) {
54 URL.revokeObjectURL(item.cardData.objectUrl);
55 delete item.cardData.objectUrl;
56 }
57
58 return item;
59 },
60 settingsComponent: VideoCardSettings,
61
62 name: 'Video Card'
63} as CardDefinition & { type: 'video' };