Spaces:
Runtime error
Runtime error
fix: change vidoes table schema and fix entitiy logics accordingly
Browse files- migrations/2025-08-19-034235_create_videos/up.sql +1 -0
- migrations/2025-08-19-041510_create_keyframes/up.sql +1 -1
- src/models/dtos/keyframes/mod.rs +1 -1
- src/models/dtos/videos/mod.rs +3 -4
- src/models/entities/keyframes/mod.rs +2 -2
- src/models/entities/videos/mod.rs +5 -0
- src/schema.rs +6 -2
- src/services/vectors/keyframes/mod.rs +6 -6
migrations/2025-08-19-034235_create_videos/up.sql
CHANGED
|
@@ -2,5 +2,6 @@ CREATE TABLE videos (
|
|
| 2 |
id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
|
| 3 |
l SMALLINT NOT NULL,
|
| 4 |
v SMALLINT NOT NULL,
|
|
|
|
| 5 |
UNIQUE (l, v)
|
| 6 |
)
|
|
|
|
| 2 |
id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
|
| 3 |
l SMALLINT NOT NULL,
|
| 4 |
v SMALLINT NOT NULL,
|
| 5 |
+
watch_url TEXT NOT NULL,
|
| 6 |
UNIQUE (l, v)
|
| 7 |
)
|
migrations/2025-08-19-041510_create_keyframes/up.sql
CHANGED
|
@@ -2,6 +2,6 @@ CREATE TABLE keyframes (
|
|
| 2 |
id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
|
| 3 |
video_id BIGINT NOT NULL REFERENCES videos (id),
|
| 4 |
video_related_frame_id SMALLINT NOT NULL,
|
| 5 |
-
video_related_frame_timestamp
|
| 6 |
UNIQUE (video_id, video_related_frame_id)
|
| 7 |
)
|
|
|
|
| 2 |
id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
|
| 3 |
video_id BIGINT NOT NULL REFERENCES videos (id),
|
| 4 |
video_related_frame_id SMALLINT NOT NULL,
|
| 5 |
+
video_related_frame_timestamp REAL NOT NULL,
|
| 6 |
UNIQUE (video_id, video_related_frame_id)
|
| 7 |
)
|
src/models/dtos/keyframes/mod.rs
CHANGED
|
@@ -4,7 +4,7 @@ use crate::models::entities::{keyframes::KeyframeEntity, videos::VideoEntity};
|
|
| 4 |
pub struct KeyframeDto {
|
| 5 |
id: i64,
|
| 6 |
path: String,
|
| 7 |
-
timestamp:
|
| 8 |
}
|
| 9 |
|
| 10 |
impl From<(KeyframeEntity, VideoEntity)> for KeyframeDto {
|
|
|
|
| 4 |
pub struct KeyframeDto {
|
| 5 |
id: i64,
|
| 6 |
path: String,
|
| 7 |
+
timestamp: f32,
|
| 8 |
}
|
| 9 |
|
| 10 |
impl From<(KeyframeEntity, VideoEntity)> for KeyframeDto {
|
src/models/dtos/videos/mod.rs
CHANGED
|
@@ -3,15 +3,14 @@ use crate::models::entities::videos::VideoEntity;
|
|
| 3 |
#[derive(Debug, Clone, serde::Serialize, utoipa::ToSchema)]
|
| 4 |
pub struct VideoDto {
|
| 5 |
id: i64,
|
| 6 |
-
|
| 7 |
}
|
| 8 |
|
| 9 |
impl From<VideoEntity> for VideoDto {
|
| 10 |
-
fn from(value: VideoEntity) -> Self {
|
| 11 |
-
let path = format!("/static/videos/L{}_V{:0>3}.mp4", value.l(), value.v());
|
| 12 |
Self {
|
| 13 |
id: value.id(),
|
| 14 |
-
|
| 15 |
}
|
| 16 |
}
|
| 17 |
}
|
|
|
|
| 3 |
#[derive(Debug, Clone, serde::Serialize, utoipa::ToSchema)]
|
| 4 |
pub struct VideoDto {
|
| 5 |
id: i64,
|
| 6 |
+
watch_url: String,
|
| 7 |
}
|
| 8 |
|
| 9 |
impl From<VideoEntity> for VideoDto {
|
| 10 |
+
fn from(mut value: VideoEntity) -> Self {
|
|
|
|
| 11 |
Self {
|
| 12 |
id: value.id(),
|
| 13 |
+
watch_url: std::mem::take(value.watch_url_mut()),
|
| 14 |
}
|
| 15 |
}
|
| 16 |
}
|
src/models/entities/keyframes/mod.rs
CHANGED
|
@@ -4,7 +4,7 @@
|
|
| 4 |
pub struct KeyframeEntity {
|
| 5 |
id: i64,
|
| 6 |
video_related_frame_id: i16,
|
| 7 |
-
video_related_frame_timestamp:
|
| 8 |
}
|
| 9 |
|
| 10 |
impl KeyframeEntity {
|
|
@@ -16,7 +16,7 @@ impl KeyframeEntity {
|
|
| 16 |
self.video_related_frame_id
|
| 17 |
}
|
| 18 |
|
| 19 |
-
pub fn video_related_frame_timestamp(&self) ->
|
| 20 |
self.video_related_frame_timestamp
|
| 21 |
}
|
| 22 |
}
|
|
|
|
| 4 |
pub struct KeyframeEntity {
|
| 5 |
id: i64,
|
| 6 |
video_related_frame_id: i16,
|
| 7 |
+
video_related_frame_timestamp: f32,
|
| 8 |
}
|
| 9 |
|
| 10 |
impl KeyframeEntity {
|
|
|
|
| 16 |
self.video_related_frame_id
|
| 17 |
}
|
| 18 |
|
| 19 |
+
pub fn video_related_frame_timestamp(&self) -> f32 {
|
| 20 |
self.video_related_frame_timestamp
|
| 21 |
}
|
| 22 |
}
|
src/models/entities/videos/mod.rs
CHANGED
|
@@ -5,6 +5,7 @@ pub struct VideoEntity {
|
|
| 5 |
id: i64,
|
| 6 |
l: i16,
|
| 7 |
v: i16,
|
|
|
|
| 8 |
}
|
| 9 |
|
| 10 |
impl VideoEntity {
|
|
@@ -19,4 +20,8 @@ impl VideoEntity {
|
|
| 19 |
pub fn v(&self) -> i16 {
|
| 20 |
self.v
|
| 21 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
| 22 |
}
|
|
|
|
| 5 |
id: i64,
|
| 6 |
l: i16,
|
| 7 |
v: i16,
|
| 8 |
+
watch_url: String,
|
| 9 |
}
|
| 10 |
|
| 11 |
impl VideoEntity {
|
|
|
|
| 20 |
pub fn v(&self) -> i16 {
|
| 21 |
self.v
|
| 22 |
}
|
| 23 |
+
|
| 24 |
+
pub fn watch_url_mut(&mut self) -> &mut String {
|
| 25 |
+
&mut self.watch_url
|
| 26 |
+
}
|
| 27 |
}
|
src/schema.rs
CHANGED
|
@@ -5,7 +5,7 @@ diesel::table! {
|
|
| 5 |
id -> Int8,
|
| 6 |
video_id -> Int8,
|
| 7 |
video_related_frame_id -> Int2,
|
| 8 |
-
video_related_frame_timestamp ->
|
| 9 |
}
|
| 10 |
}
|
| 11 |
|
|
@@ -14,9 +14,13 @@ diesel::table! {
|
|
| 14 |
id -> Int8,
|
| 15 |
l -> Int2,
|
| 16 |
v -> Int2,
|
|
|
|
| 17 |
}
|
| 18 |
}
|
| 19 |
|
| 20 |
diesel::joinable!(keyframes -> videos (video_id));
|
| 21 |
|
| 22 |
-
diesel::allow_tables_to_appear_in_same_query!(
|
|
|
|
|
|
|
|
|
|
|
|
| 5 |
id -> Int8,
|
| 6 |
video_id -> Int8,
|
| 7 |
video_related_frame_id -> Int2,
|
| 8 |
+
video_related_frame_timestamp -> Float4,
|
| 9 |
}
|
| 10 |
}
|
| 11 |
|
|
|
|
| 14 |
id -> Int8,
|
| 15 |
l -> Int2,
|
| 16 |
v -> Int2,
|
| 17 |
+
watch_url -> Text,
|
| 18 |
}
|
| 19 |
}
|
| 20 |
|
| 21 |
diesel::joinable!(keyframes -> videos (video_id));
|
| 22 |
|
| 23 |
+
diesel::allow_tables_to_appear_in_same_query!(
|
| 24 |
+
keyframes,
|
| 25 |
+
videos,
|
| 26 |
+
);
|
src/services/vectors/keyframes/mod.rs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
| 1 |
use candle_core::{Device, Tensor};
|
| 2 |
use candle_transformers::models::clip::ClipModel;
|
| 3 |
-
use qdrant_client::{Qdrant, qdrant::
|
| 4 |
use rayon::iter::{IntoParallelIterator, ParallelIterator};
|
| 5 |
use tokenizers::Tokenizer;
|
| 6 |
|
|
@@ -50,11 +50,11 @@ impl<'a> VectorizedKeyframeService<'a> {
|
|
| 50 |
|
| 51 |
let query_result = self
|
| 52 |
.client
|
| 53 |
-
.
|
| 54 |
-
"keyframes"
|
| 55 |
-
|
| 56 |
-
|
| 57 |
-
)
|
| 58 |
.await?
|
| 59 |
.result;
|
| 60 |
|
|
|
|
| 1 |
use candle_core::{Device, Tensor};
|
| 2 |
use candle_transformers::models::clip::ClipModel;
|
| 3 |
+
use qdrant_client::{Qdrant, qdrant::QueryPointsBuilder};
|
| 4 |
use rayon::iter::{IntoParallelIterator, ParallelIterator};
|
| 5 |
use tokenizers::Tokenizer;
|
| 6 |
|
|
|
|
| 50 |
|
| 51 |
let query_result = self
|
| 52 |
.client
|
| 53 |
+
.query(
|
| 54 |
+
QueryPointsBuilder::new("keyframes")
|
| 55 |
+
.query(embeddings.squeeze(0)?.to_vec1::<f32>()?)
|
| 56 |
+
.limit(top_k),
|
| 57 |
+
)
|
| 58 |
.await?
|
| 59 |
.result;
|
| 60 |
|