hjxdl 0.3.39__py3-none-any.whl → 0.3.40__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
hdl/_version.py CHANGED
@@ -17,5 +17,5 @@ __version__: str
17
17
  __version_tuple__: VERSION_TUPLE
18
18
  version_tuple: VERSION_TUPLE
19
19
 
20
- __version__ = version = '0.3.39'
21
- __version_tuple__ = version_tuple = (0, 3, 39)
20
+ __version__ = version = '0.3.40'
21
+ __version_tuple__ = version_tuple = (0, 3, 40)
@@ -142,6 +142,8 @@ class OpenAIWrapper(object):
142
142
  assis_info: str = None,
143
143
  images: list = None,
144
144
  image_keys: tuple = ("image_url", "url"),
145
+ videos: list = None,
146
+ video_keys: tuple = ("video_url", "url"),
145
147
  model: str=None,
146
148
  tools: list = None,
147
149
  tool_choice: str = "auto",
@@ -207,10 +209,30 @@ class OpenAIWrapper(object):
207
209
  elif len(image_keys) == 1:
208
210
  image_keys = (image_keys[0],) * 3
209
211
 
212
+ if isinstance(video_keys, str):
213
+ video_keys = (video_keys,) * 3
214
+ elif len(video_keys) == 2:
215
+ video_keys = (video_keys[0],) + tuple(video_keys)
216
+ elif len(video_keys) == 1:
217
+ video_keys = (video_keys[0],) * 3
218
+
210
219
  content = [{
211
220
  "type": "text",
212
221
  "text": prompt
213
222
  }]
223
+
224
+ if videos:
225
+ if isinstance(videos, str):
226
+ images = [videos]
227
+ for video in videos:
228
+ content.append({
229
+ "type": video_keys[0],
230
+ video_keys[1]: {
231
+ video_keys[2]: img
232
+ }
233
+ })
234
+
235
+
214
236
  if images:
215
237
  if isinstance(images, str):
216
238
  images = [images]
@@ -221,8 +243,7 @@ class OpenAIWrapper(object):
221
243
  image_keys[2]: img
222
244
  }
223
245
  })
224
- else:
225
- # If no images are provided, content is simply the prompt text
246
+ if (not images) and (not videos):
226
247
  content = prompt
227
248
 
228
249
  # Add the user's input as a message
hdl/utils/llm/vis.py CHANGED
@@ -24,6 +24,13 @@ from hdl.jupyfuncs.show.pbar import tqdm
24
24
  from redis.commands.search.query import Query
25
25
 
26
26
 
27
+ from decord import VideoReader, cpu
28
+
29
+ import base64
30
+ from io import BytesIO
31
+ from PIL import Image
32
+ import numpy as np
33
+ import requests
27
34
  # from ..database_tools.connect import conn_redis
28
35
 
29
36
 
@@ -731,4 +738,65 @@ class ImgHandler:
731
738
  return results
732
739
 
733
740
 
741
+ def to_video_base64(video_path, max_frames=80, is_fps_sampling=True):
742
+ """
743
+ Converts a video file or a video from a given URL to a list of base64 encoded image frames.
744
+
745
+ Args:
746
+ video_path (str): The path to the video file or the URL of the video.
747
+ max_frames (int, optional): The maximum number of frames to return. Defaults to 80.
748
+ is_fps_sampling (bool, optional): A flag to indicate whether to sample frames based on average FPS. Defaults to True.
734
749
 
750
+ Returns:
751
+ list: A list of base64 encoded strings representing the sampled frames of the video.
752
+
753
+ Raises:
754
+ Exception: If the video cannot be loaded or if the URL is unreachable.
755
+
756
+ Note:
757
+ This function uses the VideoReader class for reading video frames and requires the necessary libraries for handling images and base64 encoding.
758
+ """
759
+ if video_path.startswith("http") or video_path.startswith("https"):
760
+ response = requests.get(video_path)
761
+ if response.status_code == 200:
762
+ video_path = BytesIO(response.content)
763
+ else:
764
+ print('failed to load the video')
765
+
766
+ vr = VideoReader(video_path, ctx=cpu(0), num_threads=1)
767
+ total_frame_num = len(vr)
768
+ if is_fps_sampling:
769
+ # FPS Sampling
770
+ avg_fps = round(vr.get_avg_fps())
771
+ frame_idx = [i for i in range(
772
+ 0, total_frame_num, avg_fps)]
773
+ if len(frame_idx) > max_frames:
774
+ uniform_sampled_frames = np.linspace(
775
+ 0, total_frame_num - 1, max_frames, dtype=int
776
+ )
777
+ frame_idx = uniform_sampled_frames.tolist()
778
+ print(frame_idx)
779
+ else:
780
+ # uniform sampling
781
+ if total_frame_num > max_frames:
782
+ uniform_sampled_frames = np.linspace(
783
+ 0, total_frame_num - 1, max_frames, dtype=int
784
+ )
785
+ frame_idx = uniform_sampled_frames.tolist()
786
+ else:
787
+ frame_idx = [i for i in range(0, total_frame_num)]
788
+ print(frame_idx)
789
+
790
+ frames = vr.get_batch(frame_idx).asnumpy()
791
+ print("actual frames", len(frames))
792
+
793
+ base64_frames = []
794
+ for frame in frames:
795
+ img = Image.fromarray(frame)
796
+ output_buffer = BytesIO()
797
+ img.save(output_buffer, format="PNG")
798
+
799
+ byte_data = output_buffer.getvalue()
800
+ base64_str = base64.b64encode(byte_data).decode("utf-8")
801
+ base64_frames.append(base64_str)
802
+ return base64_frames
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: hjxdl
3
- Version: 0.3.39
3
+ Version: 0.3.40
4
4
  Summary: A collection of functions for Jupyter notebooks
5
5
  Home-page: https://github.com/huluxiaohuowa/hdl
6
6
  Author: Jianxing Hu
@@ -1,5 +1,5 @@
1
1
  hdl/__init__.py,sha256=GffnD0jLJdhkd-vo989v40N90sQbofkayRBwxc6TVhQ,72
2
- hdl/_version.py,sha256=X3NJYp9_3dCmctRYb1tZdvHuuPikZELQ99611KxJNh4,513
2
+ hdl/_version.py,sha256=FM2ay9B4jNpEspCcoKvkx6ALhoNo3bt_Okj6w9c819c,513
3
3
  hdl/args/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
4
  hdl/args/loss_args.py,sha256=s7YzSdd7IjD24rZvvOrxLLFqMZQb9YylxKeyelSdrTk,70
5
5
  hdl/controllers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -136,16 +136,16 @@ hdl/utils/llm/chatgr.py,sha256=5F5PJHe8vz3iCfi4TT54DCLRi1UeJshECdVtgvvvao0,3696
136
136
  hdl/utils/llm/embs.py,sha256=Tf0FOYrOFZp7qQpEPiSCXzlgyHH0X9HVTUtsup74a9E,7174
137
137
  hdl/utils/llm/extract.py,sha256=2sK_WJzmYIc8iuWaM9DA6Nw3_6q1O4lJ5pKpcZo-bBA,6512
138
138
  hdl/utils/llm/llama_chat.py,sha256=watcHGOaz-bv3x-yDucYlGk5f8FiqfFhwWogrl334fk,4387
139
- hdl/utils/llm/llm_wrapper.py,sha256=ZjmogEM0TrvlM83LG6l5t8CFnMThBWUmUOvA5WY9ODo,15309
139
+ hdl/utils/llm/llm_wrapper.py,sha256=kectOfy2lbT0UcSYXbbmeQDlYMtdf6gpV10fI7ilgug,15929
140
140
  hdl/utils/llm/ollama.py,sha256=uEdLsNAc6b56r37hNiE3nrd6oZ2lmQ0gYbVvOc9YVIM,1389
141
- hdl/utils/llm/vis.py,sha256=SSP6tOwKLq0hWcpM3twI9TitqzBmKjlcGrnXEWYlCzM,26055
141
+ hdl/utils/llm/vis.py,sha256=CLZApXlC636mYsxP7yg1UWRn0Q16pXpOX8ShJbfv5us,28739
142
142
  hdl/utils/llm/visrag.py,sha256=0i-VrxqgiV-J7R3VPshu9oc7-rKjFJOldYik3HDXj6M,10176
143
143
  hdl/utils/schedulers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
144
144
  hdl/utils/schedulers/norm_lr.py,sha256=bDwCmdEK-WkgxQMFBiMuchv8Mm7C0-GZJ6usm-PQk14,4461
145
145
  hdl/utils/weather/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
146
146
  hdl/utils/weather/weather.py,sha256=k11o6wM15kF8b9NMlEfrg68ak-SfSYLN3nOOflFUv-I,4381
147
- hjxdl-0.3.39.dist-info/licenses/LICENSE,sha256=lkMiSbeZHBQLB9LJEkS9-L3Z-LBC4yGnKrzHSG8RkPM,2599
148
- hjxdl-0.3.39.dist-info/METADATA,sha256=lGbo0pGz-o-TMwXK0Fa3NPke0werbwIaNasB3TuDqcY,1358
149
- hjxdl-0.3.39.dist-info/WHEEL,sha256=DK49LOLCYiurdXXOXwGJm6U4DkHkg4lcxjhqwRa0CP4,91
150
- hjxdl-0.3.39.dist-info/top_level.txt,sha256=-kxwTM5JPhylp06z3zAVO3w6_h7wtBfBo2zgM6YZoTk,4
151
- hjxdl-0.3.39.dist-info/RECORD,,
147
+ hjxdl-0.3.40.dist-info/licenses/LICENSE,sha256=lkMiSbeZHBQLB9LJEkS9-L3Z-LBC4yGnKrzHSG8RkPM,2599
148
+ hjxdl-0.3.40.dist-info/METADATA,sha256=otgYEo9D3UeXTRx9Qqgyi7e5f4t6ZonGvfTdDbMoS4I,1358
149
+ hjxdl-0.3.40.dist-info/WHEEL,sha256=CmyFI0kx5cdEMTLiONQRbGQwjIoR1aIYB7eCAQ4KPJ0,91
150
+ hjxdl-0.3.40.dist-info/top_level.txt,sha256=-kxwTM5JPhylp06z3zAVO3w6_h7wtBfBo2zgM6YZoTk,4
151
+ hjxdl-0.3.40.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (78.0.2)
2
+ Generator: setuptools (78.1.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5