1
- from typing import Optional
1
+ from typing import Optional , Union
2
2
from videodb ._utils ._video import play_stream
3
3
from videodb ._constants import (
4
4
ApiPath ,
5
- SearchType ,
6
5
IndexType ,
7
- Workflows ,
6
+ SceneModels ,
7
+ SearchType ,
8
8
SubtitleStyle ,
9
+ Workflows ,
9
10
)
10
11
from videodb .search import SearchFactory , SearchResult
11
12
from videodb .shot import Shot
@@ -24,6 +25,7 @@ def __init__(self, _connection, id: str, collection_id: str, **kwargs) -> None:
24
25
self .length = float (kwargs .get ("length" , 0.0 ))
25
26
self .transcript = kwargs .get ("transcript" , None )
26
27
self .transcript_text = kwargs .get ("transcript_text" , None )
28
+ self .scenes = kwargs .get ("scenes" , None )
27
29
28
30
def __repr__ (self ) -> str :
29
31
return (
@@ -45,17 +47,19 @@ def search(
45
47
self ,
46
48
query : str ,
47
49
search_type : Optional [str ] = SearchType .semantic ,
50
+ scene_model : Optional [str ] = SceneModels .gemini_vision ,
48
51
result_threshold : Optional [int ] = None ,
49
52
score_threshold : Optional [int ] = None ,
50
53
dynamic_score_percentage : Optional [int ] = None ,
51
54
) -> SearchResult :
52
55
search = SearchFactory (self ._connection ).get_search (search_type )
53
56
return search .search_inside_video (
54
- self .id ,
55
- query ,
56
- result_threshold ,
57
- score_threshold ,
58
- dynamic_score_percentage ,
57
+ video_id = self .id ,
58
+ query = query ,
59
+ result_threshold = result_threshold ,
60
+ score_threshold = score_threshold ,
61
+ dynamic_score_percentage = dynamic_score_percentage ,
62
+ scene_model = scene_model ,
59
63
)
60
64
61
65
def delete (self ) -> None :
@@ -130,6 +134,48 @@ def index_spoken_words(self) -> None:
130
134
},
131
135
)
132
136
137
+ def index_scenes (
138
+ self ,
139
+ scene_model : str = SceneModels .gemini_vision ,
140
+ force : bool = False ,
141
+ prompt : str = None ,
142
+ callback_url : str = None ,
143
+ ) -> None :
144
+ self ._connection .post (
145
+ path = f"{ ApiPath .video } /{ self .id } /{ ApiPath .index } " ,
146
+ data = {
147
+ "index_type" : IndexType .scene ,
148
+ "model_name" : scene_model ,
149
+ "force" : force ,
150
+ "prompt" : prompt ,
151
+ "callback_url" : callback_url ,
152
+ },
153
+ )
154
+
155
+ def get_scenes (
156
+ self , scene_model : str = SceneModels .gemini_vision
157
+ ) -> Union [list , None ]:
158
+ if self .scenes :
159
+ return self .scenes
160
+ scene_data = self ._connection .get (
161
+ path = f"{ ApiPath .video } /{ self .id } /{ ApiPath .index } " ,
162
+ params = {
163
+ "index_type" : IndexType .scene ,
164
+ "model_name" : scene_model ,
165
+ },
166
+ )
167
+ self .scenes = scene_data
168
+ return scene_data if scene_data else None
169
+
170
+ def delete_scene_index (self , scene_model : str = SceneModels .gemini_vision ) -> None :
171
+ self ._connection .post (
172
+ path = f"{ ApiPath .video } /{ self .id } /{ ApiPath .index } /{ ApiPath .delete } " ,
173
+ data = {
174
+ "index_type" : IndexType .scene ,
175
+ "model_name" : scene_model ,
176
+ },
177
+ )
178
+
133
179
def add_subtitle (self , style : SubtitleStyle = SubtitleStyle ()) -> str :
134
180
if not isinstance (style , SubtitleStyle ):
135
181
raise ValueError ("style must be of type SubtitleStyle" )
0 commit comments