Skip to content

Commit

Permalink
add: video thumbnail generate
Browse files Browse the repository at this point in the history
  • Loading branch information
zenkyuv committed Feb 17, 2024
1 parent 1181acb commit b891e15
Show file tree
Hide file tree
Showing 5 changed files with 27 additions and 6 deletions.
4 changes: 2 additions & 2 deletions s/components/omni-media/component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@ export const OmniMedia = shadow_component({styles}, use => {
const [media, setMedia, getMedia] = use.state<Video[]>([])

use.setup(() => {
const unsub = media_controller.on_media_change((change) => {
const unsub = media_controller.on_media_change(async (change) => {
if(change.action === "added") {
const video_files = media_controller.create_videos_from_video_files(change.files)
const video_files = await media_controller.create_videos_from_video_files(change.files)
setMedia([...getMedia(), ...video_files])
}
if(change.action === "removed") {
Expand Down
1 change: 1 addition & 0 deletions s/components/omni-media/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ export interface AudioFile extends MediaFile {
export interface Video extends MediaFile {
kind: "video"
element: HTMLVideoElement
thumbnail: string
}

export interface Audio extends MediaFile {
Expand Down
24 changes: 21 additions & 3 deletions s/context/controllers/media/controller.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import {pub} from "@benev/slate"
import {quick_hash} from "@benev/construct"

import {Video, MediaFile} from "../../../components/omni-media/types"
import {Video, MediaFile} from "../../../components/omni-media/types.js"

export class Media {
#database_request = window.indexedDB.open("database", 3)
Expand Down Expand Up @@ -80,14 +80,32 @@ export class Media {
check_if_duplicate!.onerror = (error) => console.log("error")
}
}

create_video_thumbnail(video: HTMLVideoElement): Promise<string> {
const canvas = document.createElement("canvas")
canvas.width = 150
canvas.height = 50
const ctx = canvas.getContext("2d")
video.currentTime = 1000/60
const f = (resolve: (url: string) => void) => {
ctx?.drawImage(video, 0, 0, 150, 50)
const url = canvas.toDataURL()
resolve(url)
removeEventListener("seeked", () => f(resolve))
}
return new Promise((resolve) => {
video.addEventListener("seeked", () => f(resolve))
})
}

create_videos_from_video_files(files: MediaFile[]) {
async create_videos_from_video_files(files: MediaFile[]) {
const videos: Video[] = []
for(const {file, hash} of files) {
const video = document.createElement('video')
video.src = URL.createObjectURL(file)
video.load()
videos.push({element: video, file, hash, kind: "video"})
const url = await this.create_video_thumbnail(video)
videos.push({element: video, file, hash, kind: "video", thumbnail: url})
}
return videos
}
Expand Down
3 changes: 2 additions & 1 deletion s/context/controllers/timeline/actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@ export const timeline_actions = actionize({
start: 0,
end: duration,
track: 2,
file: video.file
file: video.file,
thumbnail: video.thumbnail
}
compositor.VideoManager.add_video(effect)
state.timeline.effects.push(effect)
Expand Down
1 change: 1 addition & 0 deletions s/context/controllers/timeline/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ export interface Effect {
export interface VideoEffect extends Effect {
kind: "video"
file: File
thumbnail: string
}

export type TextEffectProps = Omit<TextEffect, keyof Effect | "kind">
Expand Down

0 comments on commit b891e15

Please sign in to comment.