Skip to content

Commit 30e4a74

Browse files
committed
refactor: stream, thumbnail method, add player
1 parent 23cffa4 commit 30e4a74

File tree

4 files changed

+95
-42
lines changed

4 files changed

+95
-42
lines changed

README.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ video = conn.upload(url="https://www.youtube.com/")
6767
video = conn.upload(file_path="path/to/video.mp4")
6868

6969
# get the stream url for the video
70-
stream_url = video.get_stream()
70+
stream_url = video.generate_stream()
7171

7272
```
7373

@@ -139,7 +139,7 @@ stream_url = result.compile()
139139
# get shots of the result returns a list of Shot objects
140140
shots = result.get_shots()
141141
# get stream url of the shot
142-
short_stream_url = shots[0].get_stream()
142+
short_stream_url = shots[0].generate_stream()
143143

144144
```
145145

@@ -155,10 +155,10 @@ video = collection.get_video("video_id")
155155
# get the stream url of the dynamically curated video based on the given timeline sequence
156156
# optional parameters:
157157
# - timeline: Optional[list[tuple[int, int]] to specify the start and end time of the video
158-
stream_url = video.get_stream(timeline=[(0, 10), (30, 40)])
158+
stream_url = video.generate_stream(timeline=[(0, 10), (30, 40)])
159159

160-
# get thumbnail of the video
161-
thumbnail = video.get_thumbnail()
160+
# get thumbnail url of the video
161+
thumbnail_url = video.generate_thumbnail()
162162

163163
# get transcript of the video
164164
# optional parameters:

videodb/search.py

Lines changed: 30 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import webbrowser as web
2+
13
from abc import ABC, abstractmethod
24
from videodb._constants import (
35
SearchType,
@@ -15,8 +17,8 @@ class SearchResult:
1517
def __init__(self, _connection, **kwargs):
1618
self._connection = _connection
1719
self.shots = []
18-
self.text_summary = None
19-
self.stream = None
20+
self.stream_url = None
21+
self.player_url = None
2022
self.collection_id = "default"
2123
self._results = kwargs.get("results", [])
2224
self._format_results()
@@ -38,18 +40,27 @@ def _format_results(self):
3840
)
3941
)
4042

43+
def __repr__(self) -> str:
44+
return (
45+
f"SearchResult("
46+
f"collection_id={self.collection_id}, "
47+
f"stream_url={self.stream_url}, "
48+
f"player_url={self.player_url}, "
49+
f"shots={self.shots})"
50+
)
51+
4152
def get_shots(self) -> List[Shot]:
4253
return self.shots
4354

4455
def compile(self) -> str:
45-
"""Compile the search result shots into a stream link
56+
"""Compile the search result shots into a stream url
4657
4758
:raises SearchError: If no shots are found in the search results
48-
:return: The stream link
59+
:return: The stream url
4960
:rtype: str
5061
"""
51-
if self.stream:
52-
return self.stream
62+
if self.stream_url:
63+
return self.stream_url
5364
elif self.shots:
5465
compile_data = self._connection.post(
5566
path=f"{ApiPath.compile}",
@@ -62,12 +73,23 @@ def compile(self) -> str:
6273
for shot in self.shots
6374
],
6475
)
65-
self.stream = compile_data.get("stream_link")
66-
return self.stream
76+
self.stream_url = compile_data.get("stream_link")
77+
self.player_url = compile_data.get("player_link")
78+
return self.stream_url
6779

6880
else:
6981
raise SearchError("No shots found in search results to compile")
7082

83+
def play(self) -> str:
84+
"""Generate a stream url for the shot and open it in the default browser
85+
86+
:return: The stream url
87+
:rtype: str
88+
"""
89+
self.compile()
90+
web.open(self.player_url)
91+
return self.player_url
92+
7193

7294
class Search(ABC):
7395
"""Search interface inside video or collection"""

videodb/shot.py

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
"""This module contains the shot class"""
22

3-
3+
import webbrowser as web
44
from typing import Optional
55
from videodb._constants import (
66
ApiPath,
@@ -29,7 +29,8 @@ def __init__(
2929
self.end = end
3030
self.text = text
3131
self.search_score = search_score
32-
self.stream = None
32+
self.stream_url = None
33+
self.player_url = None
3334

3435
def __repr__(self) -> str:
3536
return (
@@ -40,22 +41,23 @@ def __repr__(self) -> str:
4041
f"end={self.end}, "
4142
f"text={self.text}, "
4243
f"search_score={self.search_score}, "
43-
f"stream={self.stream})"
44+
f"stream_url={self.stream_url}, "
45+
f"player_url={self.player_url})"
4446
)
4547

4648
def __getitem__(self, key):
4749
"""Get an item from the shot object"""
4850
return self.__dict__[key]
4951

50-
def get_stream(self) -> str:
51-
"""Get the shot into a stream link
52+
def generate_stream(self) -> str:
53+
"""Generate a stream url for the shot
5254
53-
:return: The stream link
55+
:return: The stream url
5456
:rtype: str
5557
"""
5658

57-
if self.stream:
58-
return self.stream
59+
if self.stream_url:
60+
return self.stream_url
5961
else:
6062
stream_data = self._connection.post(
6163
path=f"{ApiPath.video}/{self.video_id}/{ApiPath.stream}",
@@ -64,5 +66,16 @@ def get_stream(self) -> str:
6466
"length": self.video_length,
6567
},
6668
)
67-
self.stream = stream_data.get("stream_link")
68-
return self.stream
69+
self.stream_url = stream_data.get("stream_link")
70+
self.player_url = stream_data.get("player_link")
71+
return self.stream_url
72+
73+
def play(self) -> str:
74+
"""Generate a stream url for the shot and open it in the default browser
75+
76+
:return: The stream url
77+
:rtype: str
78+
"""
79+
self.generate_stream()
80+
web.open(self.player_url)
81+
return self.player_url

videodb/video.py

Lines changed: 37 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import webbrowser as web
12
from videodb._constants import (
23
ApiPath,
34
SearchType,
@@ -14,10 +15,11 @@ def __init__(self, _connection, id: str, collection_id: str, **kwargs) -> None:
1415
self._connection = _connection
1516
self.id = id
1617
self.collection_id = collection_id
17-
self.stream_link = kwargs.get("stream_link", None)
18+
self.stream_url = kwargs.get("stream_link", None)
19+
self.player_url = kwargs.get("player_link", None)
1820
self.name = kwargs.get("name", None)
1921
self.description = kwargs.get("description", None)
20-
self.thumbnail = kwargs.get("thumbnail", None)
22+
self.thumbnail_url = kwargs.get("thumbnail", None)
2123
self.length = float(kwargs.get("length", 0.0))
2224
self.transcript = kwargs.get("transcript", None)
2325
self.transcript_text = kwargs.get("transcript_text", None)
@@ -27,10 +29,11 @@ def __repr__(self) -> str:
2729
f"Video("
2830
f"id={self.id}, "
2931
f"collection_id={self.collection_id}, "
30-
f"stream_link={self.stream_link}, "
32+
f"stream_url={self.stream_url}, "
33+
f"player_url={self.player_url}, "
3134
f"name={self.name}, "
3235
f"description={self.description}, "
33-
f"thumbnail={self.thumbnail}, "
36+
f"thumbnail_url={self.thumbnail_url}, "
3437
f"length={self.length})"
3538
)
3639

@@ -63,16 +66,16 @@ def delete(self) -> None:
6366
"""
6467
self._connection.delete(path=f"{ApiPath.video}/{self.id}")
6568

66-
def get_stream(self, timeline: Optional[list[tuple[int, int]]] = None) -> str:
67-
"""Get the stream link of the video
69+
def generate_stream(self, timeline: Optional[list[tuple[int, int]]] = None) -> str:
70+
"""Generate the stream url of the video
6871
6972
:param list timeline: The timeline of the video to be streamed. Defaults to None.
7073
:raises InvalidRequestError: If the get_stream fails
71-
:return: The stream link of the video
74+
:return: The stream url of the video
7275
:rtype: str
7376
"""
74-
if not timeline and self.stream_link:
75-
return self.stream_link
77+
if not timeline and self.stream_url:
78+
return self.stream_url
7679

7780
stream_data = self._connection.post(
7881
path=f"{ApiPath.video}/{self.id}/{ApiPath.stream}",
@@ -81,16 +84,18 @@ def get_stream(self, timeline: Optional[list[tuple[int, int]]] = None) -> str:
8184
"length": self.length,
8285
},
8386
)
84-
return stream_data.get("stream_link")
87+
self.stream_url = stream_data.get("stream_link")
88+
self.player_url = stream_data.get("player_link")
89+
return self.stream_url
8590

86-
def get_thumbnail(self):
87-
if self.thumbnail:
88-
return self.thumbnail
91+
def generate_thumbnail(self):
92+
if self.thumbnail_url:
93+
return self.thumbnail_url
8994
thumbnail_data = self._connection.get(
9095
path=f"{ApiPath.video}/{self.id}/{ApiPath.thumbnail}"
9196
)
92-
self.thumbnail = thumbnail_data.get("thumbnail")
93-
return self.thumbnail
97+
self.thumbnail_url = thumbnail_data.get("thumbnail")
98+
return self.thumbnail_url
9499

95100
def _fetch_transcript(self, force: bool = False) -> None:
96101
if self.transcript and not force:
@@ -132,15 +137,17 @@ def add_subtitle(self) -> str:
132137
"type": Workflows.add_subtitles,
133138
},
134139
)
135-
return subtitle_data.get("stream_link")
140+
self.stream_url = subtitle_data.get("stream_link")
141+
self.player_url = subtitle_data.get("player_link")
142+
return self.stream_url
136143

137144
def insert_video(self, video, timestamp: float) -> str:
138145
"""Insert a video into another video
139146
140147
:param Video video: The video to be inserted
141148
:param float timestamp: The timestamp where the video should be inserted
142149
:raises InvalidRequestError: If the insert fails
143-
:return: The stream link of the inserted video
150+
:return: The stream url of the inserted video
144151
:rtype: str
145152
"""
146153
if timestamp > float(self.length):
@@ -171,5 +178,16 @@ def insert_video(self, video, timestamp: float) -> str:
171178
for shot in all_shots
172179
],
173180
)
174-
stream_link = compile_data.get("stream_link")
175-
return stream_link
181+
self.stream_url = compile_data.get("stream_link")
182+
self.player_url = compile_data.get("player_link")
183+
return self.stream_url
184+
185+
def play(self) -> str:
186+
"""Generate a stream url for the shot and open it in the default browser
187+
188+
:return: The stream url
189+
:rtype: str
190+
"""
191+
self.generate_stream()
192+
web.open(self.player_url)
193+
return self.player_url

0 commit comments

Comments
 (0)